Skip to main content
Every list endpoint in the API is cursor-paginated. You request a page size and, to advance, pass the opaque next_cursor from the previous page.

Query parameters

integer
Number of objects to return. Default 20, minimum 1, maximum 100. A value outside that range is rejected with 400 validation_failed (param: "limit", message limit must be 1..100) — it is not clamped.
string
An opaque cursor — the next_cursor returned by the previous page. Returns the page of results immediately after it. Omit to fetch the first page.

Response shape

All list responses share the same envelope:
array
The page of objects, newest first.
boolean
Whether more objects exist after this page.
string | null
The cursor to pass as after for the next page. null when has_more is false.
For object collections the cursor is the id of the last object on the page, so pagination stays stable even as new objects are created. Some collections (agent versions, deployment runs, files) are also object lists with their own ids and paginate identically. Always treat next_cursor as opaque — pass it back verbatim rather than constructing it yourself. The only list that does not use this envelope is the session events log (see below).The two catalogue reads — GET /v1/models and GET /v1/media/models — are not object collections: they are read from the provider, not from rows of ours, so their cursor is a position in that read rather than an id. Paging them works exactly as above, with one caveat worth knowing: if the upstream catalogue changes between two pages of the same walk, a boundary can shift by an entry. It is stable within a single read, which is what a search-and-pick flow needs; do not rely on it to enumerate the whole catalogue exactly once.

Worked example

Fetch every agent, one page of 50 at a time.
A typical loop:
Stop when has_more is false rather than relying on an empty data array.

The events log is a distinct contract

The session events log is not paginated with after / next_cursor. It is an append-only stream with its own resumable, gap-free seq cursor, and it returns events oldest-first (the opposite of the newest-first object lists above). This is a deliberately separate contract so you can resume a stream exactly where you left off.
integer
Return events with seq strictly greater than this value (exclusive). seq is monotonic per session, starts at 1, and is gap-free; it is mirrored as last_seq on the session object and as the SSE id: field. Omit to read from the beginning of the retained window.
Events are replayable for at least 72 hours. Persist the last seq you processed and resume with after_seq to guarantee exactly-once handling across reconnects. See Events.