Pagination and sync
Lists are paged with an opaque cursor, and the same ordering that pages a register is the one that syncs it.
Walking a list
Ask for a page. If has_more is true, pass next_cursor back.
curl "https://your-workspace.kitset.io/api/v1/assets?limit=100" \
-H "Authorization: Bearer $KITSET_KEY"
import httpx
def walk(client, path):
cursor = None
while True:
params = {"limit": 500}
if cursor:
params["cursor"] = cursor
page = client.get(path, params=params).raise_for_status().json()
yield from page["data"]
if not page["has_more"]:
return
cursor = page["next_cursor"]
limit defaults to 100 and may go to 1000.
What the cursor is
A signed position in the result, not a page number. Three consequences worth knowing:
- Keep the filters identical between pages. The cursor records the filters it was issued under, and a request that changes them is refused rather than silently walking rows the first filter excluded.
- Do not edit it. An altered cursor is refused. It is not a base64 offset you can increment.
- A cursor is not a bookmark. Use it to finish a walk, not to resume one tomorrow. For that, use
updated_since.
There is no total. Counting would mean a second pass over the whole filtered set on every page, and the number would be stale before you read it. has_more is what a walk actually needs.
Keeping a mirror current
Every record carries updated_at, and every list can be filtered on it.
curl "https://your-workspace.kitset.io/api/v1/assets?updated_since=2026-09-19T00:00:00Z" \
-H "Authorization: Bearer $KITSET_KEY"
The pattern that works:
- Walk the full register once and record the highest
updated_atyou saw. - On each later run, pass that value as
updated_sinceand walk again. - Move your watermark forward only when the walk finishes.
Overlap deliberately. Subtract a few minutes from your watermark before sending it. Records are stamped when they are written rather than when the transaction commits, so a long write can commit a row stamped slightly earlier than one you have already seen. Re-reading a handful of rows costs nothing; missing one is silent and permanent, because the next edit moves that row past the window you missed it in.
Deletions are not visible to a poll. A record removed from kitset stops appearing in the list, and nothing tells you which one went. If your mirror must notice deletions, reconcile ids on a full walk periodically rather than relying on the delta.
Filters
Each endpoint accepts the filters named in the reference, plus search where the register supports it. A filter value outside the set an endpoint accepts is an error rather than an empty page — an empty page and "nothing matched" are indistinguishable, and a mirror that reads one as the other deactivates every record it holds.