Pagination
Every list endpoint returns the same envelope and uses opaque, cursor-based paging. You request a page size with limit, and follow next_cursor until the API tells you there's nothing more. Cursors are encrypted tokens tied to the exact query that produced them.
The list envelope
- Name
object- Type
- string
- Description
Always
list.
- Name
data- Type
- array
- Description
The page of resources, newest-first unless the endpoint documents otherwise.
- Name
has_more- Type
- boolean
- Description
Whether more pages exist. Stop walking when this is
false.
- Name
next_cursor- Type
- string
- Description
Pass this back as
cursorto fetch the next page.nullon the last page.
- Name
url- Type
- string
- Description
The path this list was fetched from.
Response
{
"object": "list",
"data": [
{ "object": "template", "id": "template_00a1b2c3d4e5f607" }
// ...
],
"has_more": true,
"next_cursor": "hf8a2c1b9d0e...",
"url": "/v1/templates"
}
Request parameters
- Name
limit- Type
- integer
- Description
Page size,
1–100(default10). A value outside that range is rejected with400parameter_invalid(onlimit) rather than silently clamped. Some endpoints have a fixed size and ignore this: audit events page at 25, Lab runs at 50.
- Name
cursor- Type
- string
- Description
The previous response's
next_cursor, passed back verbatim.
Walking a collection
Fetch the first page, then keep passing next_cursor back as cursor until has_more is false.
# First page
curl -s -G https://api.synexcloud.com/v1/templates \
-H "Authorization: Bearer $SYNEX_API_KEY" \
-d limit=50
# Next page
curl -s -G https://api.synexcloud.com/v1/templates \
-H "Authorization: Bearer $SYNEX_API_KEY" \
-d limit=50 \
-d cursor=hf8a2c1b9d0e...
Cursor rules
Cursors are opaque, encrypted tokens. Treat them as a black box — you only
ever read next_cursor and pass it straight back as cursor.
- Never construct or modify a cursor. A malformed or tampered cursor returns
400invalid_cursor. - Don't persist cursors long-term. To resume later, restart from the first page.
- Cursors are tied to their query. Every filter joins the cursor's scope, so a cursor minted under one set of filters and replayed under another is
400invalid_cursor. Keep the filters identical for the whole walk and vary onlylimit.
Creation-time filters
Three list endpoints accept a creation window, generalising the bracket filter the audit log already had:
| Endpoint | Filter runs as |
|---|---|
GET /v1/templates | key condition |
GET /v1/ontologies | key condition |
GET /v1/imports | SQL WHERE |
- Name
created[gte]- Type
- string
- Description
Only objects created at or after this time.
- Name
created[lte]- Type
- string
- Description
Only objects created at or before this time.
Both bounds are inclusive of the whole second they name and accept unix seconds or an ISO string. An inverted range — a created[gte] later than created[lte] — is rejected with 400 parameter_invalid rather than returning an empty page.
None of the three scans. Only templates can return a short page, and only because its pre-existing category post-filter still applies.
The events feed accepts the same pair, applied as bounds on the evt_ id rather than as a scan over timestamps — so a narrow window is exact and cheap.
Endpoints that page differently
A few lists do not take the standard envelope's parameters. Assume the standard shape and these will surprise you:
| Endpoint | Difference |
|---|---|
GET /v1/audit_events | Fixed page of 25; limit is ignored. Filters are applied after a page is read, so a page can come back short or empty while has_more is true |
GET /v1/suppliers | No limit; pages at a fixed 25. Carries pending_invites on the first page only |
GET /v1/supplier_requests | No limit; fixed 25. The open filter is applied after the page is read, so short and empty pages are normal |
GET /v1/team/members | Unpaginated — every member in one response. has_more is always false |
GET /v1/lab/runs | A fixed-size window of the 50 most recent runs rather than a cursor walk |
Where a filter is applied after the page is read, page until has_more is false and never terminate on a short page.