Skip to main content
Phosra returns lists in two shapes, and which one you get depends on the surface — not on a query flag. Read this once and you will never wonder whether a response has “more”.
Runnable. The shapes below were captured live from https://phosra-api-sandbox-production.up.railway.app on 2026-07-06. The catalog reads (/api/v1/platforms, /api/v1/ratings/systems) need no API key.

The two shapes at a glance

There is no has_more, no total_count, and no "object": "list" wrapper. Product lists are bare arrays; census lists carry next_cursor. Do not code against fields Phosra does not return — detect the last page by the two rules in the table above.

Offset lists (product data plane)

Most product list endpoints return a plain array and accept limit and, where supported, offset. An empty result is [], never null.
curl
Response · 200

Limits and defaults

Each endpoint sets its own default and ceiling. Ask for more than the ceiling and you get the ceiling.

Walk every page

Keep advancing offset by limit until you get back fewer rows than you asked for — that short page is the last one.
Offset lists are newest-first and mutable. New rows land at offset 0, so a row can shift while you page. For an audit-stable walk, filter by a fixed created_at/since window rather than relying on offsets across a long crawl.

Cursor lists (OCSS census rails)

The OCSS census rails return an envelope with the collection plus a next_cursor. The cursor is opaque — treat it as a token, never parse it — and null means you have reached the end. Pass it back verbatim to get the next page.
Response · 200 (advisor audit log)
For the CSM bulk rail the cursor rides the request body (it is part of the signed, convergent payload — the same request set and cursor always return the same records):
Request body
TypeScript
Never construct or mutate a cursor. next_cursor is a server token. Send it back byte-for-byte; do not decode it, add to it, or assume it is a row id — its encoding is not part of the contract and can change.

Choosing a page size

Bigger pages, fewer calls

Each request counts against your rate limit. Pull 100 at a time on offset lists rather than 10 at a time.

Detect the end correctly

Offset lists: a short page ends the walk. Cursor lists: a null next_cursor ends the walk. Never guess with a count you were not given.

Next steps

Limits & quotas

The enforced limit ceilings per endpoint, plus body-size and ID-length caps.

Rate limits

Fewer, larger pages keep you inside your window.

Idempotency

Cursor rails are signed writes — see how replay-safety works.