List candidates
Enumerate a recruiter’s own candidates, keyset-paginated, with status and updated_since filters.
Discover which candidates exist, keyset-paginated, without already holding an id.
Headers
X-Api-Keyonb_live_<key_id>_<secret>required- Your issued Partner API key — see Authentication.
Request fields
limitintegeroptional- 25 if omitted, up to 100. Never clamped — an out-of-range value is a
400, not silently reduced. cursorstringoptional- Opaque. Pass back the previous page’s
next_cursorverbatim; omit for the first page. statusstringoptional- One of
awaiting_consent,consent_denied,in_progress,verified,flagged,revoked— the same stage slug The candidate object’s ownstatusfield uses. Omit for every stage. updated_sincestring (ISO-8601)optional- ISO-8601 timestamp with a timezone (
2026-09-01T00:00:00Z) — anything else is a400. Best-effort — see the note below.
Status codes
2002xx- A page of candidates — may hold fewer than
limitrows, including zero. See the pagination note below. 4004xx- An unrecognised or out-of-range query parameter, or a malformed/tampered
cursor.Invalid query parameter: {param}Invalid or expired cursor 4014xx- Missing, malformed, unknown or revoked key. Every authentication failure looks the same — see Authentication.
4294xx- Per-key or per-account rate limit exceeded. Retry after the
Retry-Afterheader.Too many requests — please try again shortly. 5035xx- A record this page depends on could not be read right now. Never a confident empty page — retry.
Some of this candidate’s records could not be read right now. Try again shortly.
These are query-string parameters, not a request body
This is a GET with no body — every field in the table above is sent on the URL (?limit=25&status=in_progress), not as JSON. The generated curl/Node/Python samples on this page show the bare endpoint with no query string; append the parameters you need yourself, as in the examples below.
GET /api/v1/candidates?limit=50GET /api/v1/candidates?status=verified&limit=25GET /api/v1/candidates?cursor=<next_cursor from the previous page>GET /api/v1/candidates?updated_since=2026-08-20T00:00:00ZIterate until `next_cursor` is `null` — never until `candidates` is empty
next_cursor is derived from the underlying scan alone, independent of ?status. A ?status filter can legitimately return candidates: [] on a page while next_cursor stays non-null — the scan had more rows beyond this page, none of them happened to match. Stopping at an empty candidates array will leave real matches unread.
status is refined in two passes: a database-level filter, then the exact same deriveStage computation The candidate object’s own status field uses, run again after the read with the same inputs — so a status value here and a status value from a direct GET /candidates/{id} call, taken from the same underlying row, always agree.
updated_since is best-effort: stamped by the compliance engine’s own writers, and — as of this release — by PATCH /candidates/{id} and PATCH /candidates/{id}/outreach. An edit made directly from the Onboardly dashboard does not stamp it — do not rely on updated_since alone to catch every change; poll the full roster periodically as a backstop.
cvis the sameV1CandidateCvshape The candidate object’s owncvfield uses:nullwhen no CV is on file or none is currently servable, otherwise an object withfile_name,content_type,size, andcontent_url.- A list row is intentionally thinner than The candidate object: no
documents,references,reference_requirements,compliance_pack, orchase. FetchGET /candidates/{id}for the full record.
curl \ "https://rca-onboardly.com/api/v1/candidates" \ -H "X-Api-Key: $ONB_KEY"{ "candidates": [ { "id": "3f9c1a2e-8b7d-4c1f-9a3e-2d5f8c1b4e70", "external_id": "ats-record-4471", "status": "in_progress", "consent": true, "candidate": { "name": "Jordan Ellis", "mobile_number": "+447700900321", "email": "jordan.ellis@example.com", "job_title": "Support Worker" }, "cv": null, "created_at": "2026-08-20T10:15:00.000Z", "updated_at": "2026-09-01T09:02:11.000Z" } ], "next_cursor": "MjAyNi0wOC0yMFQxMDoxNTowMC4wMDBafDNmOWMxYTJlLThiN2QtNGMxZi05YTNlLTJkNWY4YzFiNGU3MA"}GET /api/v1/candidates
curl \ "https://rca-onboardly.com/api/v1/candidates" \ -H "X-Api-Key: $ONB_KEY"{ "candidates": [ { "id": "3f9c1a2e-8b7d-4c1f-9a3e-2d5f8c1b4e70", "external_id": "ats-record-4471", "status": "in_progress", "consent": true, "candidate": { "name": "Jordan Ellis", "mobile_number": "+447700900321", "email": "jordan.ellis@example.com", "job_title": "Support Worker" }, "cv": null, "created_at": "2026-08-20T10:15:00.000Z", "updated_at": "2026-09-01T09:02:11.000Z" } ], "next_cursor": "MjAyNi0wOC0yMFQxMDoxNTowMC4wMDBafDNmOWMxYTJlLThiN2QtNGMxZi05YTNlLTJkNWY4YzFiNGU3MA"}