> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aiql.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Pagination

> Page through list endpoints using opaque cursors

All list endpoints return results one page at a time using cursor-based pagination. You request a page size and follow a cursor to walk through the full result set.

## Paginated endpoints

These endpoints return a page of results:

* `GET /workspaces`
* `GET /ingestions`
* `GET /queries`
* `GET /requests`

## Parameters

Control pagination with two query parameters:

| Parameter | Type      | Description                                                                        |
| --------- | --------- | ---------------------------------------------------------------------------------- |
| `limit`   | `integer` | Maximum number of items to return per page. Defaults to `20`, maximum `100`.       |
| `cursor`  | `string`  | Opaque cursor pointing to the page to fetch. Omit it to start from the first page. |

## Response shape

Every list response wraps the items in a page object:

| Field         | Type      | Description                                                                             |
| ------------- | --------- | --------------------------------------------------------------------------------------- |
| `data`        | `array`   | The items in this page.                                                                 |
| `next_cursor` | `string`  | Cursor to pass as `cursor` to fetch the next page. `null` when there are no more items. |
| `has_more`    | `boolean` | Whether more items are available after this page.                                       |

## Fetch the first page

Request a page without a cursor. Set `limit` to control the page size.

```bash theme={null}
curl "https://api.aiql.io/workspaces?limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

The response contains the items and a cursor for the next page:

```json theme={null}
{
  "data": [
    { "id": "ws_3a1b", "name": "Analytics" }
  ],
  "next_cursor": "eyJpZCI6IndzXzNhMWIifQ",
  "has_more": true
}
```

## Fetch the next page

Pass `next_cursor` from the previous response as the `cursor` parameter.

```bash theme={null}
curl "https://api.aiql.io/workspaces?limit=20&cursor=eyJpZCI6IndzXzNhMWIifQ" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Keep following `next_cursor` until `has_more` is `false` and `next_cursor` is `null`.

## Page through every item

Loop until there are no more pages.

<CodeGroup>
  ```python Python theme={null}
  import os
  from aiql import AiQL

  client = AiQL(api_key=os.environ["AIQL_API_KEY"])

  cursor = None
  while True:
      page = client.workspaces.list(limit=20, cursor=cursor)
      for workspace in page.data:
          print(workspace.id, workspace.name)
      if not page.has_more:
          break
      cursor = page.next_cursor
  ```

  ```typescript TypeScript theme={null}
  import { AiQL } from "@aiql.io/sdk";

  const client = new AiQL({ apiKey: process.env.AIQL_API_KEY });

  let cursor: string | null = null;
  do {
    const page = await client.workspaces.list({ limit: 20, cursor });
    for (const workspace of page.data) {
      console.log(workspace.id, workspace.name);
    }
    cursor = page.next_cursor;
  } while (cursor);
  ```
</CodeGroup>

<Note>
  Cursors are opaque. Do not parse, build, or modify them — treat each `next_cursor` as a token you pass back unchanged. A cursor stays valid as you page forward but is not guaranteed to be stable across long periods.
</Note>
