- Retrieve Candidates API workflow
- Retrieve Candidates API reference
- Authenticate
- Asset types
- Best practices
- Register employer
- Request – Register employer
- Response – Register employer
- Get unacknowledged assets
- Request – Get unacknowledged assets
- Response – Get unacknowledged assets
- Get assets by time range
- Request – Get assets by time range
- Response – Get assets by time range
- Create test assets
- Requirements
- Request – Create test assets
- Troubleshoot errors
Retrieve Candidates API guide
Get candidate information from Indeed for employers.
By using this API and its documentation and building an integration, you agree to the Additional API Terms and Guidelines.
Call the Retrieve Candidates API to get candidate information from Indeed for employers.
Retrieve Candidates API workflow
After you integrate with the Retrieve Candidates API, review the:
- Asset types that the Retrieve Candidates API returns.
- Best practices.
Then you can call these operations:
- 1.Authenticate.
- 2.Register employer: Register an employer and return the registration details.
- 3.Get unacknowledged assets: Get unacknowledged assets from oldest to newest, in the order you staged them.
- 4.Get assets by time range: Get acknowledged assets for a time range.
- 5.Create test assets: Create test candidate assets in sandbox mode for integration testing.
- 6.Troubleshoot GraphQL errors: Fix GraphQL errors.
Retrieve Candidates API reference
registerEmployer: Registers an employer and returns information about the registration.fetchAssets: Returns unacknowledged assets in the order you staged them, from oldest to newest.assetsByTimeRange: Returns acknowledged assets in a time range.stageAssets: Creates test assets for integration testing.
Authenticate
When you become an Indeed partner, Indeed sets up an app for your integration. Sign 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 and operations | OAuth token type |
|---|---|
| Authenticate with a 3-legged OAuth token that represents an employer and has the |
| Authenticate with a 2-legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction. |
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 sign in every time they need to view updated job statuses.
See Integrate with Indeed and call APIs and Scopes.
Asset types
The Retrieve Candidates API returns these candidate asset types, which implement the AtsSyncCandidateSyncAsset interface:
-
AtsSyncCandidateSyncInterestedCandidateAssetfrom Smart Sourcing.Includes this candidate information (
AtsSyncCandidateSyncInterestedCandidate):AtsSyncCandidateSyncInterestedCandidate fields Field Description Type:
String!The candidate's full name. Type:
EmailAddress!The candidate's email address.
Type:
StringThe candidate's location, if provided.
A presigned S3 URL to download the candidate's resume. See Download and upload objects with presigned URLs.
-
AtsSyncCandidateSyncSmartScreeningUpdateAssetfrom Smart Screening updates.Smart Screening updates apply to the partner, not one employer registration. Any Smart Screening job can produce application updates. Fetch results omit
employerIdentifier. Staging input omitsmetadata.employerIdentifier.Use the Indeed Apply ID to identify the application.
Smart Sourcing requires
employerIdentifierbecause it targets one employer registration.AtsSyncCandidateSyncSmartScreeningUpdateAssetincludes this candidate information (AtsSyncCandidateSyncSmartScreeningUpdate):AtsSyncCandidateSyncSmartScreeningUpdate fields Field Description Application ID for the screening update. This field is a union. Set indeedApply.indeedApplyId.Type:
FloatThe candidate's smart fit score, if available. Returns
nullif no score was staged.The candidate's resume file. Use:
resume {url,name,contentType}The download URL is a short-lived presigned URL. See Download and upload objects with presigned URLs
Type:
DateTime!When the screening update was created. Order updates by this timestamp.
These fetch operations can return both types:
Create test assets (stageAssets) accepts either asset type as input when creating test assets.
Best practices
| Best practice | Description |
|---|---|
| Handle interfaces and unions defensively | For the For the |
| Apply updates in order | Order Smart Screening updates by Do not order Smart Screening updates by If you apply updates out of order, older data can overwrite newer data. |
Register employer
Use the Employer Registration API 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 and has 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.
Provide these input fields in RegisterEmployerInput:
| Field | Required | Description |
|---|---|---|
Type: | ✅ | An ID you provide to uniquely identify the employer. You can register one |
Type: | ✅ | The name you provide for the employer. Employers see this name on Indeed. |
Response – Register employer
The API returns an EmployerRegistration. Store its id for later Candidate Sync API calls, or query findRegisteredEmployers with the partnerEmployerId to get it again.
Get unacknowledged assets
Call fetchAssets to get unacknowledged assets in the order you staged them, from oldest to newest.
fetchAssets supports interested candidates from:
- Smart Sourcing outreach (
AtsSyncCandidateSyncInterestedCandidateAsset) - Smart Screening updates (
AtsSyncCandidateSyncSmartScreeningUpdateAsset)
Partners might receive a mix of both asset types in a single request.
Indeed might add asset types, so handle unexpected asset types in the response. Not every asset is an AtsSyncCandidateSyncInterestedCandidateAsset or AtsSyncCandidateSyncSmartScreeningUpdateAsset.
Authenticate with a 2-legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction.
The employerIdentifier in the response matches the ID that you sent to Indeed when you created the registration. Use it to identify which employer receives the candidate.
Request – Get unacknowledged assets
This mutation gets unacknowledged assets.
This query gets unacknowledged candidate sync assets and returns a token, asset metadata, candidate details for interested candidates, and screening update details for Smart Screening assets:
mutation FetchAssets($input: FetchAssetsAtsSyncCandidateSyncInput) { atsSyncCandidateSync { fetchAssets(input: $input) { token assets { id metadata { stagedAt stagedTest employerIdentifier completeSourceAttribution { enumKey name } } ... on AtsSyncCandidateSyncInterestedCandidateAsset { contact { candidate { email location name phone resume { files { url name contentType } } } job { sourcedPostingId } tracking { recruiterEmail } } } ... on AtsSyncCandidateSyncSmartScreeningUpdateAsset { smartScreeningUpdate { smartFitScore createdAt applicationIdentifier { __typename ... on AtsSyncCandidateSyncIndeedApplyApplicationIdentifier { indeedApplyId } } resume { url name contentType } } } } } }}Provide these input fields:
Response – Get unacknowledged assets
The API returns a FetchAssetsAtsSyncCandidateSyncPayload object with these fields:
| Field | Type | Description |
|---|---|---|
assets | [AtsSyncCandidateSyncAsset]! | Next available |
token | String | Acknowledgment token for this batch. Pass the token in the next fetchAssets call to acknowledge receipt and request the next batch. If the token is null or empty, Indeed has delivered all assets. Wait the standard polling interval before you call again. |
Get assets by time range
After you acknowledge assets, call assetsByTimeRange to fetch them again from Indeed. Use this query to recover from data loss. Persist asset data in your data store. For pagination best practices, see the GraphQL Cursor Connections Specification.
Authenticate with a 2-legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction.
To retrieve new assets, use fetchAssets.
Request – Get assets by time range
If you omit a start or end date, the query uses the earliest and latest acknowledgment dates as defaults.
Gets candidate sync assets for a time range, including candidate details, smart screening updates, and pagination information.
query AssetsByTimeRange($input: AtsSyncCandidateSyncAssetsByTimeRangeInput!, $after: String) { atsSyncCandidateSync { assetsByTimeRange(input: $input, after: $after) { assets { id metadata { employerIdentifier stagedAt stagedTest completeSourceAttribution { enumKey name } } ... on AtsSyncCandidateSyncInterestedCandidateAsset { contact { candidate { email location name phone resume { files { url name contentType } } } job { sourcedPostingId } tracking { recruiterEmail } } } ... on AtsSyncCandidateSyncSmartScreeningUpdateAsset { smartScreeningUpdate { smartFitScore createdAt applicationIdentifier { __typename ... on AtsSyncCandidateSyncIndeedApplyApplicationIdentifier { indeedApplyId } } resume { url name contentType } } } } pageInfo { hasNextPage endCursor } } }}Response – Get assets by time range
assetsByTimeRange returns the same asset data as fetchAssets, but only for acknowledged assets. See Response – Get unacknowledged assets.
Mock assets expire after 14 days and stop appearing in assetsByTimeRange responses. See Create test assets.
Create test assets
Call stageAssets to create test candidate assets in sandbox mode. Test assets behave like real candidate assets. Use fetchAssets to retrieve them and test your workflow.
Authenticate with a 2-legged OAuth token. Your application authenticates directly with Indeed's authorization server without user interaction.
Requirements
Before you stage test assets:
- For Smart Sourcing test assets,
metadata.employerIdentifiermust match theemployerIdentifierof an employer registration that you created throughregisterEmployer. - Smart Screening test assets do not use
metadata.employerIdentifier. - The
sourcedPostingIdmust be a UUID, but does not need to match an existing job posting. - Indeed removes mock asset data 14 days after you stage it.
Request – Create test assets
To create test assets:
-
Call
stageAssetswith test candidate details such as name, email, phone, and location.To include a test resume, set
includeResumetotrue.The API returns a unique ID for each staged asset.
-
Call
fetchAssetsto retrieve the staged candidates. -
Verify that your integration processes the candidate data.
To identify mock assets, check the
stageTestfield on themetadataof eachassetsentry.
Stages a Smart Sourcing candidate asset for an employer and returns the created asset IDs.
Provide these required and optional fields:
| Field | Required | Type | Description |
|---|---|---|---|
metadata | Yes | AtsSyncCandidateSyncAssetMetadataInput | Asset metadata. |
contact | Yes | AtsSyncCandidateSyncInterestedCandidateContactInput | The candidate’s contact information. |
job | No | AtsSyncCandidateSyncInterestedCandidateContactJobInput | Job information for the contact. |
tracking | No | AtsSyncCandidateSyncInterestedCandidateTrackingInput | Tracking information for attribution and reporting. |
mutation { atsSyncCandidateSync { stageAssets(input: { assets: [{ smartSourcingContact: { metadata: { employerIdentifier: "employer-123" } contact: { candidate: { name: "Jane Smith" email: "jsmith@example.com" location: "Syracuse, New York 13209" phone: "+10001112223" includeResume: true } job: { sourcedPostingId: "e29aaba8-2cef-447f-a1e0-bcb7ec3fa730" } tracking: { recruiterEmail: "recruiter@example.com" } } } }] }) { ids } }}Stages a Smart Screening update asset for an Indeed Apply application and returns the created asset IDs.
Provide these required and optional fields:
smartScreeningUpdate is one member of the oneOf AtsSyncCandidateSyncStageableAssetInput. Set exactly one asset type for each list entry.
| Field | Required | Type | Description |
|---|---|---|---|
indeedApplyId | Yes | ID! | Indeed Apply ID for the application that was updated. applicationIdentifier is a oneOf, so set only indeedApply. |
smartFitScore | No | Float | The candidate’s smart fit score, if available. Omit this field to return null for the score. |
createdAt | No | DateTime | The time when the screening update was created. Order updates by this timestamp. Defaults to the current time if omitted. |
mutation { atsSyncCandidateSync { stageAssets(input: { assets: [{ smartScreeningUpdate: { applicationIdentifier: { indeedApply: { indeedApplyId: "example-indeed-apply-id" } } smartFitScore: 0.87 createdAt: "2026-06-22T12:00:00Z" } }] }) { ids } }}Screening does not use an includeResume flag. A fixed sample resume PDF is always attached because screening updates always include a resume.
Troubleshoot errors
For OAuth errors that occur before you reach GraphQL, see Troubleshoot OAuth errors.
For GraphQL errors, see Troubleshoot GraphQL errors.