- Job Update API workflow
- Job Update API references
- Authentication
- Update job posting
- Workflow
- Request – Update job posting
- Confirm your updates
- Partial updates
- Response – Update job posting
- Choose the query method to get job posting information
- Get job posting status by ID
- Authentication
- Single job query (node)
- Batch job query (nodes)
- Work with webhooks
- List job postings by criteria
- Clear job posting updates
- Workflow
- Request – Clear job posting updates
- Response – Clear job posting updates
- Job status
- Organic non-sponsored jobs
- Sponsored jobs
- Rate limits
- Troubleshoot errors
- FORBIDDEN: Advertiser is in a restricted moderation status
- FORBIDDEN: You are missing permissions for this action
- FORBIDDEN: Advertiser is requesting an update to EJ
- UNAUTHENTICATED
- BAD_USER_INPUT
- NOT_FOUND
- DOWNSTREAM_SERVICE_ERROR or INTERNAL_SERVER_ERROR
Job Update API guide
Update, clear updates, get details for, and list job postings on Indeed.
By using this API and its documentation and building an integration, you agree to the Additional API Terms and Guidelines.
Job Update API workflow
Update, clear updates, get details for, and list job postings on Indeed. Calls are free and excluded from Sponsored Jobs API usage policy limits.
- 1.Review Before you start - Under the single-source policy, ATSs are the source of truth for employer jobs.
- 2.Authenticate.
- 3.Update job posting - Ad agencies call
updateSourcedJobPostingsto update job posting fields. - 4.Choose a query method to get job posting information.
- 5.Get job posting status by ID. If you have job IRIs, call the GraphQL
nodeornodesquery. - 6.List job postings by criteria. For bulk job retrieval, call
findEmployerJobsPartner. - 7.Clear job posting updates - Ad agencies can clear job posting updates.
- 8.Check job status.
- 9.Review rate limits.
- 10.Troubleshoot GraphQL errors - Resolve GraphQL errors.
Job Update API references
updateSourcedJobPostings- Ad agencies can update job posting fields.node- Get job posting status by ID.nodes- List job postings by ID.findEmployerJobsPartner- Lists job postings for an employer.clearSourcedJobPostingUpdates- Ad agencies can clear job posting updates.
The ATS controls job posting creation and expiration.
Authentication
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.
See Integrate with Indeed and call APIs.
The findEmployerJobsPartner, node, and nodes queries require one of these OAuth token types:
| Token type | Description |
|---|---|
| 2‑legged OAuth token that specifies an advertiser | If you are an ad agency that uses the Sponsored Jobs API with the client credentials grant type (2-legged OAuth), you already have this token type. |
| 3-legged OAuth token | If you already have a 3-legged OAuth token, you can use it instead. |
The OAuth access token must include these scopes:
employer_accessemployer.hosted_job
For more information about adding scopes to OAuth tokens, see Scopes.
After you get an access token, include this token in the query. Indeed recommends that you refresh access tokens before they expire so that users do not need to sign in each time they view updated job statuses.
Update job posting
This feature is in beta and is not available in Japan. Contact Indeed for more information.
- If you submitted the job posting to Indeed, upsert it.
- If another partner submitted it, update the posting. Updates are primarily for ad agencies.
Japan only: All partners except ad agencies and Indeed PLUS Publisher Network partners can update the posting.
See also:
Enables ad agencies to update job posting fields on Indeed and Indeed PLUS.
Update only jobs authorized by your client. Unauthorized updates can prevent the client from using other Indeed tools on that job. To add a location the ATS does not have, use your XML or API integration.
Workflow
To update a job posting that you did not send to Indeed:
| # | Description | See |
|---|---|---|
| 1. | Choose clients to add: Contact Indeed. | |
| 2. | List job postings by criteria: Call | |
| 3. | Update job posting: To update a field such as the tracking URL or job URL, call | |
| 4. | Confirm your updates: To confirm your updates, call one of these methods:
To list sponsored jobs for a campaign, set | |
For information about rate limits on this call, see Rate limits.
Request – Update job posting
To update selected fields in a job posting, ad agencies can call the jobsIngest.updateSourcedJobPostings mutation.
This operation requires an access token that represents the advertiser.
The OAuth access token must include these scopes:
employer_accessemployer.hosted_job
See Get access token that represents employer. Instead of an employer ID, associate the token with an advertiser ID.
Provide only the fields that you want to update. To leave a field unchanged, set it to null or omit it.
This example calls the updateSourcedJobPostings mutation to update several fields in a job posting:
mutation UpdateSourcedJobPostings { jobsIngest { updateSourcedJobPostings( input: { updates: [ { sourcedPostingId: "<SOURCED POSTING ID OF JOB POSTING>" metadata: { url: "https://www.example.com/jobs/123" campaignCategories: ["springCampaign"] trackingUrl: "https://www.example.com/jobs/123?utm_source=indeed" } body: { title: "Software Developer" description: "Come build the future with us!" jobLocation: { general: { cityRegionPostal: "Phoenix, AZ 85003" streetAddress: "1234 Sunny Lane, Phoenix, AZ 85003" } } salary: { currency: "USD" maximumMinor: 1000 minimumMinor: 1000 period: "HOUR" } } } ] } ) { results { jobPosting { sourcedPostingId employerJobId } } } }}mutation UpdateSourcedJobPostings { jobsIngest { updateSourcedJobPostings(input: { updates: [{ sourcedPostingId: "<SOURCED POSTING ID OF JOB POSTING>" body: { description: "<h2>About the role</h2><p>Join our team as a software engineer. You design and build scalable backend services.</p><ul><li>Competitive salary</li><li>Remote-friendly</li><li>Health and dental benefits</li></ul>" descriptionFormatting: HTML } }] }) { results { jobPosting { sourcedPostingId employerJobId } } } }}updateSourcedJobPostings takes one argument: input, of type UpdateSourcedJobPostingsInput.
input takes one field: updates, which is an array of UpdateSourcedJobPostingInput objects. Each UpdateSourcedJobPostingInput object defines updates for one job posting.
Each UpdateSourcedJobPostingInput object takes these fields:
| Field | Type | Description |
|---|---|---|
sourcedPostingId | ID! | Required. For each job posting, provide one of these values:
|
metadata.url | WebUrl | The URL from the ad agency where a job seeker can apply if Indeed Apply is not available. |
metadata.campaignCategories | [String!] | Category tags that group related jobs for campaign job selection. Write Sponsored Jobs API queries with ad_campaign_category:{category} for the campaignCategories values that you provide. |
metadata.trackingUrl | WebUrl | The job tracking URL. When a job seeker views the job on Indeed, Indeed sends an HTTP request to this URL. |
body.title | String | The job posting title. |
body.description | String | The job description:
|
body.descriptionFormatting | DescriptionFormatting | The job description format. Set this field to |
body.jobLocation .general.cityRegionPostal | String! | Required if you update location. The city, administrative region such as state, county, or prefecture, and postal code for the job. If you set this field for a remote job, Indeed treats the job as a regional remote job. |
body.jobLocation .general.streetAddress | String | The street address of the job's primary location. Include the full address, including the street name and number. Indeed can use this address to improve location-based matching and show the address to job seekers. |
body.salary.currency | CurrencyCode | The salary currency code in ISO 4217 format. |
body.salary.maximumMinor | Int64 | The maximum salary in local minor currency. For example, the minor currency for USD is cents, so 1,000 represents $10. Set this field to |
body.salary.minimumMinor | Int64 | The minimum salary in local minor currency. For example, the minor currency for USD is cents, so 1,000 represents $10. Set this field to |
body.salary.period | JobSalaryPeriod! | Required if you update salary. The rate used to calculate the salary, such as hourly, daily, or weekly. |
body.companyName | String | Updates the company name for the job posting. To leave it unchanged, set this field to |
For more information about these fields, see the API reference.
Confirm your updates
To verify changes, the updateSourcedJobPostings response includes job IRIs. Use the node query with the returned IRIs.
See Get job posting status by ID.
Partial updates
Field updates are not atomic. If you update more than one field in one request, the API can rarely apply only some of the changes. When this happens, the response always includes an error. However, an error response does not always mean a partial update happened. If a request that updates multiple fields returns an error, you can view the updated job posting to see which fields, if any, were updated successfully. For error handling guidance, see Troubleshoot GraphQL errors.
Response – Update job posting
updateSourcedJobPostings returns an UpdateSourcedJobPostingsPayload object. This object includes a results field, which is an array of UpdateSourcedJobPostingResult objects. Each object corresponds to one job posting update result.
Each UpdateSourcedJobPostingResult object includes a jobPosting field of type SourcedJobPostingUpdate. If Indeed does not accept the update, this field is null. Otherwise, it contains this job posting information:
sourcedPostingId: The job posting UUID. This is the same asSourcedJobPosting.sourcedPostingId, which Indeed generated when it created the job posting. You use this value to expire or update the job posting.employerJobId: The job posting Indeed Resource Identifier (IRI). This is the same asEmployerJob.id.
Choose the query method to get job posting information
Use one of these methods to get job posting information:
| Method | Description |
|---|---|
Get job posting status by ID (node or nodes query) | Use this method for direct lookup by job IRI, which is the This method is faster than Use cases:
|
List job postings by criteria (findEmployerJobsPartner) | Use this search-based method to list all jobs. It works best for bulk inventory retrieval. Use case:
|
Get job posting status by ID
To get job posting status by IRI, which is the EmployerJob ID, call the GraphQL node or nodes query. These queries are more efficient than list job postings by criteria.
Authentication
Use the same authentication and authorization that findEmployerJobsPartner uses. See Authentication. The OAuth access token must include these scopes:
employer_accessemployer.hosted_job
Single job query (node)
Get one job by its IRI, which is the EmployerJob ID, with the Relay Node pattern:
query GetJob($id: ID!) { node(id: $id) { ...on EmployerJob { id jobData { title description company dateCreated datePostedOnIndeed jobLocation { city countryCode fullAddress } salary { max min period } externalPostingMetadata { jobPostingId jobRequisitionId } } managementUrls { viewJob } } }}Variables:
{ "id": "dXJuOmluZGVlZDplbXBsb3llcmpvYjphMWIyYzNkNC1lNWY2LTc4OTAtYWJjZC1lZjEyMzQ1Njc4OTA="}Job IRIs (EmployerJob IDs) are base64-encoded values. The id field in the response is the encoded IRI.
See EmployerJob.
POST https://apis.indeed.com/graphqlAuthorization: Bearer YOUR_ACCESS_TOKENContent-Type: application/json
{ "query": "query GetJob($id: ID!) { node(id: $id) { ... on EmployerJob { id jobData { title description company } } } }", "variables": { "id": "dXJuOmluZGVlZDplbXBsb3llcmpvYjphMWIyYzNkNC1lNWY2LTc4OTAtYWJjZC1lZjEyMzQ1Njc4OTA=" }}Batch job query (nodes)
Get status for multiple jobs by their IRIs (EmployerJob IDs).
Use to confirm multiple job updates, processing batches, of webhook events.
query GetMultipleJobs($ids: [ID!] !) { nodes(ids: $ids) { ... on EmployerJob { id jobData { title description company datePostedOnIndeed jobLocation { city countryCode } } } }}Variables:
{ "ids": [ "dXJuOmluZGVlZDplbXBsb3llcmpvYjphMWIyYzNkNC1lNWY2LTc4OTAtYWJjZC1lZjEyMzQ1Njc4OTA=", "dXJuOmluZGVlZDplbXBsb3llcmpvYjpiMmMzZDRlNS1mNmE3LTg5MDEtYmNkZS1mMjM0NTY3ODkwMTI=", "dXJuOmluZGVlZDplbXBsb3llcmpvYjpjM2Q0ZTVmNi1hN2I4LTkwMTItY2RlZi0zNDU2Nzg5MDEyMzQ=" ]}Job IRIs (EmployerJob IDs) are base64-encoded values. The id fields in the response are the encoded IRIs.
See EmployerJob.
Work with webhooks
Webhook payload includes job IRI:
{ "eventType": "job.updated", "jobIri": "dXJuOmluZGVlZDplbXBsb3llcmpvYjphMWIyYzNkNC1lNWY2LTc4OTAtYWJjZC1lZjEyMzQ1Njc4OTA=", "timestamp": "2025-12-10T15:30:00Z"}Use the node query with an IRI to get job posting status. For query examples, see Get job posting status by ID.
Benefits:
- Real-time updates
- Fast IRI-based retrieval
- Pre-visibility enrichment window
List job postings by criteria
Contact Indeed to use this feature. Additional requirements apply.
Lists job postings for an employer.
This call is rate limited.
If you make one call to list job postings by criteria each hour for each client, you might never reach the rate limit. However, the HTTP 429 error can still occur. If that happens, reduce your request rate. See 429 error code.
For rate limit information for this call, see Rate limits.
Request – List job postings by criteria
To list an employer's job postings, call the findEmployerJobsPartner query:
This example calls the findEmployerJobsPartner query to list job postings by criteria in descending order by the date posted on Indeed:
query FindEmployerJobsPartner { findEmployerJobsPartner(input: { filters: { legacySourceId: "60a9614a5d973a21", jobFeedType: ["INTEGRATED_FROM_PARTNER"] }, sort: [{ sortDirection: DESC, sortField: datePostedOnIndeed }] }, first: 10, before: null, after: null) { employerJobs { id jobData { title datePostedOnIndeed dateCreated description company jobLocation { countryCode city postalCode fullAddress } externalJobPageUrl externalPostingMetadata { jobPostingId jobRequisitionId campaignCategories trackingUrls rawInputLocation isIntegratedJob } } managementUrls { viewJob } seatsConnection { pageInfo { endCursor hasNextPage hasPreviousPage startCursor } seats { jobPost { id externalPartnerCallToAction(input: { locale: "en-us" }) { imageAltText imageUrl } status { globalStatus { isIndeedApplyActive } surfaceStatuses { isRejected isSponsorshipRequired isMissingRequiredSponsorship } } } } } } estimatedTotalResultsCount pageInfo { endCursor hasNextPage hasPreviousPage startCursor } }}findEmployerJobsPartner finds job postings by source ID or lists an employer's job postings. It takes these input fields:
| Field | Description |
|---|---|
input.filters.jobFeedType | Filters jobs by feed type, which is the job source. If the feed type is Valid values are:
Default: If your client’s jobs come from web crawling or are hosted on Indeed in Scenario 2, specify the correct jobFeedType filter. By default, findEmployerJobsPartner returns only jobs from integrations, such as XML or API feeds. For more information, see Scenario 2 details.. |
input.sort | Array of objects that define how to sort job postings in the response. Each object contains these fields:
|
first | The number of job postings to return.
|
before | Gets items with a cursor value before this value. Use the PageInfo object in the response to get pagination details. |
after | Gets items with a cursor value after this value. Use the PageInfo object in the response to get pagination details. |
Response – List job postings by criteria
findEmployerJobsPartner lists job postings for the employer associated with the access token that you use to call the API.
If you specify FindEmployerJobsPartnerInput.filter or FindEmployerJobsPartnerInput.sort in the request, the API filters and sorts the job postings in the response.
If your API token does not return the jobs that you expect, tell the user to contact their Indeed support representative through their Indeed employer account page. The representative can help connect jobs on Indeed to your advertiser or to the user's Indeed account, if appropriate.
The API returns a FindEmployerJobsPartnerConnection response object with these fields:
| Field | Type | Description |
|---|---|---|
employerJobs | [EmployerJob]! | An array of job posting objects. For the fields in each object, see the table in Response - View job posting. |
estimatedTotalResultsCount | Int! | The estimated total number of job postings in the response. |
pageInfo | PageInfo! | Pagination information. |
This example response lists job postings.
The API returns only one item in seats, so startCursor and endCursor are the same, and hasNextPage and hasPreviousPage are false.
{ "data": { "node": { "id": "aXJpOi8vYXBpcy5pbmRlZWQuY29tL0VtcGxveWVySm9iLzkxZGU0ZjVhLWE1MWYtNGQ1Ni1iOWI0LWNhMDQzZWVjNDAzMQ==", "jobData": { "title": "Certified Nursing Assistant CNA", "datePostedOnIndeed": "2022-03-22T20:33:28Z", "dateCreated": "2022-03-22T20:33:28Z", "description": "Anytown Health and Rehabilitation Center in Anytown, USA is a 186-bed center offering a variety of individualized, health care services for our patients and residents. We are seeking a qualified and committed team member to join our team.", "company": "Anytown Health and Rehabilitation Center", "jobLocation": { "countryCode": "US", "city": "Cambridge", "postalCode": null, "fullAddress": null }, "externalJobPageUrl": "http://www.indeed.com/job/certified-nursing-assistant-cna-9354ed892ad3a1b6", "externalPostingMetadata": { "jobPostingId": "CBA-Anytown-Posting-Id", "jobRequisitionId": "CBA-Anytown-Req-Id", "campaignCategories": [], "trackingUrls": [], "isIntegratedJob": false } }, "managementUrls": { "viewJob": "https://employers.indeed.com/jobs/view?employerJobId=aXJpOi8vYXBpcy5pbmRlZWQuY29tL0VtcGxveWVySm9iLzkxZGU0ZjVhLWE1MWYtNGQ1Ni1iOWI0LWNhMDQzZWVjNDAzMQ==" }, "seatsConnection": { "pageInfo": { "endCursor": "YVhKcE9pOHZZWEJwY3k1cGJtUmxaV1F1WTI5dEwwcHZZbEJ2YzNRdk5EQXhOVFkxTW1OaFpEYzJZVFF4TlE9PQ==", "hasNextPage": false, "hasPreviousPage": false, "startCursor": "YVhKcE9pOHZZWEJwY3k1cGJtUmxaV1F1WTI5dEwwcHZZbEJ2YzNRdk5EQXhOVFkxTW1OaFpEYzJZVFF4TlE9PQ==" }, "seats": [ { "jobPost": { "id": "aXJpOi8vYXBpcy5pbmRlZWQuY29tL0pvYlBvc3QvNDAxNTY1MmNhZDc2YTQxNQ==", "externalPartnerCallToAction": [ { "imageUrl": "https://dlogqfjusi9uq.cloudfront.net/cta/en_US/not_searchable.svg", "imageAltText": "Update needed on Indeed" } ], "status": { "globalStatus": [ { "lifecycleStatus": "INACTIVE", "isIndeedApplyActive": false } ], "surfaceStatuses": [ { "isRejected": false, "isSponsorshipRequired": false, "isMissingRequiredSponsorship": false } ] } } } ] } } }}To troubleshoot validation errors, see Troubleshoot GraphQL errors. For more information about validation errors, see Validation in the GraphQL documentation.
Clear job posting updates
This beta feature is not available in Japan. Contact Indeed for more information.
An ad agency that updates a client's job posting can later clear those updates.
Workflow
An ad agency can call this operation to clear any updates it made to job postings.
For example, if you no longer plan to work with a client, use this operation to clear the updates that you made to that client's job postings. This operation restores the latest ATS data for the job posting. Your clients can then use other Indeed tools to manage the job posting again.
| # | Description | See |
|---|---|---|
| 1. | Update job postings: Add clients and update their job postings. | Update job postings |
| 2. | List job postings by criteria: Call | |
| 3. | Clear job posting updates: Clear updated fields in a job posting. Call | |
| 4. | List job postings by criteria: Call |
For rate limit information for this call, see Rate limits.
Request – Clear job posting updates
To clear fields in a job posting that updateSourcedJobPostings previously updated, ad agencies can call the jobIngest.clearSourcedJobPostingUpdates mutation.
This operation requires an access token that represents the advertiser that originally made the updates.
The OAuth access token must include these scopes:
employer_accessemployer.hosted_job
See Get access token that represents employer. Instead of an employer ID, associate the token with an advertiser ID.
This example calls the clearSourcedJobPostingUpdates mutation to clear updates from a job posting:
mutation ClearSourcedJobPostingUpdates { jobsIngest { clearSourcedJobPostingUpdates(input: { updates: [{ sourcedPostingId: "<SOURCED POSTING ID OF JOB POSTING>" }] }) { results { jobPosting { sourcedPostingId employerJobId } } } }}clearSourcedJobPostingUpdates takes one argument: input, of type ClearSourcedJobPostingUpdatesInput.
input takes one field: updates, which is an array of ClearSourcedJobPostingUpdateInput objects. Each ClearSourcedJobPostingUpdateInput object identifies a job posting whose updates you want to clear.
To clear updates for multiple job postings in one request, include multiple ClearSourcedJobPostingUpdateInput objects.
Each ClearSourcedJobPostingUpdateInput object takes these fields:
| Field | Type | Description |
|---|---|---|
sourcedPostingId | ID! | Required. For each job posting, provide one of these values:
|
Response – Clear job posting updates
clearSourcedJobPostingUpdates returns a ClearSourcedJobPostingUpdatesPayload object. This object includes a results field, which is an array of ClearSourcedJobPostingUpdateResult objects. Each object corresponds to one job posting whose updates were cleared.
Each ClearSourcedJobPostingUpdateResult object includes a jobPosting field of type SourcedJobPostingUpdate. If Indeed does not accept the request to clear updates, this field is null. Otherwise, it contains this information about the job posting:
sourcedPostingId: The job posting UUID. This value matchesSourcedJobPosting.sourcedPostingId, which Indeed generated when it created the job posting. You use this value to expire or update the job posting.employerJobId: The job posting Indeed Resource Identifier (IRI). This value matchesEmployerJob.id.
Job status
Because feed policy has changed, most jobs that you manage on Indeed no longer come from your feeds. In the past, you might have captured organic traffic data from job seekers who navigated to your career pages.
| Job status | Booleans | See |
|---|---|---|
| Organic |
| Organic non-sponsored jobs |
| Sponsored only with spend |
| Sponsored jobs |
| Sponsored only without spend |
| |
| Nowhere |
|
Organic non-sponsored jobs
To get organic traffic data for jobs that are not sponsored, use one of these approaches:
| Approach | Description | |
|---|---|---|
| 1. | Add the trackingUrl field | To receive an HTTP request for each click on a job, add this field to your jobs whether or not:
See |
| 2. | Use custom job URLs | Replace the job URL with a career page that you own, or work with ATS partners to append your tracking metadata to the job URL. If a job does not use Indeed Apply, job seekers navigate to this URL. If a job does use Indeed Apply, job seekers do not navigate to this URL. See |
| 3. | Collaborate with client ATS | Work with your clients and their ATS to gather organic performance data. |
| 4. | Have clients sign in to the Indeed Analytics interface | Your clients can sign in to the Indeed Analytics interface to view complete organic performance for all jobs, whether sponsored or not. This interface gives them a full view of account data. |
Sponsored jobs
To get sponsored job traffic data, call Sponsored Jobs API v8 or later to get employer job IDs that match the IDs that the Job Update API returns.
Rate limits
The Job Update API enforces rate limits on calls to these queries and mutations:
findEmployerJobsPartnerquery to list job postings by criteriajobsIngest.updateSourcedJobPostingsmutation to update job postingsjobsIngest.clearSourcedJobPostingUpdatesmutation to clear job posting updates
These limits follow best practices that help keep the API available. Indeed sets these limits above normal daily Job Update API usage, but throttles large request volumes over short periods and requires retries. To avoid hitting rate limits, spread your API requests over 10 minutes.
If you exceed a rate limit, the API returns HTTP 429, either at the HTTP level or in the errors array in the GraphQL JSON response.
You do not need to take any special action. If you need help working around these limits, request support.
If you exceed these rate limits, the API notifies you:
| Query or mutation | Rate limit |
|---|---|
findEmployerJobsPartner query | 5 requests per second |
| 20 requests per second total across both mutations |
See also:
Troubleshoot errors
To troubleshoot OAuth errors that occur before you access GraphQL, see Troubleshoot OAuth errors.
To troubleshoot GraphQL errors, see Troubleshoot GraphQL errors.
These errors can occur:
- FORBIDDEN: Advertiser is in a restricted moderation status
- FORBIDDEN: You are missing permissions for this action
- FORBIDDEN: Advertiser is requesting an update to EJ
- UNAUTHENTICATED
- BAD_USER_INPUT
- NOT_FOUND
- [DOWNSTREAM_SERVICE_ERROR or INTERNAL_SERVER_ERROR](
FORBIDDEN: Advertiser is in a restricted moderation status
Example error message
{ "errors": [ { "extensions": { "code": "FORBIDDEN", "message": "Advertiser is in a restricted moderation status" } } ]}What it means
Indeed has restricted the advertiser associated with the OAuth token as a spam protection measure.
What to do
This error is unlikely. If it occurs, contact your partner manager to remove the restriction.
FORBIDDEN: You are missing permissions for this action
Example error message
{ "errors": [ { "extensions": { "code": "FORBIDDEN", "message": "You are missing permissions for this action. Ask your administrator for the permissions [Hosted_Job Create, Hosted_Job Update, Hosted_Job Read]" } } ]}What it means
The user associated with the OAuth token does not have permission to update jobs.
What to do
If an admin user did not create the OAuth client, grant job management permission to the user associated with the OAuth client. Any admin user can grant this permission in the UI. See Indeed account settings.
FORBIDDEN: Advertiser is requesting an update to EJ
Example error message
{ "errors": [ { "extensions": { "code": "FORBIDDEN", "message": "Advertiser is requesting an update to EJ (id=<EJID>), but the job is claimed by a different advertiser." } } ]}What it means
A different advertiser has already updated this job, so this advertiser cannot update it. Only one advertiser can update a job at a time.
Verify that you requested the OAuth token for the correct advertiser.
What to do
If another advertiser updated the job, this error continues until that advertiser's updates are cleared. See the clear job posting updates mutation.
This situation can occur for either of these reasons:
-
The agency has access to the job through more than one advertiser.
After the agency updates the job through one advertiser, it gets this error if it tries to update the same job through a different advertiser.
-
The employer edited the job in the UI.
The employer must remove those edits in the UI before the agency can update the job through the API.
UNAUTHENTICATED
Example error message
"extensions.code": "UNAUTHENTICATED"What it means
Indeed cannot authenticate your request. Your OAuth token is expired or malformed.
What to do
See Troubleshoot OAuth errors.
BAD_USER_INPUT
Example error message
"extensions.code": "BAD_USER_INPUT" What it means
Your request contains malformed input. See the message field for details.
What to do
Fix the malformed request fields.
Check the API references for examples of correctly formatted requests:
NOT_FOUND
Example error message
"extensions.code": "NOT_FOUND"What it means
Indeed cannot find the job.
What to do
Verify that the sourcedPostingId is correct and that you requested the OAuth token for the correct advertiser. This error also occurs if the requesting advertiser does not have permission to view the job.
DOWNSTREAM_SERVICE_ERROR or INTERNAL_SERVER_ERROR
Example error message
"extensions.code": "DOWNSTREAM_SERVICE_ERROR"Or:
"extensions.code": "INTERNAL_SERVER_ERROR"What it means
An internal server error occurred.
What to do
Try the request again later. If the error continues, contact your partner manager.