Job Sync API guide (BETA)
Use the Job Sync API to submit job postings to Indeed, and update or expire those job postings in Indeed.
Closed BETA:
During BETA, Indeed can support a limited number of ATS partners.
Indeed maintains a waiting list. To indicate your interest, submit an integration request. Indeed keeps the request on file and will reach out when ready to onboard you.
Note:
By using this API and its documentation and building an integration, you agree to the Additional API Terms and Guidelines.
Job Sync API reference
For Job Sync API reference information, see the Job Sync API reference.
Before you start
Use the client credentials flow (2-legged OAuth) to get a client ID and secret for your application, which you exchange for an access token. Use this token for authentication when you call the Job Sync API. The token expires after one hour.
To call the API, POST
the request to the following endpoint:
POST https://apis.indeed.com/graphql
Note:
Use the
POST
method for all queries and mutations. The API does not support theGET
method.
In the POST
request body, include the mutation or query, an optional operation name, and variable inputs:
{
"query": "...",
"operationName": "...",
"variables": {
"myVariable": "someValue",
...
}
}
Job Sync API overview
Note:
For information about how to authenticate and call the API, see Before you start.
Use the Job Sync API to submit job postings to Indeed, and update or expire those job postings in Indeed.
To submit a job posting, you provide details about the job. In addition to a job title, description, location, and benefits for the job, you provide details about the job source, including the sourceName
.
The sourceName
is the name for a group of jobs, such as a parent organization, that are managed together and that is hiring for the role. Choose a unique sourceName
for each client delineation that you have.
So, if an employer has multiple job groups that separate people manage, choose a unique sourceName
for each job group. For example, if subsidiaries or franchises exist with multiple branded locations under the same company, those jobs have the same value in the sourceName
field. The sourceName
must be unique across all job groups. A sourceName
can have only one sourceType
, which is the type of organization.
The API accepts a complete job posting. If accepted, the API returns an Indeed employer job ID, which is the unique ID for the posting, in the sourcedPostingId
field. Pending spam and fraud detection, Indeed indexes and makes the job available on Indeed in from minutes to hours.
The API rejects the job posting if it has missing or malformed data, which causes an error at call time. The API returns null in the sourcedPostingId
field and an error in the standard GraphQL errors
array.
To update a job posting, provide the same values for the jobPostingId
and sourceName
fields and OAuth client ID that you used when you submitted the job posting. You must also provide all required job details even if you are not changing those. The API returns the same unique ID, the Indeed employer job ID, that Indeed generated for the submitted job posting.
To expire a job posting, provide the same Indeed employer job ID that Indeed generated for the submitted job posting in the sourcedPostingId
field. The API returns an internal tracking ID from logrepo and a response code that indicates the success or failure of the operation.
Note:
Jobs that you manage through the Job Sync API support the same Indeed Apply capabilities that the Indeed Apply XML feed supports.
Submit a job posting
createSourcedJobPostings(input:
CreateSourcedJobPostingsInput):
CreateSourcedJobPostingsPayload
To submit a job posting, call the createSourcedJobPostings
mutation with the CreateSourcedJobPostingsInput
input object. In the jobPostings
field in this input object:
- The
body
andmetadata
fields are required - The
applyMethod
field is optional
Provide a job title, description, location, benefits for the job, details about the job source, including the source name. The sourceName
is the name for a group of jobs, such as a parent organization, that are managed together and that is hiring for the role. Choose a unique value for each client delineation that you have. So, if an employer has multiple job groups that separate people manage, choose a unique value for each job group. For example, if subsidiaries or franchises exist with multiple branded locations under the same company, those jobs have same value in the sourceName
field. The sourceName
must be unique across all job groups and can have only one sourceType
, which is the type of organization.
Mutation {
createSourcedJobPostings(input: {
jobPostings: [{
body: {
title: "title 1"
description: "description 1"
location: {
country: "US"
cityRegionPostal: "Syracuse, New York 13209"
}
benefits: []
}
metadata: {
jobSource: {
companyName: "Company"
companyWebsite: "https://www.mycompany.com"
sourceName: "Source"
sourceType: "Employer"
contacts: {
contactType: "contact"
contactInfo: {
contactEmail: "[email protected]"
}
}
}
jobPostingId: "JobId1"
datePublished: "2023-01-02T12:00Z"
url: "http://example.com/careers/job1.html"
}
}]
}) {
results {
jobPosting {
sourcedPostingId
}
}
}
}
The API returns the CreateSourcedJobPostingsPayload
return type with a unique sourcedPostingId
that Indeed generates for each submitted job posting.
The value in sourcedPostingId
depends on whether the API accepts or rejects the posting:
- The API accepts a complete job posting. The
sourcedPostingId
value is the Indeed employer job ID, which you use to expire the job. Pending spam and fraud detection, Indeed indexes and makes the job available on Indeed in from minutes to hours. - The API rejects the job posting if it has missing or malformed data, which causes an error at call time. The
sourcedPostingId
value is null, and the API returns an error in the standard GraphQLerrors
array.
Update a job posting
createSourcedJobPostings(input:
CreateSourcedJobPostingsInput):
CreateSourcedJobPostingsPayload
To update a job posting, call the createSourcedJobPostings
mutation with the CreateSourcedJobPostingsInput
input object. In the jobPostings
field in the input object:
- The
body
andmetadata
fields are required - The
applyMethod
field is optional
In the input object, you must specify the same values for the jobPostingId
and sourceName
fields and OAuth client ID that you used when you submitted the job posting. You must specify all required job details even if you are not changing those.
Mutation {
createSourcedJobPostings(input: {
jobPostings: [{
body: {
title: "title 1"
description: "description 1"
location: {
country: "US"
cityRegionPostal: "Syracuse, New York 13209"
}
benefits: []
}
metadata: {
jobSource: {
companyName: "Company"
sourceName: "Source"
sourceType: "Employer"
}
jobPostingId: "JobId1"
datePublished: "2023-01-02T12:00Z"
url: "http://example.com/careers/job1.html"
}
}]
}) {
results {
jobPosting {
sourcedPostingId
}
}
}
}
The mutation returns the CreateSourcedJobPostingsPayload
return type with the same sourcedPostingId
value that Indeed generated for the job posting when it was submitted. This value is the Indeed employer job ID, which you use to expire the job.
Expire a job posting
expireSourcedJobsBySourcedPostingId(input:
ExpireSourcedJobsBySourcedPostingIdInput!):
ExpireSourcedJobsBySourcedPostingIdPayload
Call the API by using the expireSourcedJobsBySourcedPostingId
mutation with the ExpireSourcedJobsBySourcedPostingIdInput
input object with the sourcedPostingId
from the submitted job posting.
Mutation {
expireSourcedJobsBySourcedPostingId(input: {
jobs: {
sourcedPostingId: "JobId1"
}
}]
}) {
results {
trackingKey
}
}
}
The mutation returns the ExpireSourcedJobsBySourcedPostingIdPayload
return type with a trackingKey
, which is an internal tracking ID from logrepo, and the ExpireSourcedJobResultInfo
object, which includes the unique job ID.
Indeed does not verify whether the job exists before responding. The response is always ACCEPTED
.
Frequently asked questions
How does this API differ from the Indeed Apply XML feed?
Jobs that you manage through the Job Sync API support the same Indeed Apply capabilities that the Indeed Apply XML feed supports. If you're being sent to this guide, use the Job Sync API to submit job postings to Indeed rather than building an XML integration.
How do I update a job?
Call the Job Sync API with the updates to your job. You must specify the same values for the jobPostingId
and sourceName
fields and OAuth client ID that you used when you submitted the job posting.
Indeed deduplicates on those two fields to determine uniqueness. You must specify all required job details even if your are not changing those.
How do I reactivate an expired job?
Call the Job Sync API with the same jobPostingId
and sourceName
as the expired job, just as if you were updating an open job. To reflect the date the job was reopened in your ATS, update the datePublished
field value.
Important:
You can reactivate a job for 30 days after it's expired. After that time, Indeed might archive statistics and configuration related to the job, though you might receive the same
sourcedPostingId
.
How do I define a salary range or a fixed salary?
To define a salary range, enter the minimum salary in the minimumMinor
field, and enter the maximum salary in maximumMinor
field.
To define a salary with a minimum salary only, enter the minimum salary in the minimumMinor
field.
To define a fixed salary, enter the fixed salary in the minimumMinor
and maximumMinor
fields.
How do I add a client/employer?
Create the jobs with a unique sourceName
for that client.
The sourceName
is the name for a group of jobs, such as a parent organization, that are managed together and that is hiring for the role. Choose a unique source name value for each client delineation that you have.
So, if an employer has multiple job groups that separate people manage, choose a unique value for each job group. For example, if subsidiaries or franchises exist with multiple branded locations under the same company, those jobs have the same value in this field. The value must be unique across all job groups and can have only one sourceType
, which is the type of organization.
For example, to create uniqueness among branches that manage their jobs separately, follow this example.
The ConvenienceMart
company has two branches and three stores. So that these branches and stores can manage their jobs separately, define the following combinations of companyName
and sourceName
fields:
Branch | Store | companyName and sourceName definitions |
---|---|---|
Tokyo | Shibuya station |
|
Shinjuku station |
|
|
Osaka | Osaka station |
|
How long before a job posting appears on Indeed?
Most jobs take from one to two hours to become searchable by job seekers.
What data do I include in jobPostingId and jobRequisitionId?
Include this data in the jobPostingId
and jobRequisitionId
fields:
Field | Value |
---|---|
jobPostingId
|
Unique ID across your ATS. Can be a UUID if you use one. If you repost a job and persist this ID, you can open a previously expired job. |
jobRequisitionId
|
Human-readable ID, and not required to be unique across the ATS. Ideally, unique ID across one of your clients, bounded by The recruiter likely remembers this ID when they distinguish two jobs with the same title. |
See also
- Job Sync API reference
- Client credentials flow (2-legged OAuth)
Updated 1 day ago