API

Pagination

How list endpoints page their results — the page and per_page parameters, response metadata, and a worked example.

Last updated Jun 12, 2026

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

ParameterDefaultLimitsDescription
page11-indexedWhich page to return
per_page10Max 100Results per page

Response metadata

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

{
  "status": 0,
  "message": "OK",
  "timestamp": 1765456800,
  "data": {
    "contacts": [
      { "id": "5f...", "first_name": "Ada", "...": "..." }
    ],
    "total_count": 243,
    "page": 1,
    "per_page": 100,
    "max_page": 3
  }
}
FieldDescription
total_countTotal matching records across all pages
pageThe page you got
per_pagePage size used for this response
max_pageThe last page number — stop when page reaches it

Worked example: fetch every contact

Request the first page with the largest page size:

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:

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:

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.
  • 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.
  • API reference — which endpoints are lists, and their filter parameters.
  • Rate limits — how fast you can page.
  • OQL — for queries and aggregates across entities, often a better fit than paging everything down.