Pagination
Page through any list with limit and after, until next is null.
Every list works the same way. Ask for a page with limit, and you get { data, next }. next is a cursor: pass it back as after to get the following page. When next is null, you have them all.
Page through a list
curl "https://api.boxline.dev/v1/agent/runs?limit=50" \ -H "x-api-key: $BOXLINE_API_KEY"# {"data": [...], "next": "eyJvIjoiY3JlYXRlZF9kZXNjIiwidCI6…"}curl "https://api.boxline.dev/v1/agent/runs?limit=50&after=eyJvIjoiY3JlYXRlZF9kZXNjIiwidCI6…" \ -H "x-api-key: $BOXLINE_API_KEY"// One page: await the list.const page = await bx.agent.list({ limit: 50 });console.log(page.data.length, page.next);// The following page, with the same filters.if (page.hasNextPage()) { const second = await page.getNextPage(); console.log(second.data.length);}// Every item: iterate the list, and the SDK follows next for you.for await (const run of bx.agent.list({ limit: 50 })) console.log(run.id, run.status);# One page: the list call returns it.page = bx.agent.list(limit=50)print(len(page.data), page.next)# The following page, with the same filters.if page.has_next_page(): second = page.get_next_page() print(len(second.data))# Every item: iterate the list, and the SDK follows next for you.for run in bx.agent.list(limit=50): print(run["id"], run["status"])Rules
nextis opaque: do not build or change it. Send it back with the same filters and sort as the page it came from. A cursor from another list, or changed, gets400 invalid_cursor.- New items do not shift the pages you are reading, as offsets would.
- Lists that return
total(sessions, profiles) still do. There is nooffset: a list takesafteronly, andoffsetis400 invalid_request. - The session event log also returns
nextAfter, the last event’s number. Keep it to poll for new events later: there,nextbecomesnullonce you have caught up.
Every list
| List | limit default / maximum | Order |
|---|---|---|
GET /v1/sessions | 50 / 500 | The sort you ask for (newest first by default) |
GET /v1/profiles | 50 / 200 | Newest first |
GET /v1/credentials | 100 / 200 | Name order |
GET /v1/credentials/audit | 50 / 200 | Newest first |
GET /v1/extensions | 50 / 200 | Newest first |
GET /v1/project/api-keys | 100 / 100 | Oldest first |
GET /v1/agent/runs | 20 / 100 | Newest first |
GET /v1/tasks | 50 / 200 | Newest first |
GET /v1/tasks/:id/runs | 20 / 100 | Newest first |
GET /v1/crawls | 20 / 100 | Newest first |
GET /v1/crawls/:id (the crawl's pages; limit=0 for none) | 50 / 100 | The order pages were found |
GET /v1/sessions/:id/events | 500 / 2000 | Oldest first |
GET /v1/sessions/:id/pages | 1000 / 1000 | First visit |
GET /v1/webhooks | 100 / 200 | Oldest first |
GET /v1/webhooks/:id/deliveries | 20 / 100 | Newest first |
In the SDKs
Every list method of the SDKs takes limit and after and returns the first page, with data, next, and total where the list has it. Iterate it (Node: for await, Python: for, async Python: async for) to go through every item: the SDK asks for the following pages as you go. A crawl’s pages have their own helper, bx.crawl.pages(id).
These docs describe a beta API. Endpoints, fields and SDK methods may change before general availability; breaking changes will be listed in the changelog.