

## `limit` and `offset` [#limit-and-offset]

Two endpoints paginate: `/v1/persons` and `/v1/teams`. Both take two query params:

| Param    | Default | Max | Meaning                             |
| -------- | ------- | --- | ----------------------------------- |
| `limit`  | 50      | 200 | Rows per page                       |
| `offset` | 0       | —   | Rows to skip before the page starts |

```bash title="page_2.sh"
curl -H "X-API-Key: $STATSHAWK_KEY" \
  "https://api.statshawk.ai/v1/persons?q=tatum&limit=50&offset=50"
```

Requesting a `limit` above 200 doesn't error — it's clamped to 200 server-side.

Other list endpoints (editions, contests, rosters, standings) don't take these
params: they return the full set for the scope you asked for, so narrow them with
their own filters — `date`, `competition`, and so on — instead of paginating.
(`/v1/analysis/stat-board` accepts a `limit`, but it caps the board's row count;
there is no `offset`.)

## Reading the response [#reading-the-response]

Every list response's `data` carries `items` (the page) and `total` (the full match
count, not just this page):

```json title="response shape"
{
  "data": {
    "items": [ /* up to `limit` rows */ ],
    "total": 812
  },
  "meta": { "request_id": "…", "fetched_at": "…", "cache": "HIT", "version": "v1" }
}
```

Use `total` to know when you've reached the end — keep incrementing `offset` by `limit`
until `offset + items.length >= total`.

```python title="paginate.py"
import os, requests
KEY = os.environ["STATSHAWK_KEY"]
BASE = "https://api.statshawk.ai/v1"

all_items, offset, limit = [], 0, 200
while True:
    page = requests.get(
        f"{BASE}/persons",
        headers={"X-API-Key": KEY},
        params={"limit": limit, "offset": offset},
        timeout=10,
    ).json()["data"]
    all_items.extend(page["items"])
    offset += limit
    if offset >= page["total"]:
        break

print(f"{len(all_items)} persons")
```

<PlaygroundLink href="/docs/api">
  Try /v1/persons in the playground →
</PlaygroundLink>
