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

# Pagination

> Every list endpoint uses the same opaque-cursor envelope.

List endpoints return a page of results and a cursor for the next page:

```json theme={null}
{
  "data": [ ... ],
  "pagination": { "next_cursor": "djEuQ2lwaGVydGV4dEV4YW1wbGU" }
}
```

To read the next page, send `next_cursor` back as `cursor`, with the same filters. When `next_cursor` is `null`, you have reached the last page.

```bash theme={null}
curl "https://api.teambuilder.ge/v1/employees?limit=100&cursor=djEuQ2lwaGVydGV4dEV4YW1wbGU" \
  -H "Authorization: Bearer $TEAMBUILDER_API_KEY"
```

## Parameters

| Parameter | Default | Notes |
| - | - | - |
| `limit` | `25` | 1 to 100 items per page. |
| `cursor` | none | The previous page's `next_cursor`. Omit it, or send it empty, for the first page. |

Stop when `next_cursor` is `null`. Do not infer the last page from a page shorter than `limit`.

## Cursors are opaque

* Treat a cursor as an opaque string: do not parse, build or modify one. Cursors are encrypted, and any change makes them invalid.
* A cursor is valid only for the list that issued it, for the same company (live and test keys never share cursors). Keep the same filters while you page.
* Do not store cursors for later. To resume a walk after a restart, begin from the first page.
* An invalid cursor returns `400 validation_failed` with the message `Invalid cursor`. Restart from the first page.

## Walking every page

<CodeGroup>
  ```javascript Node.js theme={null}
  async function* listAll(path, params = {}) {
    let cursor;
    do {
      const query = new URLSearchParams({ ...params, limit: "100", ...(cursor && { cursor }) });
      const res = await fetch(`https://api.teambuilder.ge/v1${path}?${query}`, {
        headers: { Authorization: `Bearer ${process.env.TEAMBUILDER_API_KEY}` },
      });
      if (!res.ok) throw new Error(`HTTP ${res.status}`);
      const page = await res.json();
      yield* page.data;
      cursor = page.pagination.next_cursor;
    } while (cursor);
  }

  for await (const employee of listAll("/employees")) {
    console.log(employee.employee_id, employee.email);
  }
  ```

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

  def list_all(path, **params):
      session = requests.Session()
      session.headers["Authorization"] = f"Bearer {os.environ['TEAMBUILDER_API_KEY']}"
      cursor = None
      while True:
          query = {**params, "limit": 100, **({"cursor": cursor} if cursor else {})}
          res = session.get(f"https://api.teambuilder.ge/v1{path}", params=query, timeout=10)
          res.raise_for_status()
          page = res.json()
          yield from page["data"]
          cursor = page["pagination"]["next_cursor"]
          if not cursor:
              break

  for employee in list_all("/employees"):
      print(employee["employee_id"], employee["email"])
  ```
</CodeGroup>

A full walk at `limit=100` costs one request per 100 items. Mind your [rate limit](/reference/rate-limits) on large companies.

## Ordering and consistency

| Endpoint | Order |
| - | - |
| `GET /v1/employees` | The order employees joined your company, oldest first |
| `GET /v1/employees/{id}/badges` | Newest award first |
| `GET /v1/leaderboard` | Rank |
| `GET /v1/departments` | The order departments were created, oldest first; `parent_id` carries the hierarchy |
| `GET /v1/shop/items` | The order items were added to the catalogue |
| `GET /v1/leaderboard/by-department` | Department name; always a single page, `next_cursor` is `null` |

Cursors are keyset-based, so a list that changes while you read it does not shift whole pages. Leaderboards are the exception: while people earn XP, rows move between pages, so a page-by-page walk of a board is **approximate**, and a row can repeat or be skipped. De-duplicate by `employee_id` if you export a full board.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.