Getting started
Page through list endpoints with page and limit, skip, or cursors, and keep a local copy in sync with updatedSince.
List endpoints return results a page at a time. Most use one of three styles: numbered pages, offsets, or opaque cursors. Each endpoint's parameters in the API reference tell you which one it takes. This page shows how to walk each style to the end.
#Numbered pages: page and limit
Posts, accounts, analytics and most ads lists take page (starting at 1) and limit, and return a pagination object:
curl "https://api.pozy.ai/v1/posts?status=published&page=1&limit=100" \
-H "Authorization: Bearer $POZY_API_KEY"const all = [];
for (let page = 1; ; page++) {
const res = await fetch(`https://api.pozy.ai/v1/posts?${new URLSearchParams({ status: "published", page: String(page), limit: "100" })}`, {
headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
all.push(...data.posts);
if (page >= data.pagination.pages) break;
}import os, requests
headers = {"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"}
posts, page = [], 1
while True:
resp = requests.get(
"https://api.pozy.ai/v1/posts",
headers=headers,
params={"status": "published", "page": page, "limit": 100},
timeout=30,
).json()
posts += resp["posts"]
if page >= resp["pagination"]["pages"]:
break
page += 1{
"posts": [ { "_id": "6721a0c47b2e5f9d3a18c6e0", "status": "published" } ],
"pagination": { "page": 1, "limit": 100, "total": 342, "pages": 4 }
}GET /v1/posts defaults to 10 per page and accepts up to 500. GET /v1/accounts returns every account when you send no paging parameters at all, and up to 500 per page when you do.
Numbered pages can shift if items are added or removed while you read: a new post can push an old one onto the next page, so you see it twice. For a full export, prefer a cursor where the endpoint offers one, or dedupe by _id.
#Offsets: skip and limit
Webhook delivery logs, tracking windows, creator payouts and money endpoints take skip (how many to jump over) and limit. The response says whether more remain:
curl "https://api.pozy.ai/v1/webhooks/logs?status=failed&limit=100&skip=200" \
-H "Authorization: Bearer $POZY_API_KEY"{
"logs": [ { "_id": "dlv_0c1Fq8Lr2Zt7Wm4Kx9Pa", "event": "post.published", "status": "failed" } ],
"pagination": { "total": 241, "skip": 200, "limit": 100, "hasMore": false }
}Add limit to skip for the next page and stop when hasMore is false.
#Cursors: cursor and nextCursor
Inbox conversations, comments, leads, follower stats, the analytics change feed and most newer endpoints use cursors. Send limit alone for the first page, then pass the nextCursor you got back as cursor. Stop when nextCursor is null.
curl "https://api.pozy.ai/v1/inbox/conversations?limit=100" \
-H "Authorization: Bearer $POZY_API_KEY"
# next page
curl "https://api.pozy.ai/v1/inbox/conversations?limit=100&cursor=eyJpZCI6IjY3MjE..." \
-H "Authorization: Bearer $POZY_API_KEY"let cursor: string | undefined;
do {
const query = new URLSearchParams({ limit: "100" });
if (cursor) query.set("cursor", cursor);
const res = await fetch(`https://api.pozy.ai/v1/inbox/conversations?${query}`, {
headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);
for (const c of data.data) handle(c);
cursor = data.pagination.nextCursor ?? undefined;
} while (cursor);cursor = None
while True:
params = {"limit": 100}
if cursor:
params["cursor"] = cursor
resp = requests.get(
"https://api.pozy.ai/v1/inbox/conversations",
headers=headers, params=params, timeout=30,
).json()
for c in resp["data"]:
handle(c)
cursor = resp["pagination"].get("nextCursor")
if not cursor:
breakCursors are opaque. Pass them back exactly as you got them: do not parse, build or compare them. A page can hold fewer items than limit, or even none, while nextCursor is still set. Keep going until it is null.
GET /v1/accounts takes a cursor too: send limit without page and follow pagination.nextCursor. Cursor pages are ordered by account id, so accounts added or removed mid-walk never shift a page. You cannot combine cursor with page, sort or perProfile.
#Other styles you will meet
| Parameters | Used by | How to walk |
|---|---|---|
before + limit |
Changelog, call history | Pass the previous response's nextCursor as before. It is a timestamp; stop when it is null. |
after + limit |
Reddit search, Discord members, WhatsApp groups, some ads reports | Pass the returned after (or paging.after) back until it is empty. |
pageToken |
Google Business reviews, media and keywords | Pass the returned nextPageToken as pageToken. |
since + until |
Account insights | Date ranges, not pages. Split long ranges into smaller windows. |
Some platform-backed lists inherit the platform's quirks, for example a cursor that must be reused with the same limit. The platform pages call these out.
#Keep a local copy in sync
To mirror posts into your own database, do one full walk, then ask only for what changed:
curl "https://api.pozy.ai/v1/posts?updatedSince=2026-10-30T09:00:00Z&limit=500" \
-H "Authorization: Bearer $POZY_API_KEY"Store the time you started each sync and use it as the next updatedSince, a minute or two earlier to cover clock drift. Better still, update your copy from webhooks (post.published, post.failed and the rest) and run the updatedSince sync as a nightly safety net.
#Tips
- Use the largest
limitthe endpoint allows when you read everything. Fewer pages means fewer requests against your rate limit. - Filter on the server (
profileId,accountId,platform,status, date ranges) instead of fetching everything and filtering yourself. - Out-of-range values are rejected with
400, not silently clamped. Check the bounds in the reference.