Skip to the documentation

Pagination

Lists page by cursor. Follow the link to the next page, as given.

Every list answers one page, newest first (a run's pool, in ranking order), with a link to the next:

{
  "data": [ ... ],
  "links": { "next": "/api/v1/search?limit=20&cursor=WyIyMDI2LTEwLTAyVDE0OjAzOjExLjQwMloiLCI2ZjFjLi4uIl0" }
}
  • links.next is a path with the same limit and any filter already on it. Request it as given, against the same base URL. When it is null, that was the last page.
  • limit is 20 by default and at most 50 (50 and 100 for the audit trail). A number outside the range is clamped, and text is ignored.
  • A cursor is opaque. Do not parse it, build one, or keep one across a long time: pass back exactly the one a page linked to. An edited or truncated one is 400 invalid-cursor.
  • A cursor marks a place, not a snapshot. Rows added while you page appear on the first page and never shift a later one, so you will not see a row twice or skip one.
async function* eachSearch(headers: HeadersInit) {
  let next: string | null = '/api/v1/search?limit=50'
  while (next) {
    const page = await (await fetch(`https://liviamatch.com${next}`, { headers })).json()
    yield* page.data
    next = page.links.next
  }
}