Scope and the key separation
The two supplied excerpts are shared official Stripe guidance, so they are one documentation family rather than independent corroborating studies. This article addresses only the v1 list and search interfaces represented there.
For either family, limit selects how many objects a response may contain; it is not a declaration that a traversal has finished or that an importer may process only that many objects. The documented default is 10, and the permitted range is 1 through 100.
Completion is instead determined from the response continuation information. A false has_more marks the end of the available result sequence; a true value means another result page remains available.
Four decisions at the response boundary
Use the provider fields to determine traversal status, then apply a separately chosen application rule. The budget and action columns below are proposed application policy, not provider-prescribed behavior.
| Case | Endpoint family | Page-size evidence | Continuation evidence | Provider traversal state | Application-owned budget state | Completion conclusion | Inference to reject | Bounded application-owned action |
|---|---|---|---|---|---|---|---|---|
List; no limit supplied | List | No limit is sent, so the documented default is 10 objects. | Inspect has_more; when it is true, use the final object ID as starting_after for a later list call. | Unknown until has_more is read. | No overall cap is implied by the omitted parameter. | A default-sized page alone does not establish completion. | “Ten returned objects is the import allowance.” | Choose an application cap separately and persist whether work stopped intentionally or reached the end. |
List; limit=100, has_more=true | List | 100 is within the documented 1–100 page-size range. | A true has_more requires a subsequent list request; use the last returned ID with starting_after. | More list results are reported as available. | The application may stop under its own rule, but that is a policy stop. | The provider traversal is not complete. | “A maximum page size is a whole-import maximum.” | Label 100 as page size; record an intentional stop distinctly from completed traversal. |
Search; no limit supplied | Search | Without a limit, search also uses the documented default of 10 objects. | When continuation is needed, a returned next_page value is supplied as page on the following search request. | Read has_more before deciding whether search traversal ended. | No processing quota follows from the default response size. | The first response is not sufficient evidence of completion. | “The default response count is a search-job budget.” | Apply a locally selected budget after interpreting the response fields. |
Search; limit=100, has_more=true, and next_page present | Search | 100 is an allowed search response size. | Use the supplied next_page token as the next request’s page value. | Additional search results are indicated. | Any item or request ceiling belongs to the application. | This is not a completed provider traversal. | “Receiving 100 results closes the search.” | If stopping, retain a policy-stop status rather than a completion status. |
Hypothetical failure walkthrough
Consider a hypothetical importer that asks for a list page with limit=100, receives 100 objects, sees has_more=true, and nevertheless treats those objects as a finished 100-object import budget. Under the documented list semantics, that would stop while the provider still reports further results.
The correction is architectural rather than a different cursor trick: name limit a page-size choice, retain a status that distinguishes an intentional application stop from provider traversal completion, and maintain any total-item or request allowance independently. Those status names, budgets, and follow-up handling are recommended local policy.
Client libraries offer automatic page traversal helpers, whereas raw curl requests do not have that library capability. Either approach can be paired with the same application-owned budget policy; automation does not transform page size into a whole-job ceiling.
Boundaries and alternatives
One viable approach is manual continuation: for lists, advance with the documented list cursor; for searches, advance with the returned search-page token. Another is a client-library auto-pagination helper. In both cases, evaluate the application’s stop rule separately from the provider’s continuation signal.
The supplied API reference states that /v2 has a different pagination interface, so this guidance must not be extended to that namespace. Cursor-family validation, ordering, durable recovery, and dataset-consistency guarantees are intentionally outside this article’s scope. Review this design when source behavior changes or when a version is retired or becomes incompatible.
The continuation step needs a fail-closed precondition stronger than “this request used
limit=100.” For a manual list traversal, authorize a follow-up only when the received response hashas_more=trueand supplies a usable final object ID from that response; constructstarting_afterfrom that ID only. Stripe’s documented list procedure is explicitly conditional onhas_more: when true, use the last returned object’s ID; when false, the traversal is complete. Stripe pagination documentationFailure path: if a response reports
has_more=truebut the data boundary cannot yield a final ID—for example, the response is incomplete at the application boundary—do not guess a cursor from the chosen page size, reuse an older cursor, or mark completion. Persist a blocked traversal state with the response evidence, emit no successor request, and retry or investigate from that checkpoint. That makes the unsafe state observable and prevents both an accidental skip and an infinite replay of a prior page.The corresponding recovery test is small and decisive: inject a response with
has_more=trueand no usable final ID, then verify that outbound request count remains unchanged, traversal state does not advance, and the recorded status is neither completed nor an intentional policy stop.