Skip to main content
Lists always return the same envelope:
To get the next page, repeat the call with starting_after:
When has_more is false, next_cursor is null and you have reached the end.

Why cursors and not page numbers

Because the event carries on while you read. With ?page=2 and an OFFSET, every new ticket shifts the contents and you end up skipping or repeating rows. A cursor points at a specific element, so moving forward always means “whatever comes after this one”, no matter what happens behind you.

Incremental syncing

Combine the cursor with a time filter. Store when your last pass finished and start the next one from there.
Use updated_since, which filters by last modification. That way you receive both new tickets and those whose state changed — for instance, the ones accredited since your last pass.
Overlap your window a little. A terminal without connectivity may sync a sale hours after it happened, and that sale has an occurred_at earlier than your last pass: if you start exactly where you left off, you will never see it. Go back by whatever margin your operation tolerates — a few hours usually does — and deduplicate by id on your side.

Walking a whole list

A page may come back with fewer items than the limit you asked for and still have has_more: true. That happens when your key is restricted to certain ticket types and the page contained records outside your scope. Trust has_more, not the item count: stopping because a page came back short would leave data unread.