Pagination and rate limits
Cursor pages, the Link header, the change feed, and the rate limits of each API with their RateLimit-* headers.
Cursor pages
Every Organization API list answers { "data": [...], "has_more": true, "next_cursor": "…" }: send ?cursor=<next_cursor> back while has_more is true. The cursor is opaque: don’t build or change it. GET /v1/vault-items (Customer API) answers { "items": [...], "next_cursor": "…", "has_more": true }; /v1/audit-events keeps next_after.
/v1/logs pages newest first and filters by type, from/to, actor, level, status and q; short lists (alerts, access requests, external shares, handovers, weekly reports) also take since, until and q.
The Link header
Through passkey-x.com/api, every list with another page also answers Link: <…&cursor=…>; rel="next", so generic HTTP clients can follow pages without reading the body. offset= paging on the Organization API is deprecated: answers that use it carry Deprecation and Sunset.
| Header | APIs | What it means | Example |
|---|---|---|---|
Link | All (lists) | The next page (rel="next") and the first page (rel="first") as relative URLs, built from next_cursor (or next_after for audit events). rel="deprecation" points at the notice of a deprecated parameter. | Link: </api/org/v1/members?limit=100&cursor=b2Zmc2V0OjEwMA>; rel="next" |
Deprecation | Organization API | RFC 9745: the request used something deprecated, since this date (@unix seconds). Today: offset= paging (use cursor=). | Deprecation: @1792540800 |
Sunset | Organization API | RFC 8594: when the deprecated behaviour stops working. | Sunset: Wed, 30 Jun 2027 23:59:59 GMT |
URL='https://passkey-x.com/api/org/v1/members?limit=200'
while [ -n "$URL" ]; do
curl -s -D headers.txt "$URL" -H "Authorization: Bearer $PASSKEY_X_API_KEY" | jq -c '.data[]'
NEXT=$(grep -i '^link:' headers.txt | sed -n 's/.*<\([^>]*\)>; rel="next".*/\1/p')
URL=${NEXT:+https://passkey-x.com$NEXT}
done// Every page, following next_cursor (or Link rel="next") for you
for await (const event of org.org.auditEvents.iterate({ limit: 500 })) {
console.log(event.sequence, event.action);
}
console.log(org.rateLimit); // { limit, remaining, reset, policy } from the last answerChange feed
GET /v1/sync/changes returns a string cursor and has_more; store the cursor and send it back on the next call to get only what changed.
Rate limits
| API | Limit |
|---|---|
| Customer API | 120 requests per minute per key (or per account for a session) |
| Organization API | 300 requests per minute per key |
| Agent API | One request per second per agent |
On 429, wait Retry-After seconds and back off with jitter. Watch RateLimit-Remaining and slow down before you reach zero; RateLimit-Reset says when the window starts again. A 304 Not Modified still counts.
Rate-limit headers
| Header | APIs | What it means | Example |
|---|---|---|---|
RateLimit-Limit | All | Requests allowed in the current window (IETF draft name). | RateLimit-Limit: 300 |
RateLimit-Remaining | All | Requests left in the current window. | RateLimit-Remaining: 297 |
RateLimit-Reset | All | Seconds until the window resets (on 429: the same as Retry-After). | RateLimit-Reset: 41 |
RateLimit-Policy | All | The limit and its window in seconds: 120;w=60 (Customer), 300;w=60 (Organization), 1;w=1 (Agent). | RateLimit-Policy: 300;w=60 |
X-RateLimit-Limit | Customer, Organization | Older name of RateLimit-Limit, kept for existing clients. | X-RateLimit-Limit: 300 |
X-RateLimit-Remaining | Customer, Organization | Older name of RateLimit-Remaining, kept for existing clients. | X-RateLimit-Remaining: 297 |
Retry-After | All | Seconds to wait: on every 429, and on 502/503 when the service is briefly unavailable. Add jitter. | Retry-After: 60 |
Need help building on Passkey-X?
Questions about the API, a bug or a missing endpoint? Our team replies by email, usually within one business day.