Skip to main content
List endpoints (GET /facade/render-jobs, GET /facade/brands, etc.) return at most 50 items per page and use opaque cursors to walk forward and backward.

Request

Query paramDefaultNotes
limit25Max 50.
cursorOpaque token from a previous response’s next_cursor or prev_cursor.
curl "https://api.kynva.ai/api/v1/facade/render-jobs?limit=50" \
  -H "Authorization: Bearer $KYNVA_API_KEY"

Response shape

{
  "data": [
    { "id": "job_01HV...", "...": "..." }
  ],
  "page": {
    "has_more": true,
    "next_cursor": "eyJpZCI6Impvb...",
    "prev_cursor": null
  }
}
FieldMeaning
dataThe page items.
page.has_moretrue if more pages exist after this one.
page.next_cursorPass as ?cursor= to fetch the next page. Absent on the last page.
page.prev_cursorPass as ?cursor= to fetch the previous page. Absent on the first page.

Walking all pages

async function* listAll<T>(url: string): AsyncGenerator<T> {
  let cursor: string | undefined;
  while (true) {
    const u = new URL(url);
    u.searchParams.set("limit", "50");
    if (cursor) u.searchParams.set("cursor", cursor);

    const res = await fetch(u, {
      headers: { Authorization: `Bearer ${process.env.KYNVA_API_KEY}` },
    });
    const page = await res.json();
    for (const item of page.data) yield item as T;

    if (!page.page.has_more) break;
    cursor = page.page.next_cursor;
  }
}

for await (const job of listAll<{ id: string }>(
  "https://api.kynva.ai/api/v1/facade/render-jobs"
)) {
  console.log(job.id);
}
import os, requests

def list_all(url: str):
    cursor = None
    while True:
        params = {"limit": 50}
        if cursor:
            params["cursor"] = cursor
        res = requests.get(
            url,
            headers={"Authorization": f"Bearer {os.environ['KYNVA_API_KEY']}"},
            params=params,
            timeout=30,
        )
        res.raise_for_status()
        page = res.json()
        yield from page["data"]
        if not page["page"]["has_more"]:
            break
        cursor = page["page"]["next_cursor"]

for job in list_all("https://api.kynva.ai/api/v1/facade/render-jobs"):
    print(job["id"])

Stability guarantees

  • Cursors are stable across the page being viewed — items added after you start paginating won’t shift your cursor.
  • Cursors are opaque — don’t decode or construct them yourself. The format may change between API versions.
  • Cursors are single-direction-tolerant: a next_cursor from one request can be passed back as cursor on the same endpoint, in any order.