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

# Pagination

> Keyset cursors — page 500 costs the same as page 1.

Every list endpoint is **cursor-paginated**. There are no `OFFSET`/`page=N` parameters, because they get linearly slower as you go deeper. Duro uses keyset cursors so every page is equally cheap.

## Request

```
GET /v1/customers?limit=20
GET /v1/customers?limit=20&cursor=cus_01HKBZ4PQ9Z3K7
```

| Param    | Default | Max | Notes                                                             |
| -------- | ------- | --- | ----------------------------------------------------------------- |
| `limit`  | 20      | 100 | Page size.                                                        |
| `cursor` | —       | —   | The `nextCursor` from the previous page. Omit for the first page. |

## Response

```json theme={null}
{
  "items": [ /* … */ ],
  "nextCursor": "cus_01HKBZ4PQ9Z3K7",
  "hasMore": true
}
```

* `items` — the page, newest first (`createdAt desc, id desc`).
* `nextCursor` — pass this as `cursor` to get the next page. `null` on the last page.
* `hasMore` — `true` if another page exists.

## Iterating

```bash theme={null}
cursor=""
while :; do
  resp=$(curl -s "$DURO_API/v1/customers?limit=100&cursor=$cursor" -H "Authorization: Bearer $DURO_KEY")
  # …process items…
  cursor=$(echo "$resp" | jq -r '.nextCursor')
  [ "$cursor" = "null" ] && break
done
```

Cursors are ordered on a `(createdAt, id)` compound index, so the query plan is identical whether you're on page 1 or page 1,000.
