PlatformHTTP API

Pagination

Read long lists one page at a time with continuation tokens and cursors.

Available

Long lists come back one page at a time. Send the continuation value from each response with your next request, and stop only when a response has none, because a page can be empty and still have more after it. The Catalog and Applications use opaque page tokens; other services use one of two older styles, described below.

Page tokens on /api routes

Paginated operations of the Catalog and Applications take two optional request fields and return one optional response field:

FieldDirectionMeaning
pageSizeRequestThe maximum number of entries in the page.
pageTokenRequestThe continuation from the previous page. Omit it for the first page.
nextPageTokenResponseThe continuation for the next page. Absent or null on the last page.

The fields are in the query string of a GET operation, and in the JSON body of a POST operation. For example, list the branches of a Project:

curl "https://api.spiraldb.dev/api/catalog/projects/$PROJECT_ID/branches?pageSize=100" \
  -H "Authorization: Bearer $SPIRAL_TOKEN"

Follow these rules:

  • Treat a page size as a maximum. A page can contain fewer entries, or no entries, and still have a nextPageToken. Only an absent token ends the list.
  • Treat tokens as opaque. Do not decode, change, or construct a token.
  • Keep the other parameters. Send the same filters and page size with each token. A token is bound to the operation, the Project, the filters, the page size, and the caller's authorization scope.
  • Start again after a token error. The service returns an INVALID_ARGUMENT error for a malformed, expired, or mismatched token. It does not restart the list for you.

The service checks authorization again for each page, so a token never grants access on its own.

The Catalog validates pageSize from 1 to 1000, and uses 100 when you omit it. Other services state their range in their reference.

Snapshot and live lists

Each paginated operation states its consistency in its reference:

  • Snapshot lists read one immutable Project commit, such as the namespace entries or the state of a commit. The service binds every token to that commit, and the response includes its commitId. Concurrent writes do not change the pages.
  • Live lists read current state, such as branches, tags, and Project events. A concurrent change can omit an entry or show it twice across pages. For a consistent view of a whole Project, read an immutable commit instead.

Page tokens on other services

Organizations, Projects, Storage, and workload identities use snake_case fields:

FieldDirectionMeaning
page_sizeQueryThe maximum number of entries.
page_tokenQueryThe continuation from the previous page.
itemsResponseThe entries in this page.
next_page_tokenResponseThe continuation for the next page, or null.

Watch out for one difference: some of these lists return every entry in one page, and reject page_size and page_token with status 400. These lists are the Organizations of the caller (GET /v1/organizations), Projects (GET /v1/projects), mounts, workloads, and workload trust policies. Send no paging parameters to them.

The users and invitations of an Organization accept a page_size from 1 to 100, and use 10 when you omit it.

Cursors on Tasks and worker pools

Tasks, worker pools, worker sessions, and task triggers use an item cursor:

FieldDirectionMeaning
limitQueryThe maximum number of entries, where the operation accepts it.
afterQueryThe ID of the last entry that you received.
nextResponseThe cursor for the next page. Absent or null on the last page.

Send the value of next as after in the next request. The entries are in a field named for them, such as tasks or workerSessions. Trigger lists use items.

curl "https://api.spiraldb.dev/projects/$PROJECT_ID/tasks?after=$NEXT&limit=50" \
  -H "Authorization: Bearer $SPIRAL_TOKEN"

These cursors read live state. A cursor is an item ID, so a new entry that sorts before the cursor does not appear on later pages.

Found a problem? Edit this page or report an issue.

On this page