- Base URL
- Endpoints
- Public endpoints
- Private endpoints
- OAuth scopes
- Campaign predictions
- Organic job predictions
- Handle authorization errors
- Recommended best practices
- Account management
- Campaign management
- Get campaign budget quote
- Create campaign
- Update general campaign information
- Get campaign budget and duration
- Update campaign budget and duration
- Reports
- Get campaign statistics, for date range
- Get campaign predictions
- Request body
- CampaignPredictions
- JobInfo
- CampaignInfo
- PredictionsInfo
- Response
- JobLevelPredictions
- Job details
- Prediction
- Get organic job performance and prediction
- Organic job performance and prediction request
- OrganicjobPrediction field
- JobInfo field
- Organic job performance and prediction response
- OrganicMetric field
- OrganicPrediction field
- SponsoredPrediction field
Sponsored Jobs API guide for ATS partners
Access private endpoints, including campaign predictions and organic job performance and prediction.
Unless you have a written agreement with Indeed regarding your use of Indeed's APIs, by using this API or its documentation, you agree to apply the Indeed API Terms and the Additional API Terms and Guidelines to your use of Indeed's APIs.
These technical details supplement the Sponsored Jobs API reference for ATS partners and describe the endpoints available for your integration. Some endpoints are public; others are private and available only to ATS partners.
Base URL
ATS partners access the API at this base URL.
|
Endpoints
Public endpoints
The Sponsored Jobs API reference for ATS partners documents these endpoints.
If an endpoint supports both ad agency and direct employer usage, use the direct employer method:
Private endpoints
These endpoints are available only to ATS partners set up for this program:
OAuth scopes
In your OAuth authorization code request, pass the scopes for the endpoints you call. The end user can grant none, some, or all of them. Use these tables to find the scope for each endpoint.
Campaign predictions
| API endpoint | OAuth scope | Access token type |
|---|---|---|
POST /v1/campaignpredictions | employer_access | With employer_access scope. See Get an employer access token. |
Organic job predictions
| API endpoint | OAuth scope | Access token type |
|---|---|---|
POST /v1/organicjobpredictions | employer_access | Any |
Handle authorization errors
Handle the errors that occur when a user lacks access to the requested scopes or does not authorize your app. To see which scopes were granted, check the scope field in the access token response.
The error codes are:
| Error code | Description |
|---|---|
403 INSUFFICIENT_SCOPE | The access token is valid but was not granted the necessary scope. |
401 INVALID_TOKEN | The access token is missing, invalid, or expired. |
For ways to handle these errors, see Recommended best practices. You can let the user complete the OAuth authorization code grant again to authorize more scopes, but some users have restricted permissions and cannot authorize every scope you request.
If your app is not granted every requested scope, let it run with a limited feature set.
Recommended best practices
The API is eventually consistent. After you create a campaign with POST /v1/campaigns, GET /v1/campaigns/{campaignId} might not return it for a short time. Add a retry mechanism if you request a resource immediately after you create or change it.
Monitor 4XX responses to catch API usage issues. You might see 401 INVALID_TOKEN and 403 INSUFFICIENT_SCOPE errors when you use OAuth scopes.
5XX responses are usually temporary internal service issues. Retry after a delay. If the errors persist, email marketplacesupport@indeed.com for help.
If the request path is not prefixed with /ads, the response indicates that Indeed could not route the request to the Sponsored Jobs API. For example, use https://apis.indeed.com/ads/v1/account, not https://apis.indeed.com/v1/account.
Account management
| Verb | Endpoint | Reference |
|---|---|---|
GET | /v1/account | Get Indeed advertiser account information for an employer |
Use this endpoint to get basic information about the employer.
These responses mean the employer must complete Set up employer account:
-
400 NOT_EMPLOYER_ACCOUNTmeans the user has no Indeed employer account. -
billingActiveisfalse, which means the user has not finished the Indeed account setup required to sponsor jobs.To include the billing status in the response, pass
fields=id,email,contact,company,jobSourceList,billingActive.
Campaign management
An employer's campaign matches what the employer manages in the Indeed Analytics dashboard. Every job campaign has a unique ID, such as 784e4acec9x100z2.
Use these endpoints to:
- Get campaign budget quote
- Create campaign
- Update general campaign information
- Get campaign budget and duration
- Update campaign budget and duration
Get campaign budget quote
Before an employer creates an average daily budget (ADB) campaign, use this endpoint to get recommended daily budgets for each job and a campaign-level average daily budget.
| Verb | Endpoint | Reference |
|---|---|---|
POST |
| Get campaign budget quote |
The response includes the average budget quote for the sponsorship plan, a quote for each matched job, and recommendations for the STANDARD and PREMIUM tiers.
The recommended daily budget is a target, not a guarantee. Indeed optimizes toward it, but daily spend varies. For example, with a $25 average daily budget, spend might be $20 on day 1 and $30 on day 2.
Calls to this endpoint are not charged under the Sponsored Jobs API usage policy.
- Wait 2 to 3 hours after posting new jobs before you create a campaign.
- Create the campaign within 1 hour of the budget recommendation call. After that, market conditions can change, and campaign creation uses the latest recommended budgets.
- Jobs added manually, or automatically through query-based job resolution, use their recommended budgets as the default daily spend.
Request:
curl -L -X POST 'https://apis.indeed.com/ads/v1/campaignbudgetquote' \-H 'Content-Type: application/json' \-H 'Accept: application/json' \--data-raw '{ "jobsQuery": "title:\"financial analyst\" AND city:(toronto OR \"new york\")", "jobsTitle": "Healthcare Intern", "jobsCompany": "Indeed", "jobsLocation": "Austin, TX", "jobsLocationRadius": 25, "jobsSourceId": "8977ac341a3c4527", "jobsSourceName": "CompanyABC", "jobsToInclude": "ALL"}'Response:
{ "meta": { "status": 200, "errors": [{ "type": "RESOURCE_NOT_FOUND", "description": "Couldn't locate the requested resource" }], "rootLocation": "https://apis.indeed.com/ads", "perPage": 25, "links": [{ "rel": "next", "href": "/v1/campaigns/3141592653589793" }] }, "data": { "sponsorshipPlanBudgetQuotes": [{ "sponsorshipPlan": "PREMIUM", "dailyAvgBudgetPerJob": { "amount": 0, "currency": "string" }, "jobBudgetQuotes": [{ "jobKey": "89deb9de58ebe149", "dailyBudget": { "amount": 0, "currency": "string" } }] }] }}Create campaign
Creates a sponsored jobs campaign.
Prerequisites
- Wait 2 to 3 hours after posting new jobs before you create a campaign.
- Your employer account must be associated with a job source. Use
GET /v1/accountto list the job sources for your account. If it has none, contact Indeed Customer Support. - Your employer account must have valid billing information before the campaign can sponsor jobs.
| Verb | Endpoint | Reference |
|---|---|---|
POST |
| Create campaign |
This endpoint returns the new campaign ID. Store it so you can update the campaign or retrieve reports.
When you create a campaign, set the budget and duration the employer selected. Use the employer's default currency.
- The minimum budget is
$50, and the minimum duration is 7 days. - For each job, use the unique reference number from the XML feed.
- Use
YYYY-MM-DDfor dates, in the US Central time zone.
To create a campaign, set these parameters
| Field | Description |
|---|---|
jobsToInclude | Always set to |
jobsQuery | Use Example:
|
jobsSourceName | Source or company for this job. Must exactly match the job's Example:
|
If the employer chooses a monthly campaign
Monthly recurring campaigns follow the calendar month.
| Field | Description |
|---|---|
budgetMonthlyLimit | The budget amount. |
budgetFirstMonthBehavior | Set to |
If the employer chooses a fixed duration campaign
| Field | Description |
|---|---|
budgetOnetimeLimit | Budget amount. |
startDate | Campaign start date, in YYYY-MM-DD format and the US Central time zone. Defaults to today. |
| Campaign end date, in
|
Update general campaign information
| Verb | Endpoint | Reference |
|---|---|---|
PATCH | /v1/campaigns/{campaignId} | Update general campaign information |
Use this endpoint to change the campaign status.
Employers can set a campaign to one of these statuses:
| Status | Description |
|---|---|
ACTIVE | The campaign can sponsor jobs. |
PAUSED | The campaign does not sponsor jobs until the employer makes it active. |
DELETED | The employer deleted the campaign. |
Status applies only to the campaign. It is independent of the employer’s billing status and remaining budget.
An active campaign might still need these checks:
| Campaign status | Additional check | Description |
|---|---|---|
Active | Use the account management endpoint to confirm billing is active. | If billing is not active, the campaign cannot spend. Alert the user: “You must first add billing details to your Indeed account to fund your campaigns." Then redirect the user to set up employer account. |
Active | Use the get a campaign's budget and campaign performance endpoints to check the remaining budget. | If no budget remains, the campaign cannot keep sponsoring the job. Ask the user whether to update the budget, then use the update a campaign's budget endpoint to set the new total, which is the original amount plus any addition. |
Get campaign budget and duration
| Verb | Endpoint | Reference |
|---|---|---|
GET | /v1/campaigns/{campaignId}/budget | Get campaign budget and duration |
Use this endpoint to get a campaign’s budget and duration. The fields returned depend on whether the campaign has a single lifetime budget or recurs monthly.
Monthly recurring campaigns
These campaigns follow the calendar month. The response includes budgetMonthlyLimit, the monthly budget amount.
Fixed time-duration campaigns
| Field | Description |
|---|---|
budgetOnetimeLimit | Budget amount. |
startDate | Campaign start date, in YYYY-MM-DD format and the US Central time zone. Defaults to today. |
| Campaign end date, in
|
Update campaign budget and duration
| Verb | Endpoint | Reference |
|---|---|---|
PATCH | /v1/campaigns/{campaignId}/budget | Update campaign budget and duration |
Use this endpoint to change the campaign’s budget and duration.
Reports
Use the reporting endpoints to pull campaign performance reports from Indeed and make them available to employers.
Get campaign statistics, for date range
| Verb | Endpoint | Reference |
|---|---|---|
GET | /v1/campaigns/{campaignId}/stats | Get campaign statistics, for date range |
Use this endpoint to get a campaign performance report for a date range.
ATS Partners can use this report to present aggregated Clicks, Impressions, Conversions, and Cost information to employers.
The date range cannot exceed 366 days.
| Parameter | Description |
|---|---|
startDate | Report start date, inclusive, in YYYY-MM-DD format in the US Central time zone. |
endDate | Report end date, exclusive, in YYYY-MM-DD format in the US Central time zone. |
merge | Value is:
|
Get a campaign’s budget and combine the information with the campaign performance report to display the current budget for a job and the cost incurred to date.
To do this pass the campaign creation date in the startDate parameter of this endpoint.
Also pass, merge=true to aggregate the data.
This helps you find what was spent for a campaign from the campaign start date.
The campaign performance data that is returned includes:
- Impressions
- Clicks
- Conversions (Applies)
- Cost
- Currency Code (
USD,GBP, and so on)
Get campaign predictions
| Verb | Endpoint | Reference |
|---|---|---|
POST | /v1/campaignpredictions | Private — Get campaign predictions |
This endpoint:
- Estimates the expected job performance in terms of the number of total job applies for a budget.
- Recommends a budget to sponsor a job based on the desired performance.
For a specific job and its properties, these predictions are based on the past performance of similar jobs at Indeed. It can predict performance of campaign with multiple jobs as well
Predictions are currently available for US (English) jobs only and estimate performance for budgets lower than USD $100 per day. All budget amounts are specified in US dollars (USD).
Predictions are based on the job properties and the type and duration of the campaign.
After the employer accepts the recommended budget, create campaigns with the same parameters.
| Parameter | Description |
|---|---|
mode | Job mode value. Set to |
Request body
| Field | Required | Description | Type |
|---|---|---|---|
body | required | Job, campaign, and prediction information. | CampaignPredictions |
CampaignPredictions
| Field | Required | Description | Type |
|---|---|---|---|
jobInfo | required | Describes a job and its properties. | JobInfo |
campaignInfo | required | Describes the desired campaign type. | CampaignInfo |
predictionsInfo | required | Specifies the desired number of applies or desired budgets for predictions. | PredictionsInfo |
JobInfo
| Field | Required | Description | Type |
|---|---|---|---|
| required | City where the job is located. Example:
| String |
jobsQuery | required | Use Example:
| String |
| required | Source or company for this job. Must exactly match the Example:
| String |
| required | Job title. Example:
| String |
CampaignInfo
| Field | Required | Description | Type |
|---|---|---|---|
| required | Either Example:
| String |
| conditional | Campaign start date, in Example:
| String |
| conditional | Campaign end date, in Example:
| String |
PredictionsInfo
| Field | Required | Description | Type |
|---|---|---|---|
| required | Either Example:
| String |
| conditional | Budget for which to get an estimated performance. Performance is estimated in number of applies. Pass only one number in the array. Required if Example:
| Double array |
| conditional | Desired number of total applies (organic and sponsored) across jobs for which you want a recommended budget. Pass only one number in the array. Required if Example:
| Integer array |
| conditional | Desired number of applies (organic and sponsored) per job for which you want a recommended budget. Pass only one number in the array. Required if Example:
| Integer array |
Response
| Name | Description | Type |
|---|---|---|
currencyCode | Currency code for the budget amounts. Example:
| String |
| The estimated performance or recommended budget overall for all the jobs. | Prediction array |
| Estimated performance or recommended budget for each jobs. | JobLevelPredictions array |
JobLevelPredictions
| Name | Description | Type |
|---|---|---|
job | Job Details | Job Details |
predictions | Estimated performance or recommended budget for a job. | Prediction array |
Job details
| Name | Description | Type |
|---|---|---|
jobKey | Job key. | String |
refNum | Job reference number. | String |
title | Job title. | String |
location | Job location. | String |
Prediction
| Name | Description | Type |
|---|---|---|
budget | For BUDGET_BASED requests, this is the budget that the estimated number of applies is based on. For APPLY_BASED requests, this is the recommended budget to achieve the desired number of total applies. | Double |
organicApplies | For BUDGET_BASED requests, the estimated number of organic applies for the job without sponsoring. Use totalApplies and organicApplies to calculate the estimated number of applies that result from sponsoring the job. | Integer |
totalApplies | For BUDGET_BASED requests, the estimated number of total applies for an organic and sponsored job for a budget value. For APPLY_BASED requests, this is the number of total applies that the recommended budget is based on. | Integer |
estimatedLowerApplies | For BUDGET_BASED requests, the estimated lower range of applies for an organic and sponsored job for a budget value. For APPLY_BASED requests, the response does not include this field. | Integer |
estimatedHigherApplies | For BUDGET_BASED requests, the estimated higher range of applies for an organic and sponsored job for a budget value. For APPLY_BASED requests, the response does not include this field. | Integer |
Example JSON request for prediction
{ "jobInfo": { "jobsLocation": "Austin, TX", "jobsQuery": "refnum:12345", "jobsSourceName": "Bob’s Recruiting", "jobsTitle": "Software Engineer" }, "campaignInfo": { "campaignType": "ONETIME", "startDate": "2021-08-10", "endDate": "2021-08-11" }, "predictionsInfo": { "predictionType": "BUDGET_BASED", "budgets": [75.50] }}Example JSON response for prediction
{ "currencyCode": "USD", "predictions": [{ "predictionType": "BUDGET_BASED", "budget": 151, "organicApplies": 3, "totalApplies": 7, "estimatedLowerApplies": 3, "estimatedHigherApplies": 10 }], "jobLevelPredictions": [{ "job": { "jobKey": "80fdf7e9de72243f", "refNum": "12800649-92-99", "title": "Firmware Engineer", "location": "Irvine" }, "predictions": [{ "predictionType": "BUDGET_BASED", "budget": 75.5, "organicApplies": 2, "totalApplies": 4, "estimatedLowerApplies": 2, "estimatedHigherApplies": 5 }] }, { "job": { "jobKey": "79db86f75cbbde08", "refNum": "12800649-93-100", "title": "Principal Software Engineer", "location": "Irvine" }, "predictions": [{ "predictionType": "BUDGET_BASED", "budget": 75.5, "organicApplies": 1, "totalApplies": 3, "estimatedLowerApplies": 1, "estimatedHigherApplies": 5 }] } ]}Get organic job performance and prediction
| Verb | Endpoint | Reference |
|---|---|---|
POST | /v1/organicjobpredictions |
This endpoint provides:
- The organic traffic statistics of a single job for the past 30 days
- The estimated organic traffic statistics for the next 30 days
- The estimated improvement in traffic if the job is sponsored
The performance is expressed in terms of clicks.
All budget amounts are specified in USD.
To use this endpoint, the employer’s admin user must have an account at Indeed by following the steps in Set up employer account. However, if you do not have billing information set up for sponsoring, you can pass the type=login parameter in the URL to simplify the setup flow.
Organic job performance and prediction request
| Name | Required | Description | Type |
|---|---|---|---|
body | required | Job-related information. | OrganicJobPrediction |
OrganicjobPrediction field
| Name | Required | Description | Type |
|---|---|---|---|
jobInfo | required | Job description, and its properties. | JobInfo |
JobInfo field
| Name | Required | Description | Type |
|---|---|---|---|
jobsQuery | required | The unique reference number that identifies the job, in "refnum:xxxxx” format. Should match the Example:
| String |
jobsSourceName | required | The source or company for this job, in "refnum:xxxxx” format. Should exactly match the Example:
| String |
Organic job performance and prediction response
The response can differ depending on whether the job received traffic or whether sponsoring the job is recommended.
- If the job hasn’t received any traffic in the past 30 days, the value of the
clicksfield within themetricobject is0. - If the job hasn’t existed for 30 days, traffic statistics are returned for the number of days the job existed (but the value of the
daysresponse field is still30). - If the recommendation is not available, the
recommendationfield is not returned.
| Name | Required | Description | Type |
|---|---|---|---|
metric | required | The organic traffic statistics of the given job for the past 30 days. | OrganicMetric |
prediction | required | The estimated organic traffic statistics of the given job for the next 30 days. | OrganicPrediction |
recommendation | optional | If available, the estimated sponsored performance of the given job with a recommended budget. | SponsoredPrediction |
OrganicMetric field
| Name | Description | Type |
|---|---|---|
clicks | Number of clicks the job received in the last n number of days. | Integer |
days | Number of days. Default is 30 days. | Integer |
OrganicPrediction field
| Name | Description | Type |
|---|---|---|
clicks | For the next n number of days, the estimated clicks for the job. | Integer |
days | Number of days. Default is 30 days. | Integer |
SponsoredPrediction field
| Name | Description | Type |
|---|---|---|
clicks | For the next n number of days, the estimated clicks for the job. | Integer |
days | Number of days. Default is 30 days. | Integer |
budget | Recommended budget for sponsoring. | Double |
Example JSON request
{ "jobInfo": { "jobsQuery": "refnum:12345", "jobsSourceName": "Bob’s Recruiting" }}Example JSON response
{ "metric": { "clicks": 30, "days": 30 }, "prediction": { "clicks": 40, "days": 30 }, "recommendation": { "budget": 250.0, "clicks": 70, "days": 30 }}