Create a candidate

Create a candidate from your ATS record, optionally sending the WhatsApp opener.

POST/api/v1/candidates#

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? }[]optional
startDate/endDate are 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 missing organisation or role is 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 default
application_form, recruiter_attested, or ats_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 null for the account default.
reference_chase_attemptsinteger or nulloptional
0–10 (0 disables referee chasing for this candidate). Omit or send null for the account default.
startbooleanoptional
Must be the literal true to send the WhatsApp opener. Defaults to false — 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. meta carries 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-After header.
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
5035xx
start: true was 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_attempts maps to the same per-candidate cap the dashboard’s outreach panel calls chase_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, and opt_in_source accepting application_form / recruiter_attested / ats_import.
cURL
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
}'
Request body
{
"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
}
201 · Created, no send (start: false)
{
"id": "3f9c1a2e-8b7d-4c1f-9a3e-2d5f8c1b4e70",
"checklistSeeded": true,
"documentsSeeded": 2,
"referencesSeeded": 1,
"openerMirrored": false,
"cvStored": false
}
200 · Replay of an already-used Idempotency-Key
{
"id": "3f9c1a2e-8b7d-4c1f-9a3e-2d5f8c1b4e70",
"replayed": true
}