Indeed Jobs Scraper - Companies, Reviews, Salaries
Pricing
from $3.00 / 1,000 jobs
Indeed Jobs Scraper - Companies, Reviews, Salaries
Jobs and the employers behind them, in one run. Full descriptions, parsed salaries, company profiles, employee reviews, salary tables and Q&A — joined on Indeed's own employer id, not on company name. 62 countries, no login, pay per result. Only-new mode returns just what changed.
Pricing
from $3.00 / 1,000 jobs
Rating
0.0
(0)
Developer
Richard Feng
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Indeed Scraper — Jobs, Employers, Reviews, Salaries & Q&A
Indeed Scraper extracts job listings from Indeed with full descriptions and parsed salaries — and, in the same run, the employers behind them: company profiles, employee reviews, salary tables and community Q&A, joined on Indeed's own employer id. 62 country domains, no login required, pay per result.
Most Indeed actors do one side or the other. This one runs a keyword search and hands back the employers that search discovered, already linked to their postings.
What does Indeed Scraper do?
Type a job title and a location, press Start, and get structured job data back — or
paste an Indeed URL and it works out what you meant. It accepts a /jobs search with your
filters already in the query string, a /viewjob posting, a /cmp/… company page or tab,
or a /career/… salary page.
Switch on includeCompanyDetails and every employer the search found comes back too, with
whichever of profile, reviews, salaries and qna you ask for.
What data can I extract from Indeed?
| 🧑💼 Job title & normalized title | 🏢 Company profile, size & revenue |
| 📃 Full job description (HTML + text) | ⭐️ Employee reviews & category ratings |
| 💵 Parsed salary range & period | 💰 Salary tables by role and employer |
| 📍 City, state, postcode & remote status | ❓ Community questions & top answers |
| 🎁 Benefits, requirements & shift tags | 👔 CEO, HQ, founding year & website |
| 🕐 Posting date & expiry | 📧 Employer contact address (optional) |
Why use this scraper?
- Both sides of Indeed in one run. Jobs and the employers behind them — profiles, reviews, salary tables, Q&A — joined on Indeed's own employer id, not on company name.
- Every filter is verified, not assumed. Indeed silently ignores URL parameters it does not recognise, so each filter here was measured against a deliberate control before being shipped. Controls that turned out to do nothing were removed rather than left in place looking like they worked.
- Published coverage numbers. On a search Indeed reported as 2,676 postings: 737 unique jobs in 41 requests paging alone, 1,388 in 369 requests with widening on. Every run logs what it actually collected against what Indeed claimed.
- Full descriptions at the base rate. Job text is fetched in batches of 40, so it is included rather than sold as a per-job add-on.
- Widening that respects your query. A broad search is re-run as narrower slices — by location, date, job type, pay and education — and slices that are still too large are split again. A search you already scoped to a city is never silently widened.
- Scheduled monitoring. Remember what previous runs returned and receive only new postings. Skipped jobs cost no requests and no charge.
- Strict matching. Indeed pads every result page with loosely-related and sponsored postings. Drop them — judged against the full description, not the snippet.
- 62 country domains, with currency, locale, and miles or kilometres handled for you.
- Clean output.
source.canonicalUrlis always the public page a person would open. The endpoints the actor fetches internally, and Indeed's tracking fields, never reach your data.
Use cases
- Recruitment & talent intelligence — see who is hiring for which roles, at what pay, in which markets, and what their employees say about working there.
- Salary benchmarking — parsed pay per posting, plus company-level and national salary tables by job title and location.
- Market & competitor research — an employer's open headcount, ratings, size, revenue and hiring velocity, refreshed on a schedule you control.
- Job boards & aggregators — a clean feed filtered to what actually matches, delivering only what is new since your last run.
- Lead generation — every posting is a company spending money to hire, with optional business contact details from the employer's own website.
- Candidate matching — score every posting 0-100 against a skill list and see which skills are missing.
How do I use Indeed Scraper?
- Create a free Apify account.
- Open the actor and enter a job title under Positions / keywords and a Location.
- Optionally narrow with date posted, job type, remote, pay or education — or switch on Include company details to get the employers as well.
- Click Start and wait for the run to finish.
- Download the data as JSON, CSV, Excel, XML or HTML, or pull it from the API.
Leave the location empty to search a whole country. Residential proxies are strongly recommended — Indeed challenges most datacenter traffic.
Input
Everything is optional except giving the actor something to search — keywords,
startUrls, jobKeys, companyUrls or salaryJobTitles.
| Parameter | Type | Description |
|---|---|---|
scrapeMode | String | What this run does: jobs (keyword search, the default), company (employer pages from companyUrls), or careerSalary (national pay tables). Fields belonging to the other modes are ignored, and the log says what it skipped. |
keywords | Array | Job titles, skills or company names. Each is searched separately. |
location | String | City, state, ZIP or region. Leave empty to search a whole country. |
country | String | Which Indeed country site to search (default US). 62 supported. |
startUrls | Array | Any Indeed URL: a /jobs search with filters, a /viewjob posting, a /cmp/… company page or tab, or a /career/… salary page. |
jobKeys | Array | Look jobs up directly by Indeed job key (the jk value in a job URL). |
datePosted | String | 1, 3, 7 or 14 days. |
jobType | Array | fulltime, parttime, contract, temporary, internship, permanent, new_grad, commission. Indeed takes one type per search, so picking several runs one search per type and widens the result set. |
remoteWork | String | remote or hybrid. Indeed filters remote itself; it has no working hybrid filter, so hybrid is applied to the results and reads more pages for the same number of rows. |
education | String | high_school_degree … doctoral_degree. |
salaryMin | Integer | Annual pay threshold, in the country's currency. |
onlyWithSalary | Boolean | Keep only postings that state or estimate pay. |
radius / radiusUnit | Integer / String | Search radius, in miles or km. |
sort | String | relevance or date. |
maxItems | Integer | Total jobs to return (default 100). |
fanOut | Boolean | Re-run broad searches as narrower slices (default true). |
maxFanOutRequests | Integer | Budget for that widening. |
deepSearch | Boolean | Expand each keyword into related phrasings. |
strictMatch | Boolean | Drop postings that do not contain your keywords. |
uniqueCompanies | Boolean | At most one posting per employer. |
resumeKeywords | Array | Score every posting 0-100 against a skill list. Not a filter. |
storeName | String | Remember what this search returned, for scheduled runs. |
onlyNewJobs | Boolean | Return only postings no earlier run returned. Needs storeName. |
includeDescription | Boolean | Full job text, batched (default true). |
includeJobDetail | Boolean | Extra per-job fetch for benefits and qualifications. |
includeCompanyDetails | Boolean | Add the employer's Indeed profile. |
companyDataTypes | Array | profile, reviews, salaries, qna. |
enrichEmails | Boolean | Read each employer's own site for a business contact address. |
companyUrls | Array | Scrape employers directly, without a job search. |
salaryJobTitles | Array | National salary tables by role. |
salaryLocations | Array | Restrict those salary tables to given locations. |
maxReviews / maxQuestions | Integer | Cap review and Q&A rows per employer. |
sessionCookies | String | Cookies from a browser already signed in to Indeed. Never asks for a password. |
proxyConfiguration | Object | Residential proxies are strongly recommended. |
Input examples
| Use case | Input JSON |
|---|---|
| Jobs by keyword and location | { "keywords": ["registered nurse"], "location": "Texas", "maxItems": 200 } |
| Search a different country | { "keywords": ["software engineer"], "location": "London", "country": "GB" } |
| Only recent, full-time, remote | { "keywords": ["data analyst"], "datePosted": "3", "jobType": ["fulltime"], "remoteWork": "remote" } |
| Several employment types at once | { "keywords": ["welder"], "location": "Houston, TX", "jobType": ["fulltime", "contract", "temporary"] } |
| Roles above a salary | { "keywords": ["product manager"], "location": "Seattle, WA", "salaryMin": 150000 } |
| Only postings that state pay | { "keywords": ["warehouse associate"], "location": "Dallas, TX", "onlyWithSalary": true } |
| Clean, relevant results only | { "keywords": ["registered nurse"], "location": "Texas", "strictMatch": true, "uniqueCompanies": true } |
| Score jobs against a CV | { "keywords": ["backend engineer"], "resumeKeywords": ["Python", "Kubernetes", "PostgreSQL"] } |
| Go wide on a national search | { "keywords": ["nurse"], "location": "", "fanOut": true, "maxFanOutRequests": 40, "maxItems": 2000 } |
| Widen a narrow keyword | { "keywords": ["software engineer"], "location": "Austin, TX", "deepSearch": true, "maxItems": 500 } |
| Daily monitor — only new jobs | { "keywords": ["python developer"], "location": "Denver, CO", "storeName": "python-denver", "onlyNewJobs": true } |
| Jobs plus employer profiles | { "keywords": ["data engineer"], "location": "Chicago, IL", "includeCompanyDetails": true } |
| Everything about employers | { "keywords": ["dentist"], "location": "Phoenix, AZ", "includeCompanyDetails": true, "companyDataTypes": ["profile", "reviews", "salaries", "qna"] } |
| Employers only, no job search | { "scrapeMode": "company", "companyUrls": [{ "url": "https://www.indeed.com/cmp/Google" }], "companyDataTypes": ["profile", "reviews"], "maxReviews": 200 } |
| Employers alongside a job search | { "keywords": ["data engineer"], "location": "Chicago, IL", "includeCompanyDetails": true } |
| National salary tables | { "scrapeMode": "careerSalary", "salaryJobTitles": ["software engineer", "registered nurse"], "salaryLocations": ["New York, NY"] } |
| Sales leads with contacts | { "keywords": ["hvac technician"], "location": "Tampa, FL", "includeCompanyDetails": true, "enrichEmails": true } |
| Paste an Indeed URL | { "startUrls": [{ "url": "https://www.indeed.com/jobs?q=nurse&l=Austin%2C+TX&fromage=3" }] } |
Output
Data is stored in the default dataset. Five record types share it, told apart by
recordType, each with its own view in the Console: Jobs, Companies, Reviews,
Salaries and Q&A.
source.canonicalUrl is always the public Indeed page a person would open. The endpoints
the actor fetches internally, and Indeed's tracking fields, never appear in your data.
Jobs join to companies on company.fccId = the company record's source.encryptedFccId.
How many results can I scrape?
Indeed limits how deep any single search can go. Paging alone reaches roughly 700-1,000 distinct postings per search, after which Indeed recycles results rather than serving new ones. Measured on a search Indeed reported as 2,676 postings:
| Requests | Unique jobs | Of Indeed's count | |
|---|---|---|---|
| Paging only | 41 | 737 | 27.5% |
With fanOut on | 369 | 1,388 | 51.8% |
Widening is not free: paging returns about 18 new jobs per request, widening about 1.8,
because slices overlap on purpose and duplicates are dropped. That is why fanOut is a
switch with a budget rather than something the actor does behind your back. To go wider
still, add deepSearch, or split the search yourself by location or date and run it more
than once.
Every run reports what it actually collected, so a capped run is never presented as complete:
Coverage [software engineer | fromage=14]: harvested 198 of 442 reported (44.8%)Coverage (run): 1388 unique jobs of 2677 reported across all root queries — 51.8%
Indeed's own total is a live estimate — repeating one query minutes apart returns different totals — so an occasional figure above 100% means jobs were posted while the run was in flight, not that something is broken.
How much does it cost?
This actor uses Apify's pay-per-event model: you are charged for the results it produces, not for how long it runs.
| Event | Charged | Notes |
|---|---|---|
search-request | Once per search page fetched | Billed before filtering, because the search costs the same to run either way. This is what keeps strict matching, one-job-per-company and only-new-jobs free to use. |
job-scraped | Once per job saved | The main unit of value. The full description is included — it is fetched in batches, not per job. |
job-detail-scraped | Once per job, only when includeJobDetail is on | Adds an extra fetch per job for benefits, qualifications and attributes. |
company-scraped | Once per employer profile saved | |
contact-enriched | Once per employer that actually yields a contact address | Employers whose site publishes no address are never billed for it. |
review-scraped | Once per review saved | |
salary-scraped | Once per salary row saved | |
qna-scraped | Once per question saved |
Controlling your spend
maxItemscaps how many jobs are saved, and therefore how manyjob-scrapedevents are charged. Default100.maxReviewsandmaxQuestionscap the per-employer review and Q&A rows the same way.- Max total charge (set per run or per task) is a hard ceiling. When it is reached the actor stops of its own accord and finishes with everything already saved.
- Duplicates are never billed twice. A job reached through several keywords, filters or overlapping searches is saved and charged once per run.
onlyNewJobsstops you paying twice across runs: postings an earlier run already returned are skipped before any request is made.
Supported countries
62 Indeed country domains, including the United States, United Kingdom, Canada, Australia,
Ireland, India, Germany, France, Spain, Italy, Netherlands, Poland, Sweden, Brazil, Mexico,
Japan, Singapore and South Africa. Set country to the two-letter code; currency, locale
and distance units follow.
Using a signed-in session (optional)
Indeed keeps desktop search pagination behind a sign-in. Everything else this actor does works signed out, which is the default — but if you want the desktop pages, paste cookies from a browser you are already logged in with:
{ "keywords": ["nurse"], "location": "Austin, TX","sessionCookies": "CTK=…; SESSION_ID=…" }
Either the raw Cookie: header or a JSON array of {name, value} works, so a cookie
export extension's output can be pasted straight in.
- No password is ever requested or handled. You supply a session you already have.
- Cookies go to indeed.com and nowhere else. Employer-website enrichment fetches third-party domains, and those requests carry no Indeed session.
- Values are never logged or written to the dataset — the run log names the cookies it received and nothing more.
- An expired session degrades, it does not fail. Indeed answers a signed-out desktop request with a challenge rather than a readable sign-in page, so the actor detects the failure once, says so, and continues on the signed-out surface for the rest of the run.
FAQ
Does Indeed have an API I can use instead? Indeed's developer APIs are aimed at the hiring side — applicant tracking, conversions, interview scheduling. The Publisher Jobs API that served job search was deprecated, which is why a scraper is the practical route to this data.
Do I need an Indeed account? No. Everything above runs signed out. A session is optional and only unlocks desktop search pagination.
Why do I get fewer jobs than Indeed's result count? Indeed will not page a single query past roughly 1,000 results. See How many results can I scrape? — the run log tells you exactly what was collected.
Can I get interview questions?
Yes, in the Q&A records. Indeed has no separate interviews dataset — /cmp/{slug}/interviews
renders the company profile, and interview content is published as community Q&A, so that
tab is routed there.
Can I filter by experience level?
No. Indeed's experience-level URL parameter does not change the result set — measured
against a control — and search results carry no experience field to filter on afterwards.
Rather than ship a control that quietly does nothing, this actor does not have one. Use
keywords ("senior data analyst") or strictMatch instead.
Why is there no external apply URL?
Indeed publishes only a tracking redirect for off-site applications, and that chain cannot
be resolved outside a real browser click — it returns 404 even on the session that issued
it. apply.isIndeedApply tells you which kind of application a posting uses.
Can I run this on a schedule?
Yes. Set storeName and onlyNewJobs and each run returns only postings earlier runs did
not, without spending requests on the ones it already sent you.
Is it legal to scrape Indeed? This actor collects publicly available job listings and employer pages — the same pages any visitor can open without signing in. Web scraping is legal in many jurisdictions when it is limited to public data, but how you use what you collect is your responsibility, and personal data carries obligations under the GDPR, the CCPA and their equivalents. If your use case touches personal data or you are unsure, take legal advice.
Not supported
- Résumés —
resumes.indeed.comis not supported. This is a choice, not a technical limit: those pages carry job seekers' names, locations, employers, education and work history, and bulk-collecting identifiable personal data about private individuals into a redistributable dataset is a different activity from scraping employers' public job ads. Reachability is beside the point — the objection is to the collection, not to the difficulty. - Anything requiring a signed-in job seeker's own account — saved jobs, messages, application status.
Troubleshooting
- Blocked or challenged runs — use residential proxies. Indeed challenges most datacenter traffic. Lowering
maxConcurrencyalso helps. - Contact emails mostly empty — expected. Measured across 11 employers: 5 listed a website at all, and 1 of those 5 published an address. Indeed lists a website only for claimed employer profiles, and most corporate sites use a contact form instead of publishing an address.
onlyNewJobsreturned nothing — the search found nothing new since the last run. That is the feature working. Clear the store, changestoreName, or lowerseenRetentionDaysto see repeats again.- A company was skipped with
includeCompanyDetails— employer slugs are derived from company names when a search result carries no company link, which can miss where Indeed disambiguated similar names.
Feedback
Found a field that should be there, a filter that misbehaves, or a country that does not resolve? Open an issue on the actor page — bug reports with the input JSON that produced them get fixed fastest.