---
title: "Pagination"
description: "How list endpoints page their results — the page and per_page parameters, response metadata, and a worked example."
canonical_url: https://developer.onepagecrm.com/api/pagination/
source: Markdown mirror of https://developer.onepagecrm.com/api/pagination/
---

List endpoints return results one page at a time. Two query parameters
control paging:

| Parameter | Default | Limits | Description |
| --- | --- | --- | --- |
| `page` | `1` | 1-indexed | Which page to return |
| `per_page` | `10` | Max `100` | Results per page |

## Response metadata

The `data` object of every list response includes the paging state
alongside the results:

```json
{
  "status": 0,
  "message": "OK",
  "timestamp": 1765456800,
  "data": {
    "contacts": [
      { "id": "5f...", "first_name": "Ada", "...": "..." }
    ],
    "total_count": 243,
    "page": 1,
    "per_page": 100,
    "max_page": 3
  }
}
```

| Field | Description |
| --- | --- |
| `total_count` | Total matching records across all pages |
| `page` | The page you got |
| `per_page` | Page size used for this response |
| `max_page` | The last page number — stop when `page` reaches it |

## Worked example: fetch every contact

Request the first page with the largest page size:

```bash
curl -u "USER_ID:API_KEY" \
  "https://app.onepagecrm.com/api/v3/contacts.json?page=1&per_page=100"
```

Then loop until you pass `max_page`:

```bash
page=1
max_page=1
while [ "$page" -le "$max_page" ]; do
  resp=$(curl -s -u "USER_ID:API_KEY" \
    "https://app.onepagecrm.com/api/v3/contacts.json?page=$page&per_page=100")
  echo "$resp" | jq -r '.data.contacts[].id'
  max_page=$(echo "$resp" | jq '.data.max_page')
  page=$((page + 1))
done
```

The same loop in Python:

```python
import requests

auth = ("USER_ID", "API_KEY")
url = "https://app.onepagecrm.com/api/v3/contacts.json"

page, max_page = 1, 1
contacts = []
while page <= max_page:
    data = requests.get(
        url, auth=auth, params={"page": page, "per_page": 100}
    ).json()["data"]
    contacts.extend(data["contacts"])
    max_page = data["max_page"]
    page += 1
```

## Tips

- **Use `per_page=100` for bulk reads.** Fewer requests means faster
  syncs and less chance of hitting [rate limits](/api/rate-limits/).
- **Keep query parameters identical across pages.** Changing filters or
  any other parameter mid-loop gives inconsistent pages.
- **Don't assume pages are stable under concurrent writes.** If records
  are created or deleted while you page, items can shift between pages
  — you may see a record twice or miss one. If completeness matters,
  de-duplicate by `id`, or re-fetch when `total_count` changes between
  pages.
- **Stop on `max_page`, not on an empty page.** It saves a request and
  is unambiguous.

## What to read next

- **[API reference](/api/reference/)** — which endpoints are lists, and their filter parameters.
- **[Rate limits](/api/rate-limits/)** — how fast you can page.
- **[OQL](/oql/overview/)** — for queries and aggregates across entities, often a better fit than paging everything down.
