Skip to content
Tendral Health

Pagination

List endpoints return a page at a time and a cursor for the next page. Order is stable, so walking a list never skips or repeats a row.

The list shape

List response
{
  "object": "list",
  "livemode": true,
  "data": [],
  "has_more": true,
  "next_cursor": "eyJhdCI6IjIwMjYtMDQtMjdUMTM6MDI6MDBaIn0",
  "url": "/v1/…?limit=100"
}
  • data holds up to limit items. limit defaults to 100 and takes a whole number from 1 to 500; anything else gets 400 with code INVALID_PARAMETER.
  • has_more is true when there is another page.
  • next_cursor goes back as ?cursor= for the next page. It is null on the last page.
  • url echoes the path and query you sent.

Cursors

A cursor is opaque. Pass it back unchanged; a cursor the API did not return gets 400 with code INVALID_PARAMETER. Cursors are built from a timestamp and an id together, so rows that share a timestamp still come back in one fixed order.

Walk every page

Node
async function* everyItem(firstPageUrl: string) {
  let cursor: string | null = null
  do {
    const url = new URL(firstPageUrl)
    if (cursor) url.searchParams.set('cursor', cursor)
    const res = await fetch(url, { headers: { Authorization: `Bearer ${process.env.TENDRAL_API_KEY}` } })
    const page = await res.json()
    yield* page.data
    cursor = page.has_more ? page.next_cursor : null
  } while (cursor)
}