Multiple Locations
An applicant often fits more than one of a registry’s locations. CONFIRM models that as one candidate with one application per location. Each application has its own status, and the applicant is screened once for all of them.
This page covers the whole cycle: sending an applicant to several locations, adding or moving a location later, recording your own outcome at one location, and the webhooks you receive along the way.
Send an applicant to several locations
Use location_refs (an array) instead of location_ref on POST /candidates:
The response has one entry per location in applications, in the order you sent them:
Store each application_id against its location. Every webhook about this applicant names the location it is about.
The rules
- Exactly one of
location_reforlocation_refs. Both, or neither, is400 invalid_request. - 1 to 20 locations. A ref repeated in the list is used once.
- All in the same registry. Locations in different registries fail with
400 location_refs_span_organizations, and the error lists each ref with itsorganization_ref. Send one request per registry.organization_ref, if you send it, applies to every ref. - All or nothing on errors. An unknown ref (
404 unknown_location_ref) or a closed location the applicant is not already at (409 location_closed) fails the whole request before anything is created. - Idempotent, per location. Each entry has its own
deduped. The top-leveldedupedistrueonly when every application already existed. The status code is201when at least one application was created,200when none was. - Contact details, consent, address and
webhook_urlapply to every location in the request.
One screening call
The applicant gets one heads-up SMS and one AI screening call covering every location in the request. They are not called once per location.
- Each location is scored on its own. After the call, each location gets its own
screening.completedwebhook, with its ownresultandtier. Knockout questions count per location: failing one location’s knockout question does not fail the others. - Distance is checked per location. If you send the applicant’s
address, CONFIRM measures their commute to each location at intake. A location they live too far from is ruled out straight away: its entry reportsscreening: "skipped_ruled_out", its status becomesrejected(with acandidate.status_changedwebhook), and it is left out of the call. The other locations go ahead. - Set each location’s pay. A location without a pay rate (
payonPOST /locations) skips the pay question on screening calls.
If you send the same applicant again later with another location, and the screening call has not been placed yet, the new location joins that call. Once the call has happened, the new location gets a short follow-up call instead of a second full screening. See follow-up calls.
screening_hold on each entry is "calendar_not_connected" when that location’s call is queued but the workspace has no connected calendar yet, and null otherwise. See the calendar guide.
Add a location later
To put an applicant you already sent at another location, use POST /candidates/{external_ref}/locations:
It reuses the screening the applicant already has, and screening tells you how:
screening describes the application when it was created. It does not change when a follow-up call runs; the result reaches you as webhooks.
The new application keeps the applicant’s webhook_url. You receive candidate.location_added. It returns 201 when it creates an application and 200 (created: false) when the applicant was already at that location, so it is safe to replay.
Follow-up calls for locations added later
A location added after the applicant’s screening call does not get a second full screening. It is handled the same way whether you add it (or move the applicant to it) with POST /candidates/{external_ref}/locations (screening of pending or none), send it with POST /candidates after the call happened, or the registry office adds it in CONFIRM:
- The call hasn’t been placed yet: the new location joins it, and that one call covers it too.
- The first call is still in progress: the new location waits for it to finish, then carries on as below.
- Questions left to ask: a short follow-up call asks only the questions the applicant has not already answered.
- Nothing left to ask: no call is placed. The outcome at the new location is decided from the earlier answers.
Earlier answers carry over only when the question is asked exactly the same way. Each location has its own questions. A question that names a different address (“…at the Clearwater office?” versus “…at the Largo office?”) is a different question and is asked again. A knockout question carries over only when the new location applies the same knockout rule to it, so a failed answer elsewhere counts here only for an identical question. Answers more than 180 days old are asked again.
What the applicant gets. No second heads-up SMS: the follow-up call is not a new application. The usual requirements still apply: the applicant needs contact consent and a valid phone, and the call is held while the workspace has no connected calendar.
What you get. The new location gets its own screening.completed and candidate.status_changed, like any screened location. When the outcome was decided from earlier answers with no call, screening.completed still fires for the new location, and its completed_at is the time of the call the answers came from.
Move an applicant
Add move_from_location_ref to move instead of add:
The applicant gets an application at the new location, and the one at the old location is closed. A move is not a rejection: the applicant gets no message about it, and you receive one candidate.location_changed, with no candidate.status_changed → rejected for the location they left.
Both locations must be in the same registry, and the applicant must have an application at move_from_location_ref (404 no_application_at_location otherwise).
Take an applicant off one location
There is no DELETE. To record that an applicant is no longer going ahead at one location, set your outcome there with PATCH /candidates/{external_ref}:
- Only that location changes. The applicant’s other locations carry on as before.
- CONFIRM sends the applicant nothing about an outcome you set.
- You get the status change back. It fires
candidate.status_changed(rejectedorhired) for that location, like any other status change. Deduplicate it against the change you just made. - Idempotent. Sending the outcome the application already has returns
changed: falseand fires nothing. - Do-not-contact is final. An applicant CONFIRM has marked do-not-contact returns
409 outcome_conflict.
Pass organization_ref as a second query parameter if the same location ref exists in more than one of your registries.
Placement
When the registry office decides where the applicant goes, they place them at a location in CONFIRM. You receive candidate.placed for that location, with placed_at and placed_via. Placing does not change the applicant’s status and does not close their other locations: another location can still hire the same person later. When the applicant is actually hired, record it with outcome: "hired" (or the registry does it in CONFIRM), and the hired status arrives as candidate.status_changed.
Webhooks at a glance
Every event is about one location and carries its location_ref and application_id. See the webhooks guide for full payloads.

