Skip to content

Pagination

Lists that can grow long come a page at a time. Ask for up to 200 at once, and follow next_cursor until it is null.

How it works

Paged lists take limit and cursor as query parameters, and answer with next_cursor beside data. Pass it back unchanged to get the next page. When it is null, that was the last one.

Query parameters

limitinteger
How many to return, 1–200. Defaults to 50.
cursorstring
The next_cursor from the previous page. Opaque — don't build or edit one; an edited cursor answers 400.
curl "https://qarunbook.com/api/v1/issues?app=Checkout&limit=1" \
  -H "Authorization: Bearer $QARUNBOOK_KEY"
Response · 200
{
  "data": [
    {
      "id": "mfr8w1c4d2e",
      "app": {
        "id": "mfq3k2p9x1a",
        "name": "Checkout"
      },
      "check": {
        "id": "mfq3k2qa7bc",
        "ref": "AUTH-01",
        "title": "Sign in with email and password"
      },
      "text": "The Sign in button does nothing on Safari 18. No error, no network request.",
      "platforms": ["WL"],
      "all_platforms": false,
      "status": "open",
      "raised_by": "Ada Lovelace via API",
      "raised_at": "2026-09-27T16:02:11.482Z",
      "reporter": {
        "name": "Ada Lovelace",
        "email": "ada@example.com"
      },
      "via": "api",
      "edited_by": null,
      "edited_at": null,
      "fixed_by": null,
      "fixed_at": null,
      "attachments": []
    }
  ],
  "next_cursor": "eyJhdCI6IjIwMjYtMDktMjdUMTY6MDI6MTEuNDgyWiIsImlkIjoibWZyOHcxYzRkMmUifQ"
}

Which lists are paged

  • Issues — newest first. The cursor marks a place in time, so issues raised while you are paging never shift the pages you have not read yet. With sort=fixed_at, most recently fixed first.
  • Results — most recently recorded first, the same way.
  • Checks — in runbook order. Status is worked out fresh on every read, so a check filtered by status can move between pages if somebody records a result while you are paging.
  • Apps and sections are not paged. A workspace has tens of them, not thousands, and they come back whole.

Reading every page

JavaScript
let cursor = null;
const all = [];
do {
  const url = new URL("https://qarunbook.com/api/v1/issues");
  url.searchParams.set("app", "Checkout");
  url.searchParams.set("status", "all");
  url.searchParams.set("limit", "200");
  if (cursor) url.searchParams.set("cursor", cursor);

  const res = await fetch(url, {
    headers: { Authorization: `Bearer ${process.env.QARUNBOOK_KEY}` },
  });
  const { data, next_cursor } = await res.json();
  all.push(...data);
  cursor = next_cursor;
} while (cursor);
Python
import os, requests

issues, cursor = [], None
while True:
    params = {"app": "Checkout", "status": "all", "limit": 200}
    if cursor:
        params["cursor"] = cursor
    body = requests.get(
        "https://qarunbook.com/api/v1/issues",
        params=params,
        headers={"Authorization": f"Bearer {os.environ['QARUNBOOK_KEY']}"},
    ).json()
    issues += body["data"]
    cursor = body["next_cursor"]
    if not cursor:
        break

Something unclear or missing? Write to hello@qarunbook.com.