An application links a candidate to a job. Creating an application can reuse an existing candidate or create one from inline details. All example IDs are fictional; replace them with IDs from your company.
1. Choose the job and candidate
Read List jobs to select a job and List candidates to find an existing candidate. Send exactly one of candidateId or candidate when creating the application.
curl --fail-with-body "https://api.join.com/v3/applications" \
-H "Authorization: Bearer $JOIN_API_TOKEN" \
-H "Join-Version: 2026-11-01" \
-X POST \
-H "Content-Type: application/json" \
--data '{
"jobId": 4321,
"candidateId": 7788,
"externalId": "ats-2026-0001"
}'To supply candidate details instead, use this alternative body:
{
"jobId": 4321,
"candidate": {
"firstName": "Ada",
"lastName": "Lovelace",
"email": "[email protected]",
"countryCode": "DE",
"tags": [
"Engineering"
]
},
"externalId": "ats-2026-0001"
}If the inline email matches an existing candidate, JOIN reuses that profile, applies supplied tags and ignores other inline profile fields. If documents is omitted for an existing candidate, their profile CV and cover letter are carried forward. See Create an application for details and errors, including an application that already exists.
2. Store the returned IDs
Save data.id as the application ID and data.candidate.id as the company candidate ID. New applications start as ACTIVE in the job’s first review stage. Applications in an offer stage also have status ACTIVE.
Your application reference can be changed independently through Update an application’s external reference. Send {"externalId": null} to clear it.
3. Read the job’s stages and move
curl --fail-with-body "https://api.join.com/v3/jobs/4321" \
-H "Authorization: Bearer $JOIN_API_TOKEN" \
-H "Join-Version: 2026-11-01"Choose stageId from data.stages on this response, then move the application:
curl --fail-with-body "https://api.join.com/v3/applications/998877/stage" \
-H "Authorization: Bearer $JOIN_API_TOKEN" \
-H "Join-Version: 2026-11-01" \
-X PUT \
-H "Content-Type: application/json" \
--data '{
"stageId": 502
}'The target stage may schedule automated emails. Moving to HIRED hires the candidate. Moving to the current stage leaves the application unchanged, and a rejected application cannot be moved. See Move an application to a stage.
Manage rejections in JOIN. For timeouts or uncertain outcomes, read the application before retrying a move.