# Pagination and syncing

## Pages

Lists answer one page at a time, newest first:

```json
{
  "object": "list",
  "data": [ ... ],
  "has_more": true,
  "next_cursor": "eyJ0IjoiMjAyNi0xMS0xMFQwODoxNTowMC4wMDAwMDArMDA6MDAiLCJpZCI6Ii4uLiJ9"
}
```

- **`limit`** sets the page size, from 1 to 250 (default 50).
- **`cursor`** fetches the next page: pass `next_cursor` from the page you have, unchanged.
- **The last page** has `has_more: false` and `next_cursor: null`.

Cursors are opaque: don't build or change them. A deep page costs the same as the first.

## Time filters

Every list takes these, as ISO 8601 times with a time zone (`2026-11-10T08:15:00Z`):

| Parameter        | Includes                      |
| ---------------- | ----------------------------- |
| `created_at_min` | created at or after this time |
| `created_at_max` | created before this time      |
| `updated_at_min` | changed at or after this time |
| `updated_at_max` | changed before this time      |

Min is inclusive and max exclusive, so consecutive windows neither miss nor repeat anything.

`updated_at` changes when anything about the object changes, including its parts:

- **a product:** its variants, images, options, categories or collections;
- **an order:** its lines, payments, shipment or returns;
- **a customer:** their addresses or tags.

## Syncing changes

To keep another system up to date:

1. Remember when your last sync **started** (not finished).
2. Fetch everything changed since then: `GET /v1/orders?updated_at_min=<that time>`, following `next_cursor` to the end.
3. Save each object by its `id`. Seeing the same object twice is fine.
4. Store the new start time for next time.

Lists page by creation time, so an object changed while you are paging stays where it was. The change is picked up by the next sync.

For changes within seconds, use [webhooks](/webhooks), and run this sync every hour or so as a safety net.
