Ingest an applicant
Ingests an applicant from your platform and starts screening. The
applicant’s registry is resolved from location_ref, so you do not pass
an organization — one call, one applicant, wherever they applied.
Several locations at once. Send location_refs (an array of 1–20
location refs) instead of location_ref to put one applicant at
several locations in one call. Send exactly one of the two. You get
one candidate with one application per location, and the response
lists them in applications[]. The applicant is screened once: one
heads-up SMS and one screening call cover every location named in the
request. All the locations must be in the same registry, or the
request fails with 400 location_refs_span_organizations and nothing
is created. See the
multiple locations guide.
What happens next. The applicant receives a heads-up SMS
immediately and an AI screening call a few minutes later. Results land
in the registry’s CONFIRM portal, at the portal_url in the response.
Store two things: candidate_id and portal_url. The first is the
durable correlation key; the second is your “View Full Details” link.
Idempotency. Re-submitting the same applicant returns the existing
IDs with deduped: true and a 200. A duplicate never conflicts and
never creates a second application on the same location. Matching is by your
external_ref first, then by phone number, then by email — so an
applicant who reaches a registry through both your intake form and a job
board resolves to one person, not two.
Shared phones and emails stay separate people. A phone or email match
only links to a candidate you have not already sent under a different
external_ref (in practice, someone who applied through a job board).
Two applicants you send with different refs are always two candidates,
even when they share a household phone or email, and neither one’s
details are changed by the other.
Consent governs contact. consent.contact must be true for
CONFIRM to text or call. Send false (or omit it) and the applicant is
still created and visible in the portal, but no outreach happens and the
response returns screening: "skipped_no_consent". This is the TCPA
boundary: we contact within minutes of ingest, so consent is not
something to assume.
Consent (or a phone) sent later starts screening. If you first send
an applicant without consent, or without a usable phone, and later
re-send them with it, that re-send starts screening: 200,
deduped: true, screening: "enqueued". This happens once, and only
while the applicant is still new: if a recruiter has already moved them
on in CONFIRM, the re-send changes nothing about their screening.
Unknown locations fail loudly. A location_ref we don’t recognise
returns 404 unknown_location_ref rather than dropping the applicant.
The same request succeeds on retry once the location exists.
Closed locations take no new applicants. A location closed with
PATCH /locations/{ref} returns 409 location_closed for someone new.
An applicant you sent before it closed still returns 200 with
deduped: true. With location_refs, one closed location the
applicant is not already at fails the whole request with
409 location_closed before anything is created; reopen it or leave
it out, then retry.
Distance at intake. Send the applicant’s address and CONFIRM
measures their commute to each location. A location they live too far
from (beyond its maximum commute distance) is ruled out straight away: that
application gets screening: "skipped_ruled_out", its status becomes
rejected, and it is left out of the screening call. Other locations
are unaffected.
A location sent after the call. If the applicant’s screening call
has not been placed yet, a new location joins it. If the call has
already happened, the new location gets a short follow-up call that
asks only the questions the applicant has not already answered, with
no second heads-up SMS. If nothing is left to ask, no call is placed
and the outcome at the new location is decided from the earlier
answers. If the first call is still in progress, the new location
waits for it. In each case the response reports screening: "enqueued",
and the result arrives as screening.completed and
candidate.status_changed for that location. See
follow-up calls.
Held for a calendar. Screening calls are held while the registry’s
workspace has no connected calendar. When screening is enqueued and
the workspace has none, screening_hold is "calendar_not_connected";
the call goes out once a calendar is connected. See the
calendar guide.
Same location ref in several registries. If you use one location ref
in more than one registry, pass organization_ref to say which;
without it the request returns 409 ambiguous_location_ref.
Authentication
Partner API key sent as Authorization: Bearer cfk_.... Keys are partner-level — one key reaches every registry linked to your partner account and nothing else. CONFIRM issues and revokes them; a key is shown exactly once at creation because only its hash is stored, and revocation takes effect on the next request. Develop against the sandbox base URL with a sandbox key, where telephony is restricted to an allowlist you provide.
Request
Send exactly one of location_ref and location_refs. Both, or neither, is a 400 invalid_request.
Your identifier for this applicant. Stored on the candidate and echoed on every response and webhook, and the primary key for idempotent re-submission.
The location the applicant applied to (the external_ref you created it with). Resolves both the registry and the role. Send this or location_refs, not both.
Several locations for the same applicant, in place of location_ref. 1–20 non-blank refs; a ref repeated in the list is used once, in the order first given. Every ref must be in the same registry, else 400 location_refs_span_organizations. The response then has applications[] with one entry per location instead of a single application_id.
The registry the location belongs to. Only required when the same location ref exists in more than one of your registries. With location_refs, it applies to every ref in the list.
The applicant’s home address, used to measure their commute to each location at intake. Optional.
It is stored only when it pins down a real place: it needs a
postal_code, or a city with its state, and it must match a real
location. Otherwise nothing is stored, distance screening stays off for
this applicant, and the response says why in warnings:
- “address was not stored: it needs a postal_code, or a city with its state, to measure commute distance. Distance screening is inactive for this applicant.”
- “address could not be matched to a real location and was not stored. Distance screening is inactive for this applicant.”
- When it only partly matched, the address is stored and the warning names the place distances are measured from.
For an applicant CONFIRM already has an address for, the stored address is kept and the one you send is ignored.
Required unless phone is supplied. Both is ideal.
Required unless email is supplied. E.164 preferred; other common formats are normalised. Screening calls need a phone — without one the response returns screening: "skipped_no_phone". A phone that isn’t a valid number is a 400 when there is no email. With a valid email the applicant is still accepted: the phone is dropped, the response carries a warnings entry saying so, and screening is skipped_no_phone.
Where to POST this applicant’s lifecycle events. Append your own tracking identifier to it and every delivery arrives already correlated to your record — you never need a CONFIRM ID to match an event. Must be HTTPS, on a public host that exists in DNS, with no credentials in the URL, and at most 2048 characters. A URL that breaks a rule is rejected with 400 and one of the codes in the webhooks guide, before the applicant is created. Omit it and this applicant emits no webhooks at all. Re-sending the applicant with a different webhook_url re-points them; omitting the field, or sending null, on a re-send leaves the stored URL unchanged.
Response headers
The ID of this request. On an error it equals request_id in the body. If you sent an X-Request-Id, it is your value, returned unchanged. Log it, and quote it when contacting CONFIRM support.
Response
Applicant created. If the person already exists (matched on your external_ref, then on phone or email — but only against a candidate not already sent under a different ref), you get 200 with the original IDs and deduped: true. No second application is created, and screening reports the existing application’s state rather than a new call. With location_refs the body is a multi-location result: 201 when at least one application was created, 200 when every one already existed.
The result of ingesting an applicant with location_refs: one candidate, and one entry in applications per location, in the order you sent them.

