- Integrate with the Hiring Lab API
- Get an API key
- Authenticate your requests
- Test your integration
- Handle authentication errors
- Hiring Lab API overview
- Key features
- Available datasets
- Get job postings data
- Regional job postings data
- Sectoral job postings data
- Get remote work data
- Get wage growth data
- Get AI job postings data
- List available data coverage
- List countries with data coverage
- List available sectors
- List available geographies
- List available regions
- List all datasets
- Pagination
- Troubleshoot errors
- Hiring Lab API FAQs
Hiring Lab API
Access Indeed Hiring Lab labor market data for analysis and research.
By using this API and its documentation and building an integration, you agree to the Indeed's terms of service.
Integrate with the Hiring Lab API
To integrate with the Hiring Lab API, get an API key for authentication.
Get an API key
Indeed issues API keys to partners and researchers who need access to Hiring Lab data.
To request an API key:
- Email hiring-lab-api@indeed.com with your use case and organization details.
- Indeed reviews your request and provisions an API key.
- Indeed sends the API key to you by email.
Store your API key securely. Do not embed the key in client-side code or commit it to version control.
Authenticate your requests
Include your API key in the Indeed-API-Key header on every GraphQL request to the Hiring Lab API:
curl -X POST 'https://apis.indeed.com/graphql' \ -H 'Content-Type: application/json' \ -H 'Indeed-API-Key: YOUR_API_KEY' \ --data-raw '{ "query": "query { findHiringLabPostingsPublic(first: 10, input: { filter: { country: [\"US\"] } }) { edges { node { ... on HiringLabNationalPosting { date indexSa } } } } }" }'Replace YOUR_API_KEY with your API key.
Add a Referer header
Include a Referer header in your requests so security filters do not block them. The header identifies the domain that makes the API call:
curl -X POST 'https://apis.indeed.com/graphql' \ -H 'Content-Type: application/json' \ -H 'Indeed-API-Key: YOUR_API_KEY' \ -H 'Referer: https://your-domain.com' \ --data-raw '{ "query": "query { findHiringLabPostingsPublic(first: 10, input: { filter: { country: [\"US\"] } }) { edges { node { ... on HiringLabNationalPosting { date indexSa } } } } }" }'Replace https://your-domain.com with your domain or service identifier.
Test your integration
Test your API key with a simple query:
curl -X POST 'https://apis.indeed.com/graphql' \ -H 'Content-Type: application/json' \ -H 'Indeed-API-Key: YOUR_API_KEY' \ -H 'Referer: https://your-domain.com' \ --data-raw '{ "query": "query { findHiringLabPostingsPublic(first: 5, input: { filter: { country: [\"US\"], postingType: TOTAL } }) { edges { node { ... on HiringLabNationalPosting { id date country { countryCode countryName } postingType indexSa indexNsa } } cursor } pageInfo { hasNextPage } } }" }'A successful response returns job postings data:
{ "data": { "findHiringLabPostingsPublic": { "edges": [{ "node": { "id": "...", "date": "2024-10-01", "country": { "countryCode": "US", "countryName": "United States" }, "postingType": "TOTAL", "indexSa": 102.5, "indexNsa": 103.2 }, "cursor": "..." }], "pageInfo": { "hasNextPage": true } } }}Handle authentication errors
If your API key is missing or invalid, Indeed returns a 401 Unauthorized error.
If your request does not include a Referer header, security filters might block the request. Include a Referer header that identifies your domain or service.
If you call APIs outside the Hiring Lab scope, Indeed returns a FORBIDDEN error:
{ "errors": [{ "message": "The client doesn't have access to any requested field from '[API NAME]'.", "extensions": { "code": "FORBIDDEN" } }], "data": { "[value]": null }}Confirm that your query uses only Hiring Lab API queries: findHiringLabPostingsPublic, findHiringLabRemotePublic, findHiringLabWagesPublic, findHiringLabAiPublic, and related metadata queries.
Hiring Lab API overview
Use the Hiring Lab API to access data that Indeed Hiring Lab publishes at data.indeed.com. The API serves comprehensive labor market data, including job posting trends, wage growth, remote work patterns, and AI-related job opportunities.
Researchers, policymakers, economists, and analysts can call the Hiring Lab API to gather reliable labor market data. The Hiring Lab API offers data at different granularities and frequencies, depending on the dataset.
Key features
- Comprehensive coverage: Reach multiple countries and regions.
- Multiple granularities: Get national, regional, and sectoral data.
- Real-time updates: Receive daily and monthly data updates.
- Cursor-based pagination: Page through large datasets efficiently.
- Public and private data: Choose access levels based on authentication.
Available datasets
The Hiring Lab API provides access to these core datasets:
| Dataset | Description | Granularity | Frequency | |||
|---|---|---|---|---|---|---|
| National | Regional | Sectoral | Daily | Monthly | ||
| Job Postings | Job postings indices by seasonal adjustment | ✔ | ✔ | ✔ | ✔ | |
| Remote Work | Remote and hybrid job postings and searches | ✔ | ✔ | ✔ | ||
| Wage Growth | Year-over-year wage growth from job postings | ✔ | ✔ | ✔ | ||
| AI Jobs | AI-related job postings, including generative AI | ✔ | ✔ | |||
Get job postings data
To get job postings index data, call the findHiringLabPostingsPublic query:
query { findHiringLabPostingsPublic(first: 50, input: { filter: { country: ["US"], postingType: TOTAL } }) { edges { node { ...on HiringLabNationalPosting { id date country { countryCode countryName } postingType indexSa indexNsa } } cursor } pageInfo { hasNextPage hasPreviousPage startCursor endCursor } }}Regional job postings data
To get regional job postings data, call the same query and filter by geography and region:
query { findHiringLabPostingsPublic(input: { filter: { country: ["US"], geography: STATES, region: ["California", "Texas"] } }) { edges { node { ...on HiringLabRegionalPosting { date country { countryCode countryName } region { regionCode regionName } geography { geography } indexSa indexNsa } } } }}Sectoral job postings data
To get job postings data by sector:
query { findHiringLabPostingsPublic(input: { filter: { country: ["US"], sector: ["Technology", "Healthcare"] } }) { edges { node { ...on HiringLabSectoralPosting { date country { countryCode countryName } sector { sectorCode sectorName } indexSa indexNsa } } } }}Get remote work data
To access remote work trends, call the findHiringLabRemotePublic query:
query { findHiringLabRemotePublic(input: { filter: { country: ["US"], metric: POSTINGS } }) { edges { node { ...on HiringLabNationalRemote { date country { countryCode countryName } metric remoteShare } } } }}The remoteShare field returns the percentage of job postings that are remote or hybrid. To filter by POSTINGS or SEARCHES, include the metric parameter.
Get wage growth data
To get wage growth information, call the findHiringLabWagesPublic query:
query { findHiringLabWagesPublic(input: { filter: { country: ["US"] } }) { edges { node { ...on HiringLabNationalWage { date country { countryCode countryName } wageGrowthYoy wageGrowth3Ma } } } }}The response includes:
wageGrowthYoy: Year-over-year change in posted wageswageGrowth3ma: 3-month lagged moving average of year-over-year change
Get AI job postings data
Use the findHiringLabAiPublic query to access AI-related job trends:
query { findHiringLabAiPublic(input: { filter: { country: ["US"] } }) { edges { node { ...on HiringLabNationalAI { date country { countryCode countryName } aiShare } } } }}The response includes aiShare, the percentage share of AI-related job postings.
List available data coverage
List countries with data coverage
query { findHiringLabCountriesPublic(input: { filter: { datasetId: "job_postings", granularity: NATIONAL } }) { results { countryCode countryName } }}List available sectors
query { findHiringLabSectorsPublic(input: { filter: { datasetId: "job_postings", country: "US" } }) { results { sectorCode sectorName } }}List available geographies
query { findHiringLabGeographiesPublic(input: { filter: { datasetId: "job_postings", country: "US" } }) { results { geography } }}List available regions
query { findHiringLabRegionsPublic(input: { filter: { datasetId: "job_postings", country: "US", geography: STATES } }) { results { regionCode regionName } }}List all datasets
query { allHiringLabDatasetsPublic { results { id name description granularity frequency } }}Pagination
The Hiring Lab API uses cursor-based pagination to page through large datasets efficiently. Set the first parameter to the number of results per page (maximum 50), and pass a cursor value in the after parameter to get the next page:
query { findHiringLabPostingsPublic(first: 50, after: "cursor_value_from_previous_response", input: { filter: { country: ["US"] } }) { edges { node { #...your fields } cursor } pageInfo { hasNextPage hasPreviousPage startCursor endCursor } }}Troubleshoot errors
For OAuth errors that occur before you reach GraphQL, see Troubleshoot OAuth errors.
For GraphQL errors, see Troubleshoot GraphQL errors.
For Hiring Lab API term definitions, see Hiring Lab API glossary.
Hiring Lab API FAQs
Every job postings index uses February 1, 2020 as the baseline (= 100). This baseline keeps comparisons consistent across countries and time periods.
Seasonally adjusted (SA) indices remove typical seasonal patterns to reveal underlying trends. Non-seasonally adjusted (NSA) indices show raw data, including normal seasonal fluctuations such as holiday hiring.
- Indeed updates job postings and remote work data daily.
- Indeed updates wage growth data monthly.
- Indeed updates AI job postings data daily.
Coverage varies by dataset. Use the findHiringLabCountriesPublic query to see the available countries for each dataset and granularity level.
To get historical data, use cursor-based pagination. Start with your filters, then use the after parameter and the cursor values from previous responses to page through the results.
The maximum is 50 results per request. Use pagination to retrieve larger datasets.
The API returns data in chronological order. Use pagination and the date field in your application logic to filter to your desired time range.