- Send Candidates API workflow
- Send Candidates API references
- Send Candidates API overview
- Authenticate
- Register employer
- Request – Register employer
- Response – Register employer
- Initialize application and upload attachments
- Request – Initialize application
- Response – Initialize application
- Submit application
- Request – Submit application
- Response – Submit application
- Track application status
- Request – Find application status
- Delete application
- Request – Delete application
- Response – Delete application
Send Candidates API guide
Sync candidate applications with Indeed.
By using this API and its documentation and building an integration, you agree to the Additional API Terms and Guidelines.
Send Candidates API workflow
- 1.Send Candidates API overview: Learn how the Send Candidates API syncs candidate applications with Indeed.
- 2.Authenticate.
- 3.Register employer: Register an employer, and return information about the registration.
- 4.Initialize application and upload attachments: Stage an application version with Indeed, generate attachment upload URLs, and upload files to those URLs.
- 5.Submit application: Submit an application version to Indeed. Versions are published asynchronously in submission order.
- 6.Track application status: Track application status and processing errors.
- 7.Delete application: Permanently remove an application and all its versions from Indeed.
- 8.Troubleshoot GraphQL errors: Resolve GraphQL errors.
Send Candidates API references
registerEmployer: Register an employer, and return information about the registration.application.initialize: Stage an application version with Indeed and generate URLs to upload attachments.application.submit: Submit an application.findStatuses: Track application status and processing errors.application.delete: Delete an application.
Send Candidates API overview
The Send Candidates API provides a complete workflow for submitting and tracking candidate applications. Submitting an application requires three steps: initialize, upload attachments, and submit.
Initializing stages an application version with Indeed and generates URLs to upload attachments. Each initialization creates a version with a unique applicationVersionId. After initialization, you have five minutes to upload attachments and submit.
The API organizes data in a hierarchy. The applicationIdentifier object contains these fields, which uniquely identify an application:
| Field | Required | Description |
|---|---|---|
indeedRegistrationId | ✅ | Unique ID linking an Indeed employer to a partner employer. Provided during registration. |
atsCandidateId | ⬜ | ID for a candidate profile associated with one or more ATS applications. |
atsApplicationId | ✅ | Unique ID for the application in the ATS. |
job.sourcedPostingId | ✅ | Job posting ID that createSourcedJobPostings returns. |
This combination defines a single logical application. Each time you call initialize with the same applicationIdentifier, you create a new version of that application.
All fields contribute to this uniqueness, including those that are optional. This means that, for example, an application that includes an atsCandidateId is different from one that does not include this field, even if the other fields are all identical.
When you upload attachments:
- All attachments are scanned for viruses and harmful content. Unsafe files are removed.
- Total size of all attachments must not exceed 15 MB (15,728,640 bytes).
- Individual file size must not exceed 6 MB (6,291,456 bytes).
- Duplicate attachments are not allowed, based on MD5 hash.
- Include at most one RESUME and one COVER_LETTER attachment. Use OTHER_RESUME or OTHER_COVER_LETTER for additional files.
- All attachments must have a valid Base64-encoded MD5 checksum.
Answers to questions about protected demographic information (such as race, gender, age, or disability status) are not published to Indeed.
Deleting an application permanently removes it and all its versions from Indeed. You cannot reinitialize deleted applications.
Avoid concurrent mutations (initialize, submit, delete) on the same application. Multiple operations in quick succession can cause race conditions, unexpected data states, and difficulty confirming which version is published.
Authenticate
When you become an Indeed partner, Indeed sets up an app for your integration. Log in to Partner Console to view your app and OAuth credentials (client ID, secret, and authorization code for 3-legged OAuth). Exchange credentials for an access token to authenticate API calls.
Each Candidate Sync API operation requires an OAuth token:
| API / operations | OAuth token type |
|---|---|
| Authentication Authenticate with a 3-legged OAuth token that represents an employer with the If |
| Authentication Authenticate with a 2‑legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction. See 2‑legged OAuth token. |
Securely store access tokens in your ATS, and don't share them between users. Indeed trusts that your system is the source of truth for a job. If you use a user's access token for a job that another user posted, Indeed might grant that user access to the other user's job on Indeed.
After you get an access token, include this token in the query or mutation. Indeed recommends that you refresh your access tokens before they expire to avoid asking users to log in every time they need to view updated job statuses.
See Integrate with Indeed and call APIs and Scopes.
Register employer
The Employer Registration API enables you to register an employer.
Request – Register employer
To register an employer and return registration information, call registerEmployer.
Authenticate with a 3-legged OAuth token that represents an employer with the employer.ats_candidate.sync scope. This token links the employer's Indeed account to their ATS account. An Indeed administrator or owner must create it.
If registerEmployer returns a missing scope error, the token might not be associated with an employer.
See 3-legged OAuth token that represents an employer.
Provide these input fields:
| Field | Required | Description |
|---|---|---|
Type: | ✅ | Partner-provided ID that uniquely identifies the employer. You can register one |
Type: | ✅ | Partner-provided name the employer uses. Employers on Indeed see this name. |
Response – Register employer
The response returns EmployerRegistration. Save the registration id for subsequent Candidate Sync API calls, or look it up later with findRegisteredEmployers by partnerEmployerId.
Initialize application and upload attachments
Stage an application version with Indeed, generate attachment upload URLs, and upload files to those URLs.
Request – Initialize application
To initialize an application, call initialize. This operation stages an application version with Indeed and generates URLs to upload attachments.
Authenticate with a 2‑legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction.
See 2‑legged OAuth token.
To identify the employer on Indeed, set indeedRegistrationId to the id that registerEmployer returns in EmployerRegistration.
The employer must have the sendApplications feature enabled.
Provide these input fields:
| Field | Required | Description |
|---|---|---|
| ✅ | Unique ID for the application on Indeed. | |
| ✅ | Complete applicant details. | |
Type: [AtsSyncCandidateSyncApplicationQuestionAndAnswerInput!]! | ⬜ | Screener questions and applicant answers, each as a plain text string. |
| ✅ | Current application disposition status. See Indeed Standard Disposition Statuses for status mapping examples. | |
|
Type: | ✅ | Direct link to the application in your system. |
|
Type: | ⬜ | Direct link to the candidate profile in your system. |
mutation InitializeApplication($input: InitializeAtsSyncCandidateSyncApplicationInput!) { atsSyncCandidateSync { application { initialize(input: $input) { applicationVersionId attachments { fileType fileName contentType contentLength fileChecksum { checksum } url } } } }}Response – Initialize application
| Field | Description |
|---|---|
|
Type: | New application version, used when submitting. |
| Uploads file data for each attached file. |
For each attachment returned in the initialize response, upload the file data with a PUT request to url. Include these headers matching the applicant.attachments values from the initialize mutation:
| Header | Value source | Description |
|---|---|---|
Content-Type | contentType | Original media type of the file attachment. |
Content-Length | contentLength | File size in bytes. |
Content-MD5 | fileChecksum.checksum | MD5 hash. Important Base64-encode the |
Submit application
Authenticate with a 2‑legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction.
See 2‑legged OAuth token.
Submit an application version to Indeed. Versions are published asynchronously in submission order.
Provide an indeedRegistrationId to identify the employer on Indeed. The employer must have the sendApplications feature enabled.
For information about managing these IDs, see Employer Registration API.
Request – Submit application
To submit an application, call the application.submit mutation.
Provide these input fields:
| Field | Required | Description |
|---|---|---|
|
Type: | ✅ | Links to the Indeed employer account. |
|
Type: | ✅ | Version ID that application.initialize returns. |
mutation SubmitApplication($input: SubmitAtsSyncCandidateSyncApplicationInput!) { atsSyncCandidateSync { application { submit(input: $input) { applicationVersionId } } }}Response – Submit application
| Field | Description |
|---|---|
|
Type: | Same as the input value. Log for audit purposes if needed. |
Call within five minutes of initialization. Upload all file attachments before submission. Applications with missing attachments are still processed, but findStatuses returns a FILE_NOT_UPLOADED error. Applications can be submitted even if a file attachment failed to process. Processing is asynchronous but maintains submission order.
Track application status
Authenticate with a 2‑legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction.
See 2‑legged OAuth token.
After submission, query application version status to check processing and identify errors.
Request – Find application status
To query application version status with pagination, call findStatuses.
Use this query to track publishing progress after submission and check bulk status with version history.
| Field | Filters by |
|---|---|
|
Type: | Employers. |
| Application IDs. | |
|
Type: | Application versions. |
|
Type: | Statuses. |
query FindApplicationStatuses($input: AtsSyncCandidateSyncApplicationFindStatusesInput!$first: Int $after: String $last: Int $before: String) { atsSyncCandidateSync { application { findStatuses(input: $input first: $first after: $after last: $last before: $before) { applicationVersionStatuses { applicationVersionId applicationIdentifier { indeedRegistrationId atsCandidateId atsApplicationId job { sourcedPostingId } } status processingStatus errors } pageInfo { hasNextPage hasPreviousPage startCursor endCursor } } } }}Delete application
Authenticate with a 2‑legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction.
See 2‑legged OAuth token.
Permanently remove an application and all its versions from Indeed.
Provide an indeedRegistrationId to identify the employer on Indeed. The employer must have the sendApplications feature enabled.
For information about managing these IDs, see Employer Registration API.
Request – Delete application
To delete an application, call the application.delete mutation.
This operation is permanent. All application versions are removed from Indeed and cannot be recreated. New versions cannot be created after deletion.
| Field | Required | Description |
|---|---|---|
| ✅ | Unique ID for the application. | |
|
Type: | ✅ | Timestamp when the application was deleted. |
mutation DeleteApplication($input: DeleteAtsSyncCandidateSyncApplicationInput!) { atsSyncCandidateSync { application { delete(input: $input) { applicationVersionId } } }}Response – Delete application
| Field | Description |
|---|---|
|
Type: | Unique ID for this deletion. References the final version of the deleted application. |