# Pagination

> Brix list endpoints use opt-in cursor pagination: send limit, follow nextCursor until it is null. Which endpoints page, their limits, and a full loop.

Source: https://brixsignage.com/developers/pagination/

Brix uses cursor pagination. There are no page numbers.

## How it works

1. Send `?limit=N` on a list endpoint. This turns pagination on.
2. The response has `data` and `nextCursor`.
3. Send `?cursor=<nextCursor>` with the same `limit` to get the next page.
4. Stop when `nextCursor` is `null`.

```json
{ "data": [ { "id": "scr_..." } ], "nextCursor": "scr_..." }
```

- Treat the cursor as opaque. Pass it back as it came.
- A page can hold fewer than `limit` items even when more follow, for example with a key pinned to one location. Always follow `nextCursor`, do not stop on a short page.
- Without `limit`, these endpoints return the full list in one response. Use `limit` for large workspaces.

## Endpoints

| Endpoint | `limit` | Order | Notes |
| --- | --- | --- | --- |
| `GET /v1/screens` | 1 to 500 | by id | |
| `GET /v1/media` | default 100, max 500 | newest first | `?search=`, `?kind=`, `?state=`, `?folderId=` filters. `?count=1` adds `total`. |
| `GET /v1/media-folders`, `/v1/app-instances`, `/v1/creatives`, `/v1/signage-templates`, `/v1/layouts`, `/v1/banners`, `/v1/alert-rules`, `/v1/celebration-entries` | default 100, max 500 | newest first | `?search=` and `?count=1` as above. |
| `GET /v1/webhooks/deliveries` | default 50, max 200 | newest first | `?endpointId=`, `?status=` |
| `GET /v1/casts` | default 200, max 500 | newest first | `?status=active`. No cursor. |
| `GET /v1/playlists`, `GET /v1/schedules` | none | | Return the full list. |

## Loop over every screen

```bash
cursor=""
while :; do
  page=$(curl -s "https://api.brixsignage.com/v1/screens?limit=500${cursor:+&cursor=$cursor}" \
    -H "Authorization: Bearer $BRIX_API_KEY")
  echo "$page" | jq -r '.data[] | [.id, .name, .status] | @tsv'
  cursor=$(echo "$page" | jq -r '.nextCursor // empty')
  [ -z "$cursor" ] && break
done
```

The same loop in JavaScript:

```js
async function* allScreens(key) {
  let cursor = null;
  do {
    const url = new URL('https://api.brixsignage.com/v1/screens');
    url.searchParams.set('limit', '500');
    if (cursor) url.searchParams.set('cursor', cursor);
    const res = await fetch(url, { headers: { Authorization: `Bearer ${key}` } });
    if (!res.ok) throw new Error(`${res.status} ${(await res.json()).error}`);
    const page = await res.json();
    yield* page.data;
    cursor = page.nextCursor;
  } while (cursor);
}
```
