Pagination, Limits & Errors
Cursor pagination
The API uses opaque cursor pagination — no page numbers or offsets. This is stable even as new data arrives.
| Field | Meaning |
|---|---|
limit | Items per page — 1–200, default 50. |
cursor | Opaque token; omit on the first call. |
nextCursor | Pass this back for the next page. |
hasMore | false means you’ve reached the end. |
Results are ordered newest-first (createdAt desc, or clickedAt for clicks). The
cursor encodes the last item’s timestamp + id, so paging is consistent.
Rate limits
Limits are per API key over a rolling 60-second window. The default per-minute budget depends on the owner’s plan:
| Plan | Requests / minute |
|---|---|
| Free / Starter | 60 |
| Pro | 600 |
| Scale | 6,000 |
| White-label | 600 |
Every API-key response carries rate-limit headers:
| Header | Meaning |
|---|---|
X-RateLimit-Limit | Your per-minute limit |
X-RateLimit-Remaining | Requests left in the window |
X-RateLimit-Reset | Unix epoch (seconds) when the window resets |
When you exceed the limit you get 429 with a Retry-After header and:
{ "error": "rate_limited", "limit": 600, "retryAfterSeconds": 12 }Because the limit is keyed to the API key, you can split heavy workloads across multiple keys. Interactive dashboard (cookie) sessions are not rate-limited by this mechanism.
Error model
Errors are JSON with a stable, snake_case error code and an appropriate HTTP status.
| Status | When |
|---|---|
400 | Business validation (e.g. invalid_group_by, unknown_fields) |
401 | Missing/invalid/expired/revoked key |
403 | insufficient_scope — valid key without the needed scope |
404 | not_found — nonexistent or not-owned resource |
422 | Schema validation error (with a details field) |
429 | rate_limited |
5xx | Server error (logged + captured) |
Example:
{ "error": "insufficient_scope", "required": "read:conversions" }Note the distinction: a 400 is a business validation error (your group_by value
isn’t allowed), while a 422 is a schema validation error (a parameter is the wrong
type). Both are safe to surface to your code as “fix the request.”