01API
Pagination
Every list is paged with a cursor, never an offset. A cursor names a position in a stable order, so a row is never shown twice and a row that was there is never skipped, even if the store's catalog is rebuilt, or an order changes, while you are paging.
The request
| Parameter | Meaning |
|---|---|
limit | How many to return. 1 to 100, default 50. The products search keeps its own range: 1 to 60, default 20. |
cursor | The next_cursor of the previous page. Opaque: do not build, read or change one. |
The answer
next_cursor is null on the last page. The products search answers { "query", "total", "products", "next_cursor" } (its original shape, with the cursor added); every other list is { "data", "next_cursor" }.
Follow it until it is null:
A cursor belongs to the request that made it: with different filters, or another endpoint, it is 400 bad_cursor. Start again without it.
The order of a list
| List | Order | Why |
|---|---|---|
| Orders, distributor orders, inventory | oldest change first (updated_at, then id) | So updated_since and the cursor together make an incremental sync |
| Webhook deliveries | newest first | It is a log |
| Products search | best match first, ending in the product key | The cursor is the position in that order |
Products with updated_since | oldest change first | A mirror of the catalog |
Syncing only what changed: updated_since
updated_since (an ISO 8601 date or time) is on products, orders, distributor orders and inventory. It returns what changed at or after that time. To mirror a store and keep it current:
- Note the time before you start (
T0). - Walk the whole list with
updated_since=1970-01-01(or the date of your last sync) and follownext_cursorto the end. - Next time, use
T0as yourupdated_since. Anything that changed while you walked is simply met again; handle it twice without harm.
For products, updated_since also returns removed: the keys of products that changed and are no longer visible (inactive, switched off, hidden). Drop them from your copy. total is null in this mode. A change to a product's library content (photos, specifications) reaches updated_since when the store's listing next changes.
Filters that go with it
Products: q, in_stock, category, type, firearm. Orders: status, source, store_order_number, ref. Distributor orders: status, distributor, order_id. Inventory: source, product_key, external_id, hidden. The exact values are in the reference.
The FFL Checkout lists (/checkout/ffls, /checkout/preferred) keep page, limit and total: they are sorted by distance inside a radius and are bounded.