Reference

Pagination

List endpoints page with an opaque cursor, not page numbers. Cursors are stable under inserts — new rows arriving while you page won't shift or duplicate results — which makes them the right tool for high-write logs like events and the ledger.

Requesting a page

Two parameters, both optional:

  • limit — page size, default 50, max 200.
  • cursor — the opaque cursor for the next (or previous) page. Omit it for the first page.
First page bash
curl "https://api.flyhalf.run/v1/events?limit=50" \
  -H "Authorization: Bearer fh_live_…"

The response shape

Cursor-paginated collection json
{
  "data": [ /* … up to `limit` items, newest first … */ ],
  "links": {
    "first": null,
    "last": null,
    "prev": null,
    "next": "https://api.flyhalf.run/v1/events?cursor=eyJpZCI6MTA0Mn0"
  },
  "meta": {
    "path": "https://api.flyhalf.run/v1/events",
    "per_page": 50,
    "next_cursor": "eyJpZCI6MTA0Mn0",
    "prev_cursor": null
  }
}

Cursor pagination doesn't know first/last positions, so links.first and links.last are always null. Walk forward with links.next (or meta.next_cursor) and stop when next is null. Results are ordered newest-first.

Walking every page

Follow next until null js
let url = 'https://api.flyhalf.run/v1/events?limit=200';

while (url) {
  const res = await fetch(url, { headers: { Authorization: 'Bearer fh_live_…' } });
  const page = await res.json();

  handle(page.data);

  url = page.links.next;   // null on the last page → loop ends
}

Treat the cursor as opaque

Cause of subtle breakage: parsing or hand-building the cursor. It's an encoded token whose format is not a contract and can change. Fix: only ever pass back a cursor the API handed you, via links.next or meta.next_cursor.

Filters compose with the cursor

Endpoint filters carry across pages automatically as long as you follow the returned links. For example the event log takes status, event_type, participant (external id) and since (ISO timestamp); GET /v1/participants takes search. The links.next URL already includes your filters alongside the cursor.

Every list endpoint pages this way — events, participants, the ledger, flows, flow runs, event types, ingest endpoints, message templates and webhook subscriptions. One convention, no exceptions.