Scrape Indeed job postings with salary and company data
Last updated
Indeed is the board to start with when you need job listings in bulk. Datapika's job board scraper on Apify reads Indeed's public search pages with no API key or login, returns each posting as a structured row with salary range, company size, revenue, rating and full description, and streams the first Indeed rows into your dataset 5 to 20 seconds after the run starts. Set countryIndeed to target any supported Indeed country site. You pay $0.005 for each job delivered, which puts 1,000 Indeed listings at $5. The scraper has 27,458 runs, 2,471 users and a 5.0 rating.
What fields does an Indeed job scraper return?
Every Indeed posting becomes one dataset row, and the sample row in the actor's documentation is an Indeed posting, which shows how much of the schema Indeed fills in. The salary block carries salary_min, salary_max, salary_currency and salary_interval, plus a salary_source flag that tells you whether the range came from Indeed's own structured pay data or was parsed out of the description text; set enforceAnnualSalary to convert hourly and monthly figures to yearly equivalents before you compare roles. The company block is where Indeed stands out: employee count with a readable label such as 1001-5000, revenue with a label such as $1B+, an employer rating with its review count, industry, country, logo URL and a short description. In that sample, an Indeed row for a Senior Software Engineer at JPMorganChase shows a 120,000 to 185,000 USD yearly range, a 3.9 rating from 21,432 reviews and a 10,000+ headcount. The full description arrives by default in Markdown, or HTML if you set descriptionFormat, and any email addresses found in it are extracted into a separate emails field.
- salary_min, salary_max, salary_currency, salary_interval and salary_source (direct_data or description)
- company_num_employees and company_revenue, each with a human-readable label field
- company_rating, company_reviews_count, company_industry, company_country, company_logo and company_description
- job_url to the Indeed listing plus job_url_direct to the employer's own careers page when Indeed exposes it
- description in Markdown or HTML without a separate fetch switch (LinkedIn needs linkedinFetchDescription for the same field)
- emails extracted from the description text, useful for recruiter contact
How do you set the Indeed country for a search?
Indeed runs a separate site for each country, and the scraper picks which one to query through the countryIndeed input. It defaults to usa; the documented codes include uk, canada, australia, germany, france, india, singapore and uae, and most other Indeed country sites are accepted as well. The location field then narrows results inside that country, so a run with countryIndeed set to uk and location set to Manchester returns Manchester postings from Indeed's UK site. Leaving countryIndeed on the default while typing a London location is the most common configuration mistake: the scraper dutifully asks the US site for London jobs, so check the country before you blame the query. The same value also drives Glassdoor's country targeting, so a UK run that includes both boards needs only one setting. Pair the country with distance, which defaults to a 50-mile radius, to control how far outside the named city the search reaches, and turn on enforceAnnualSalary when you plan to compare pay across countries with different salary conventions.
- countryIndeed defaults to usa and accepts codes such as uk, canada, australia, germany, france, india, singapore and uae
- location narrows inside the chosen country: a city, a region or the word Remote
- distance sets the search radius in miles, default 50
- One countryIndeed value targets both Indeed and Glassdoor in the same run
- salary_currency accompanies each salary range, so mixed-country datasets stay comparable
- Pick the country first, then the location; the country chooses the site and the location narrows within it
What are Indeed's quirks compared with the other boards?
Indeed is the only board in the actor's site notes flagged as having no rate limiting, which is why those notes call it the best choice for large scrapes. It also skips the stealth browser, so its rows land in the dataset 5 to 20 seconds after the run starts, while Glassdoor, ZipRecruiter, Bayt and Naukri are fetched through a real browser and typically take 1 to 3 minutes. Three limits are worth knowing. First, Indeed cannot combine hoursOld with jobType, isRemote or easyApply in one search; if you set both, the run returns fewer rows than expected, so filter by recency in one run and by role type in another, or post-filter the dataset. Second, date_posted is a calendar date with no time of day, so a 24-hour window is day-precise rather than hour-precise. Third, job_level is a LinkedIn field and comes back null on Indeed rows, so use title keywords for seniority instead. A listing_type field flags sponsored placements, which lets you separate paid promotion from organic postings when you count who is hiring.
- No rate limiting on Indeed, so large maxResults values and repeated scheduled runs are fine
- No stealth browser step: first Indeed rows in 5 to 20 seconds, not minutes
- hoursOld cannot be combined with jobType, isRemote or easyApply on Indeed
- date_posted is day-precise (YYYY-MM-DD), not an hour-level timestamp
- job_level is null on Indeed rows; skills and experience_range are Naukri-only
- listing_type marks sponsored listings
How do you scrape Indeed jobs at volume?
A single run returns up to maxResults rows per board per search term, with maxResults capped at 100 and searchTerms capped at 5, so an Indeed-only run tops out at 500 rows before deduplication. To go beyond that, page with the offset input, which skips the first N results, or split the job across locations, job types and countries and let Apify schedules run the pieces. Each row carries matched_search_term, so a multi-term OR search such as data engineer, analytics engineer and ETL developer stays traceable after the results are merged. For a daily feed, keep hoursOld at 24 and run once a day; because you pay only for rows delivered, a morning that turns up nothing costs no result events. Runs default to 4 GB of memory, which matters mainly when browser-based boards are included; an Indeed-only run is light. Cap each run with a maximum total charge in the Apify Console as a hard budget, and keep maxResults at the default of 20 while you tune the query before raising it to 100.
- maxResults up to 100 per term and searchTerms up to 5: 500 Indeed rows per run before dedup
- offset skips the first N results for pagination across repeated runs
- matched_search_term tags every row with the query that found it
- hoursOld 24 plus a daily schedule gives a fresh-postings feed
- Zero-result runs produce no result events, only Apify's small start fee
- A maximum total charge on the run caps spend before it starts
How do you call the Indeed scraper from code or an AI agent?
The actor has three entry points. In the Apify Console you fill the form, run it and download the dataset as JSON, CSV, Excel, XML, HTML or RSS from the Output tab. From code, POST your input to the runs endpoint for openclawai~job-board-scraper, or call run-sync-get-dataset-items to get the rows back in one synchronous request; the Python and JavaScript clients wrap the same calls behind client.actor("openclawai/job-board-scraper").call(). For agents, register the scraper as an MCP tool via mcp.apify.com, and a Claude, ChatGPT or Cursor session can ask for remote data analyst jobs on Indeed posted in the last day and reason over the structured rows directly. Zapier, Make and n8n can run the scraper on a schedule and push new rows to Google Sheets, Airtable, Slack or a CRM, and a webhook can kick off downstream processing when a run finishes. When one board is not enough, the same input can sweep LinkedIn, Glassdoor, ZipRecruiter, Naukri and Bayt in the same run with cross-board deduplication; the full board list is at datapika.com/scrape.
- Console export: JSON, CSV, Excel, XML, HTML table or RSS
- REST: POST to /v2/acts/openclawai~job-board-scraper/runs, or run-sync-get-dataset-items for a single call
- Python and Node clients: pip install apify-client or npm i apify-client
- MCP: https://mcp.apify.com/?tools=fetch-actor-details,openclawai/job-board-scraper
- Zapier, Make and n8n schedules, plus webhooks on run completion
| Field | Populated on Indeed? | Notes |
|---|---|---|
| id, title, company, location, site | Yes | id is the board's job ID (in-7f3a2c9e1b in the sample); site is indeed |
| job_url, job_url_direct | Yes / when available | indeed.com/viewjob link, plus the employer careers page (careers.jpmorgan.com in the sample) |
| date_posted | Yes | Calendar date only (YYYY-MM-DD), no time of day |
| job_type, is_remote, listing_type | Yes | fulltime, parttime, contract, internship or temporary; remote flag; sponsored marker |
| job_level | No | LinkedIn-only seniority field, null on Indeed rows |
| salary_min, salary_max, salary_currency, salary_interval, salary_source | Yes | yearly, monthly or hourly; direct_data from Indeed's pay field or description when parsed; enforceAnnualSalary normalizes to yearly |
| company_industry, company_country | Yes | company_country is documented as an Indeed field |
| company_num_employees, company_revenue (plus label fields) | Yes | Labels such as 1001-5000 and $1B+ |
| company_rating, company_reviews_count | Yes | Employer rating with review count, 3.9 from 21,432 reviews in the sample |
| company_logo, company_description, company_url | Yes | Logo URL, short employer blurb, profile page on Indeed |
| description, emails | Yes | Full text in Markdown or HTML; emails parsed from it |
| skills, experience_range, vacancy_count, work_from_home_type | No | Naukri-only fields |
How to do it
- 1.Open apify.com/openclawai/job-board-scraper, enter a searchTerm such as data analyst (or up to 5 searchTerms) and a location.
- 2.Set sites to indeed only, set countryIndeed to the country whose Indeed site you want (usa, uk, canada, india and so on) and choose maxResults up to 100.
- 3.Add filters: either hoursOld for recency, or jobType, isRemote and easyApply for role type, but not both together on Indeed. Turn on enforceAnnualSalary if you will compare pay.
- 4.Run it; Indeed rows appear within 5 to 20 seconds. Export from the Output tab or read the dataset through the API or MCP.
Questions, answered
Does Indeed have an official API?
Not for reading job postings. Indeed's Publisher Job Search API was shut down, its old developer.indeed.com documentation now redirects to partners.indeed.com, and the APIs Indeed documents today, such as the GraphQL Job Sync API, exist for approved ATS partners to push their own postings into Indeed rather than to search listings. There is no self-serve key to apply for. Datapika reads the public search pages instead and returns the same fields you see in a browser.
What does it cost to pull 1,000 Indeed jobs?
One thousand Indeed rows cost $5, billed per delivered job at $0.005 on a pay-per-event basis. Rows removed by deduplication never reach your dataset, so they are not charged, and a run that returns nothing costs only Apify's small start fee. Apify's free plan includes $5 of monthly credit, roughly enough for 1,000 jobs, and a maximum total charge set on the run caps spend before it starts.
Why does Indeed return fewer jobs than maxResults?
Usually one of three things. Indeed cannot combine hoursOld with jobType, isRemote or easyApply in the same search, so that combination silently narrows results; run recency and role-type filters separately. Duplicates are removed when the same posting appears on several boards in a multi-board run. Or the country and location disagree, such as a London location on the default usa site. Widen the radius or drop hoursOld to check.
Can I scrape Indeed jobs from the UK, Canada, India or other countries?
Yes. Set countryIndeed to the country code for the Indeed site you want; usa is the default, uk, canada, australia, germany, france, india, singapore and uae are documented codes, and most other Indeed country sites are accepted too. Then put a city or region in location. For India-specific fields such as skills and experience_range, add Naukri to the same run alongside Indeed.
How fresh are Indeed postings, and can I watch when a specific company starts hiring?
Indeed exposes a posting date, not a time, so hoursOld set to 24 gives you a day-precise window; run it daily to keep a rolling feed of new listings. For a company-by-company view, the hiring signals use case uses the companion Indeed and ZipRecruiter scraper, which takes a list of employers and reports which ones posted in the last 48 hours, with the titles and pay ranges attached.
Keep reading
Comparisons
Indeed API alternatives for job data (2026)
Comparisons
Best Indeed scrapers 2026: 7 actors priced per 1,000
Scrape guides
Scrape LinkedIn Jobs Without Login, Cookies, or an API
Scrape guides
Scrape Glassdoor jobs with salary bands, no API key
Use cases
Hiring signals API: who is hiring, at $0.0005 per company