# Paging: limit, cursor, items, nextCursor

Lists in the API are paged with a cursor: `limit` bounds the page, `cursor` continues it, and the response carries `items` and, as long as more records follow, `nextCursor`. This page lists the limits, the four exceptions with `page`, and the loop that collects all pages.

> **Type:** reference
> **For:** Anyone who wants to read a list completely or show a page in a user interface.
> **Prerequisite:** an `ak_…` key with a `*.list` permission, in the example `scene.list` (class **Read only**)

## Cursor paging

| Part | Rule |
|---|---|
| `limit` (query parameter) | integer 1–200, default 50 |
| `cursor` (query parameter) | the value of `nextCursor` from the previous page. Omit it on the first call |
| `items` (response) | the records of this page |
| `nextCursor` (response) | the marker of the next page. **Missing** on the last page |
| `total` (response) | the total count where the route knows it. Otherwise the field is missing |

The cursor is stable under insertions: A record that is added while you page does not shift any page. 29 operations of the reference take `cursor`, 34 take `limit`.

```bash
curl -sS "$SZENERA_API/v1/scenes?limit=2" \
  -H "Authorization: Bearer $SZENERA_API_KEY"
```

The response, with each scene trimmed to four fields:

```json
{
  "items": [
    { "id": "scn_01KJPX8NH0SZENE00000000001", "name": "Notdienst & Wetter", "status": "published", "version": 4 },
    { "id": "scn_01KJPX8NH0SZENE00000000002", "name": "Wochenkarte", "status": "draft", "version": 1 }
  ],
  "nextCursor": "c2NuOjIwMjYtMDctMDY"
}
```

## Filtered lists: 25 and 100

The filtered administration lists (organizations, accounts, devices, roles, grants, keys) cap lower because every row carries more: default 25, at most 100. A `limit` above that answers `422 Validation.Failed`. The reference currently names no bound on `limit`. The limits that apply are 200/50 for cursor lists and 100/25 for the filtered administration lists (organizations, accounts, devices, roles, grants, keys).

## The exception: page

Four lists page with page numbers instead of a cursor, because a pagination bar (“Page 3 of 12”) needs the total count:

| Route | Content |
|---|---|
| `GET /v1/devices/{id}/commands` | commands of a device |
| `GET /v1/devices/{id}/events` | operations log of a device |
| `GET /v1/players/{id}/commands` | commands of a display |
| `GET /v1/players/{id}/events` | operations log of a display |

| Part | Rule |
|---|---|
| `page` | integer from 1, default 1 |
| `limit` | 1–200, default 50 |
| Response | `items`, `total`, `page`, `pageSize`, all four required |

`page` and `pageSize` come back in the response even though you sent them: They are the numbers that `total` refers to.

## Small collections

Small collections that cannot be paged answer with a plain list without an `items` envelope. The response shape is stated at the endpoint in the reference. A client that checks for `items` recognizes the difference by the structure.

## Collect all pages

```bash
cursor=""
while :; do
  antwort=$(curl -sS "$SZENERA_API/v1/scenes?limit=200${cursor:+&cursor=$cursor}" \
    -H "Authorization: Bearer $SZENERA_API_KEY")
  echo "$antwort" | jq -c '.items[]'
  cursor=$(echo "$antwort" | jq -r '.nextCursor // empty')
  [ -z "$cursor" ] && break
done
```

The loop ends as soon as `nextCursor` is missing. Do not treat an empty `items` block as the end, because the last page can be full.

## Command line

Every list command of `szenera` knows the same three flags:

| Flag | Effect |
|---|---|
| `--limit=<count>` | at most this many rows per page. A value outside the range from 1 to the cap of the route is rejected **locally** (exit 1) before a call goes out |
| `--cursor=<marker>` | continue reading from this marker. The header line of a result names it: “weiter mit --cursor=…” (continue with) |
| `--all` | follow all pages until no more come. The concatenated output carries no `nextCursor` |

```bash
szenera scene list --all --json | jq -r '.items[].id'
```

How to build a script from this is described under [Scripts and CI](/cli/scripts-and-ci).

## Related

- [What a response contains](/getting-started/response-contents)
- [Scripts and CI](/cli/scripts-and-ci)
