Application form
Mint a candidate-facing application-form link, and read back what a candidate submitted.
Mint-only — this pair never sends anything
The POST below mints and commits a fresh link; it never composes or enqueues a WhatsApp message. Deliver the URL to your candidate yourself.
Mint a candidate-facing application-form link. This call never sends it.
Headers
X-Api-Keyonb_live_<key_id>_<secret>required- Your issued Partner API key — see Authentication.
Request fields
application_form_sectionsstring[]optional- Optional. Which parts of the candidate's application form are shown, as a list of any of: address, eligibility, dbs, referees, cv_upload, documents, date_of_birth, email, declarations. Full name and phone number are always shown. Leave the field out to show every part. An empty list
[]shows only name and phone number;["cv_upload"]asks name, phone number and an optional CV. A part you leave out is not asked. If you leave outdeclarations, the candidate signs nothing and no signed declaration is kept: the compliance pack lists the declarations as not recorded. The consent is recorded in the declarations, so a list that includesdbsordocumentsmust includedeclarationstoo (a 400 otherwise);cv_uploaddoes not need it. A list has at most 18 entries. An unknown value is a 400 naming the allowed values; duplicates are ignored. Sent with the mint, it is stored in the same step as the new link, so the link and the parts it shows can never disagree. Leave the body out and the candidate's current choice is left as it is.
Status codes
2002xx- Minted and committed. A repeat call ROTATES the token — the previous link stops resolving the moment this succeeds.
4014xx- Missing, malformed, unknown, revoked or expired key. Every authentication failure looks the same — see Authentication.
4034xx- The key’s user has the
viewerteam role, or their account could not be read just then (retry) — or the key was created Read only (code: "key_read_only", refused before anything else). Checked before the body or any id — see Authentication.Your team role doesn't allow this. Ask your team's admin or owner.This API key is read-only. Create a full-access key to make changes. 4044xx- Unknown, cross-tenant, or (a candidate id) sandbox-hidden. One outcome, never a 403.
Not found 4094xx- This candidate has opted out — a link would only ever resolve as unavailable.
opted_out 4094xx- This candidate is not currently eligible for a fresh link — not yet consented, mid a data-subject request, taken over by a recruiter, or otherwise suppressed. No token is minted.
no_conversationmirror_not_ownednot_consentednot_collectingreal_seededlive_disabledrecruiter_deletion_scheduledprocessing_pausedbot_paused 4094xx- This candidate has already submitted and their correction window has closed — a new link would be expired on arrival. No token is minted and the candidate is left unchanged.
correction_window_closed 4294xx- Per-key or per-account rate limit exceeded. Retry after the
Retry-Afterheader.Too many requests — please try again shortly. 5005xx- No service client, the ownership read failed, the eligibility check itself could not run, or the token commit failed.
This endpoint sends nothing itself — but it enrols the candidate in the WhatsApp chase for the form
Deliver the returned url yourself — your own SMS, email, or ATS notification; this call never messages the candidate directly. It DOES mark the form outstanding: once the account-level application-form chase is switched on, a candidate who has not opened their link within their chase window will be reminded over WhatsApp, the same as any other outstanding document. A candidate ineligible for a fresh link (opted out, mid a data-subject request, not yet consented, …) is refused before that can happen — see the 409 rows below.
- Before minting, this checks the SAME eligibility a recruiter’s own “Send application form” button checks — consent, conversation flow-state, and suppression (opt-out, data-subject-request pause, account status). A candidate this account has never messaged on WhatsApp has no WhatsApp state to check, so they are checked against durable records instead — opt-out, refused consent, an active recruiter take-over, data-subject requests (an open data request, a completed erasure or an upheld objection blocks the link; a rejected request does not, except a rejected erasure until the person messages or consents again) and account deletion — and a link is minted when none of those applies.
- Each call issues a new link and invalidates any link issued before it — send the newest one.
expiresAtis 14 days out on a first mint, or 48 hours out if this candidate has already submitted once — a re-mint after submission gets the shorter correction window, never a fresh two-week credential for declarations already recorded. Repeated calls after a submission can only SHRINK that window further, never renew or extend it. Once it has closed, the call returns 409correction_window_closedinstead of a link that is already expired.- The request body is optional: only
application_form_sectionsis read (one of: address, eligibility, dbs, referees, cv_upload, documents, date_of_birth, email, declarations). An unknown value is a 400 and nothing is minted.
curl -X POST \ "https://rca-onboardly.com/api/v1/candidates/<candidate id>/application-form" \ -H "X-Api-Key: $ONB_KEY"{ "application_form_sections": [ "cv_upload" ]}{ "url": "https://rca-onboardly.com/apply/9f2c1a4e7b3d8f5a6c2e1b9d4f7a3c8e5b1d9f2c1a4e7b3d8f5a6c2e1b9d4f7a", "expiresAt": "2026-09-28T10:14:02Z"}Read back a candidate’s newest submitted application form.
Headers
X-Api-Keyonb_live_<key_id>_<secret>required- Your issued Partner API key — see Authentication.
Status codes
2002xxapplicationis the newest submission, ornullwhen nothing has been submitted yet — both are a genuine checked answer, never an outage.4014xx- Missing, malformed, unknown, revoked or expired key. Every authentication failure looks the same — see Authentication.
4044xx- Unknown, cross-tenant, or (a candidate id) sandbox-hidden. One outcome, never a 403.
Not found 4294xx- Per-key or per-account rate limit exceeded. Retry after the
Retry-Afterheader.Too many requests — please try again shortly. 5035xx- A read this payload depends on could not be completed. Never a confident
application: null— retry.Some of this candidate’s records could not be read right now. Try again shortly.
- The example is shortened.
personalDetailsandeligibilityare built from the form as it is today: every field the form has, in the form’s order, whether or not this candidate was asked it. The set changes when the form does — keys were added on 29 September 2026 (table below), and a question removed from the form drops out of every response, older submissions included. Do not hard-code the list or its order: read the keys you need bykey, ignore keys you do not know, and never match onlabel, which is display text. valueisnullwhen the candidate was not asked the question: a follow-up whose trigger answer they did not give, a question in a section switched off for their link, or a question added to the form after they submitted. An optional question they were asked and left blank reads""instead. Treat both as no answer. Choice answers carry the option’s code (yes,no,pre_settled_status), not the words the candidate saw. Dates areYYYY-MM-DD.declarationslists every declaration the form asks today, in the form’s own order, then any declaration since removed from the form that this candidate accepted, labelled<title> (retired declaration). Do not hard-code this list either. A current declaration this candidate has no row for readsaccepted: null, acceptedAt: null— an absence, never a refusal the candidate did not make.application_form_sectionsis the list of parts this candidate's form shows: every part unless you chose otherwise on create or mint. A part not in the list was not asked, so its answers arenull. Ifdeclarationsis not in the list the candidate signed nothing, and every entry indeclarationsabove hasaccepted: null.- Referees given on the form are not part of this response.
submitted_ipandsubmitted_user_agentare never returned here. They DO surface elsewhere on this API — inside the compliance-pack audit block returned byGET /candidates/{id}/pack— where they exist for a regulator/DSR audit trail.
Answer keys added on 29 September 2026
| Key | In | Asked when | Value |
|---|---|---|---|
shareCode | eligibility | rightToWorkStatus is settled_status, pre_settled_status, visa_required or other. Optional. | The candidate’s right-to-work share code as they typed it: nine letters or digits, which may be split into threes by a space or hyphen. |
shareCodeExpiry | eligibility | As shareCode. Optional. | YYYY-MM-DD. |
workRestrictions | eligibility | As shareCode. | yes or no — are there limits on the hours or type of work they can do. |
workRestrictionsDetail | eligibility | workRestrictions is yes. | Free text, up to 2,000 characters. |
hasDbsCertificate | eligibility | The link includes the DBS section. | yes or no. |
dbsUpdateService | eligibility | hasDbsCertificate is yes. | yes or no — is the certificate on the DBS Update Service. |
dbsCertificateNumber | eligibility | dbsUpdateService is yes. | The twelve-digit certificate number as they typed it (it may contain single spaces). |
declarationSignatureName | personalDetails | Always, on the declarations step. | The name the candidate typed to sign, up to 100 characters. Its label is Signed by. |
declarationSignatureDate | personalDetails | Always. | YYYY-MM-DD — the UK date the server received the form, whatever the candidate’s device said. Its label is Date signed. |
A recruiter can switch the eligibility section or the DBS section off for a link, and a link whose section list was saved before the DBS section existed does not include it; the questions in a switched-off section read null.
Treat the share code and the DBS certificate number as sensitive
Together with the name and date of birth in this same response, a shareCode can be used to look up the candidate’s right to work on GOV.UK, and a dbsCertificateNumber to check their certificate on the DBS Update Service. Any key that can read this candidate can read them, a viewer’s key included — reads are not role-checked (see Authentication). Keep them out of logs, and store them only where you need them.
curl \ "https://rca-onboardly.com/api/v1/candidates/<candidate id>/application-form" \ -H "X-Api-Key: $ONB_KEY"{ "application": { "submittedAt": "2026-09-29T09:02:14Z", "formVersion": "2026-09-29.3", "personalDetails": [ { "key": "fullName", "label": "Full name", "value": "Marcus Ade" }, { "key": "dateOfBirth", "label": "Date of birth", "value": "1994-03-02" }, { "key": "declarationSignatureName", "label": "Signed by", "value": "Marcus Ade" }, { "key": "declarationSignatureDate", "label": "Date signed", "value": "2026-09-29" } ], "eligibility": [ { "key": "rightToWorkStatus", "label": "UK right-to-work status", "value": "pre_settled_status" }, { "key": "visaType", "label": "Visa type", "value": null }, { "key": "shareCode", "label": "Right to work share code", "value": "W7K 2PX R4M" }, { "key": "workRestrictions", "label": "Are there any limits on the hours or type of work you can do?", "value": "no" }, { "key": "workRestrictionsDetail", "label": "Please tell us what the limits are", "value": null }, { "key": "hasDbsCertificate", "label": "Do you have a DBS certificate?", "value": "yes" }, { "key": "dbsUpdateService", "label": "Is it on the DBS Update Service?", "value": "yes" }, { "key": "dbsCertificateNumber", "label": "DBS certificate number", "value": "001234567890" } ], "declarations": [ { "key": "dbs_ongoing", "label": "Ongoing DBS checks", "accepted": true, "acceptedAt": "2026-09-29T09:02:14Z" } ] }, "application_form_sections": [ "address", "eligibility", "dbs", "referees", "cv_upload", "documents", "date_of_birth", "email", "declarations" ]}POST /api/v1/candidates/{id}/application-form
curl -X POST \ "https://rca-onboardly.com/api/v1/candidates/<candidate id>/application-form" \ -H "X-Api-Key: $ONB_KEY"{ "application_form_sections": [ "cv_upload" ]}{ "url": "https://rca-onboardly.com/apply/9f2c1a4e7b3d8f5a6c2e1b9d4f7a3c8e5b1d9f2c1a4e7b3d8f5a6c2e1b9d4f7a", "expiresAt": "2026-09-28T10:14:02Z"}GET /api/v1/candidates/{id}/application-form
curl \ "https://rca-onboardly.com/api/v1/candidates/<candidate id>/application-form" \ -H "X-Api-Key: $ONB_KEY"{ "application": { "submittedAt": "2026-09-29T09:02:14Z", "formVersion": "2026-09-29.3", "personalDetails": [ { "key": "fullName", "label": "Full name", "value": "Marcus Ade" }, { "key": "dateOfBirth", "label": "Date of birth", "value": "1994-03-02" }, { "key": "declarationSignatureName", "label": "Signed by", "value": "Marcus Ade" }, { "key": "declarationSignatureDate", "label": "Date signed", "value": "2026-09-29" } ], "eligibility": [ { "key": "rightToWorkStatus", "label": "UK right-to-work status", "value": "pre_settled_status" }, { "key": "visaType", "label": "Visa type", "value": null }, { "key": "shareCode", "label": "Right to work share code", "value": "W7K 2PX R4M" }, { "key": "workRestrictions", "label": "Are there any limits on the hours or type of work you can do?", "value": "no" }, { "key": "workRestrictionsDetail", "label": "Please tell us what the limits are", "value": null }, { "key": "hasDbsCertificate", "label": "Do you have a DBS certificate?", "value": "yes" }, { "key": "dbsUpdateService", "label": "Is it on the DBS Update Service?", "value": "yes" }, { "key": "dbsCertificateNumber", "label": "DBS certificate number", "value": "001234567890" } ], "declarations": [ { "key": "dbs_ongoing", "label": "Ongoing DBS checks", "accepted": true, "acceptedAt": "2026-09-29T09:02:14Z" } ] }, "application_form_sections": [ "address", "eligibility", "dbs", "referees", "cv_upload", "documents", "date_of_birth", "email", "declarations" ]}