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

# Pagination

> Pagination par offset et par curseur dans l'API Retriever, avec exemples de boucles en Node et Python.

L'API utilise deux types de pagination.

| Type    | Routes                                                                                  | Paramètres                                        | Réponse                  |
| ------- | --------------------------------------------------------------------------------------- | ------------------------------------------------- | ------------------------ |
| Offset  | `GET /v1/runs`, `/v1/workspaces`, `/v1/workspaces/{id}/tables`, `/v1/exclusions/{kind}` | `limit` (1–1000, défaut 100), `offset` (défaut 0) | `items` et `next_offset` |
| Curseur | `GET /v1/tables/{id}/rows`, `/v1/runs/{id}/output/tables/{key}/rows`                    | `limit` (1–1000, défaut 100), `cursor`            | `items` et `next_cursor` |

* `next_offset` ou `next_cursor` vaut `null` sur la dernière page.
* Le curseur est opaque : ne le décodez pas. Il appartient à une table ou à un run précis ; ailleurs, il donne `400 invalid_cursor`.
* Les listes par offset lisent l'état actuel : elles ne figent pas la liste entre deux appels.
* Workspaces et exclusions refusent tout paramètre de query inconnu (`400`).

## Parcourir toutes les lignes d'une table

<CodeGroup>
  ```js Node theme={null}
  const API = process.env.RETRIEVER_API_URL;
  const HEADERS = { Authorization: `Bearer ${process.env.RETRIEVER_API_KEY}` };

  async function* rows(tableId) {
    let cursor = null;
    do {
      const qs = new URLSearchParams({ limit: "1000", ...(cursor ? { cursor } : {}) });
      const res = await fetch(`${API}/v1/tables/${tableId}/rows?${qs}`, { headers: HEADERS });
      const page = await res.json();
      if (!res.ok) throw new Error(`${res.status} ${page.error.code}`);
      yield* page.items;
      cursor = page.next_cursor;
    } while (cursor);
  }

  for await (const row of rows("tbl_001")) console.log(row.values);
  ```

  ```python Python theme={null}
  import os, requests

  API = os.environ["RETRIEVER_API_URL"]
  HEADERS = {"Authorization": f"Bearer {os.environ['RETRIEVER_API_KEY']}"}

  def rows(table_id):
      cursor = None
      while True:
          params = {"limit": 1000, **({"cursor": cursor} if cursor else {})}
          res = requests.get(f"{API}/v1/tables/{table_id}/rows", headers=HEADERS, params=params, timeout=30)
          res.raise_for_status()
          page = res.json()
          yield from page["items"]
          cursor = page["next_cursor"]
          if not cursor:
              break

  for row in rows("tbl_001"):
      print(row["values"])
  ```

  ```bash cURL theme={null}
  curl "$RETRIEVER_API_URL/v1/tables/tbl_001/rows?limit=100" -H "Authorization: Bearer $RETRIEVER_API_KEY"
  # page suivante : reprendre next_cursor
  curl "$RETRIEVER_API_URL/v1/tables/tbl_001/rows?limit=100&cursor=eyJ0YWJsZUlkIjoi..." -H "Authorization: Bearer $RETRIEVER_API_KEY"
  ```
</CodeGroup>
