# Pagination

> List endpoints return newest-first pages with a has_more flag. Page backwards with the before cursor.

List endpoints (`GET /v1/verifications`, `/v1/consents` and `/v1/bulk`) return objects newest first, in this shape:

**List response**

```json
{
  "object": "list",
  "data": [
    "…"
  ],
  "has_more": true
}
```

## Parameters

| Parameter | Description |
| --- | --- |
| `limit` | Items per page, 1 to 100. Defaults to 20 for verifications, 50 for consents and bulk jobs. |
| `before` | Cursor: the `created_at` of the **last** item on the previous page. Returns items created strictly before it. |

`has_more` is `true` when at least one more item exists beyond this page. Lists are scoped to the mode of your key.

## Walking every page

_cURL_

```bash
curl "http://localhost:4000/v1/verifications?limit=100&before=2026-10-19T09%3A41%3A07.512Z" \
  -H "Authorization: Bearer sk_test_..."
```

_Node.js_

```javascript
const res = await fetch("http://localhost:4000/v1/verifications?limit=100&before=2026-10-19T09%3A41%3A07.512Z", {
  method: "GET",
  headers: {
    Authorization: `Bearer ${process.env.SPEEDMAP_API_KEY}`,
  },
});

const page = await res.json();
if (!res.ok) throw new Error(page.error.message);
console.log(page);
```

_Python_

```python
import os, requests

res = requests.get(
    "http://localhost:4000/v1/verifications",
    headers={
        "Authorization": f"Bearer {os.environ['SPEEDMAP_API_KEY']}",
    },
    params={
        "limit": "100",
        "before": "2026-10-19T09:41:07.512Z"
    },
    timeout=30,
)
res.raise_for_status()
print(res.json())
```

_Node.js_

```javascript
async function* allVerifications(params = {}) {
  let before;
  while (true) {
    const qs = new URLSearchParams({ limit: "100", ...params, ...(before && { before }) });
    const res = await fetch(`${process.env.SPEEDMAP_API_URL}/v1/verifications?${qs}`, {
      headers: { Authorization: `Bearer ${process.env.SPEEDMAP_API_KEY}` },
    });
    const page = await res.json();
    yield* page.data;
    if (!page.has_more) return;
    before = page.data.at(-1).created_at;
  }
}

for await (const v of allVerifications({ product: "nin" })) console.log(v.reference_id, v.status);
```

_Python_

```python
import os, requests

def all_verifications(**params):
    before = None
    while True:
        query = {"limit": 100, **params, **({"before": before} if before else {})}
        res = requests.get(
            os.environ["SPEEDMAP_API_URL"] + "/v1/verifications",
            headers={"Authorization": f"Bearer {os.environ['SPEEDMAP_API_KEY']}"},
            params=query,
            timeout=30,
        )
        page = res.json()
        yield from page["data"]
        if not page["has_more"]:
            return
        before = page["data"][-1]["created_at"]

for v in all_verifications(product="nin"):
    print(v["reference_id"], v["status"])
```

Filters (`product`, `status` on verifications) combine with the cursor, so keep them the same on every page. Verification lists always contain the assertion view, never `data`.

---

Source: https://speedmap-delta.vercel.app/docs/pagination
