Create a candidate
Create a candidate from your ATS record, optionally sending the WhatsApp opener.
Headers
X-Api-Keyonb_live_<key_id>_<secret>required- Your issued Partner API key — see Authentication.
Idempotency-Key<your own record id>required- Matches on the key alone, per account. 1–255 characters.
Request fields
first_namestringrequired- Up to 200 characters.
last_namestringrequired- Up to 200 characters.
emailstringrequired- A syntactically valid address.
mobile_numberstringrequired- Include a country code (
+447700900321) where possible — a bare national number is accepted but assumes GB. role_typestring or nulloptional- Up to 200 characters.
documentsstring[]optional- Any name is accepted — there is no fixed catalogue (see Document names). Up to 50 entries, each up to 200 characters. Omit to seed the default five-document checklist.
references{ organisation, role, startDate?, endDate? }[]optionalstartDate/endDateare camelCase — the one exception to this endpoint's otherwise snake_case body. Up to 20 entries; only the first 5 are seeded and asked for. An entry missingorganisationorroleis silently dropped, not rejected.opt_inbooleanunless your account has a configured default opt-in source- Must be
true.false(or omitted with no account default) is a 400. opt_in_sourcestringunless your account has a configured defaultapplication_form,recruiter_attested, orats_import.opt_in_atstring (ISO-8601)unless your account has a configured default- When consent was captured.
opt_in_evidence_refstringoptional- Up to 500 characters — a pointer to your own consent record.
docs_chase_attemptsinteger or nulloptional- 1–10. Omit or send
nullfor the account default. reference_chase_attemptsinteger or nulloptional- 0–10 (
0disables referee chasing for this candidate). Omit or sendnullfor the account default. startbooleanoptional- Must be the literal
trueto send the WhatsApp opener. Defaults tofalse— every other truthy value still means "do not send".
Status codes
2012xx- Candidate created.
2002xx- This Idempotency-Key already created a candidate — the original result is returned, nothing new is written.
4004xx- Malformed body, a field failed its own validation, or the Idempotency-Key header was missing/too long.
An Idempotency-Key header is required (max 255 characters).Invalid mobile numbermobile_number must include a country code (e.g. +447700900123)mobile_number is not a valid number for its country codeConfirm the candidate opted in first 4014xx- Missing, malformed, unknown or revoked key. Every authentication failure looks the same — see Authentication.
4024xx- Reserved for plan limits — over your account’s seat or message quota.
metacarries the figures. 4094xx- A duplicate phone or email already in your roster, a mobile number this API cannot create a candidate for right now, or another request with this Idempotency-Key still in flight. Nothing was created; fix the input or wait for the in-flight request.
A candidate with this mobile number already existsA candidate with this email already exists 4294xx- Per-key or per-account rate limit exceeded. Retry after the
Retry-Afterheader.Too many requests — please try again shortly. 5005xx- Creation failed and was not retried automatically. Retry with the SAME Idempotency-Key.
Failed to create candidate 5035xxstart: truewas sent but WhatsApp sending is not available on the account right now. The candidate may still have been created — read it back before retrying, and contact support if it persists.
`start` must be the literal `true`
Any other value — "yes", 1, omitted — sends nothing. This is deliberate: an ATS sync that silently messaged every imported record would be an expensive surprise.
Attaching a CV needs a multipart body, not the JSON shape above
Send multipart/form-data instead, with every field above as a plain-string form field (documents/references as their JSON-encoded strings) plus a cv_file file field — accepted types: application/pdf, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, up to 10 MB. Idempotency-Key is still required. start is silently ignored on a multipart body — this route only reads it from a JSON-parsed clone of the request; call Start a candidate afterwards.
- A body that is not valid JSON may be answered with a 500 rather than a 400. Fix the body and retry with the same Idempotency-Key — the claim is released on failure.
- Documents accept any name — there is no fixed catalogue to validate against.
- References beyond the first 5 are collected in your ATS but neither seeded nor asked for.
docs_chase_attemptsmaps to the same per-candidate cap the dashboard’s outreach panel callschase_attempts_override; the wire name differs by endpoint (see Update outreach settings).- Undocumented in the design outline but present on the wire:
opt_in_at,opt_in_evidence_ref, andopt_in_sourceacceptingapplication_form/recruiter_attested/ats_import.
curl -X POST \ "https://rca-onboardly.com/api/v1/candidates" \ -H "X-Api-Key: $ONB_KEY" \ -H "Idempotency-Key: <your own record id>" \ -H "Content-Type: application/json" \ -d '{ "first_name": "Jordan", "last_name": "Ellis", "email": "jordan.ellis@example.com", "mobile_number": "+447700900321", "role_type": "Support Worker", "documents": [ "DBS", "Right to Work" ], "references": [ { "organisation": "Acme Ltd", "role": "Support Worker", "startDate": "2022-01", "endDate": "2023-06" } ], "opt_in": true, "opt_in_source": "ats_import", "opt_in_at": "2026-09-01T09:00:00Z", "start": false}'{ "first_name": "Jordan", "last_name": "Ellis", "email": "jordan.ellis@example.com", "mobile_number": "+447700900321", "role_type": "Support Worker", "documents": [ "DBS", "Right to Work" ], "references": [ { "organisation": "Acme Ltd", "role": "Support Worker", "startDate": "2022-01", "endDate": "2023-06" } ], "opt_in": true, "opt_in_source": "ats_import", "opt_in_at": "2026-09-01T09:00:00Z", "start": false}{ "id": "3f9c1a2e-8b7d-4c1f-9a3e-2d5f8c1b4e70", "checklistSeeded": true, "documentsSeeded": 2, "referencesSeeded": 1, "openerMirrored": false, "cvStored": false}{ "id": "3f9c1a2e-8b7d-4c1f-9a3e-2d5f8c1b4e70", "replayed": true}POST /api/v1/candidates
curl -X POST \ "https://rca-onboardly.com/api/v1/candidates" \ -H "X-Api-Key: $ONB_KEY" \ -H "Idempotency-Key: <your own record id>" \ -H "Content-Type: application/json" \ -d '{ "first_name": "Jordan", "last_name": "Ellis", "email": "jordan.ellis@example.com", "mobile_number": "+447700900321", "role_type": "Support Worker", "documents": [ "DBS", "Right to Work" ], "references": [ { "organisation": "Acme Ltd", "role": "Support Worker", "startDate": "2022-01", "endDate": "2023-06" } ], "opt_in": true, "opt_in_source": "ats_import", "opt_in_at": "2026-09-01T09:00:00Z", "start": false}'{ "first_name": "Jordan", "last_name": "Ellis", "email": "jordan.ellis@example.com", "mobile_number": "+447700900321", "role_type": "Support Worker", "documents": [ "DBS", "Right to Work" ], "references": [ { "organisation": "Acme Ltd", "role": "Support Worker", "startDate": "2022-01", "endDate": "2023-06" } ], "opt_in": true, "opt_in_source": "ats_import", "opt_in_at": "2026-09-01T09:00:00Z", "start": false}{ "id": "3f9c1a2e-8b7d-4c1f-9a3e-2d5f8c1b4e70", "checklistSeeded": true, "documentsSeeded": 2, "referencesSeeded": 1, "openerMirrored": false, "cvStored": false}{ "id": "3f9c1a2e-8b7d-4c1f-9a3e-2d5f8c1b4e70", "replayed": true}