Indeed Scraper - Jobs, Salaries & Companies USA
Pricing
Pay per event
Indeed Scraper - Jobs, Salaries & Companies USA
Scrape Indeed.com US jobs: title, company, parsed salary, remote flag, location, skills. 30+ fields per job, HTTP-only. Filter by keyword, location, remote, salary minimum.
Pricing
Pay per event
Rating
0.0
(0)
Developer
deusex machine
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
5 days ago
Last modified
Categories
Share
Indeed Scraper API — Jobs, Salaries, Companies & Skills Data USA
A high-performance Indeed scraper that extracts complete job listings from Indeed.com, the most-visited job portal in the United States with 350M+ monthly visits and 24M+ active postings across every industry — IT, healthcare, finance, manufacturing, retail, hospitality and the public sector. Pull 30+ structured fields per job in seconds, with salary automatically parsed to numbers, remote flag detected, posting date normalized to ISO 8601, plus full job description from the schema.org JobPosting block when fetchDetails is enabled.
Built for recruiters tracking talent supply, market analysts comparing US labor demand against portals like LinkedIn Jobs and Glassdoor, compensation consultants enriching benchmarks across BLS data, founders monitoring competitor hiring, and ML teams training resume-to-job matching models. Output is clean JSON suitable for direct ingestion into Google BigQuery, Snowflake, Postgres, or Google Sheets.
What this Indeed scraper does
This actor automates browsing indeed.com the way a real visitor does. It hits the public job search pages, walks through pagination, parses Indeed's internal mosaic-provider-jobcards JSON blob embedded in the HTML, and (optionally) opens each job's detail page to extract the full description plus the structured schema.org JobPosting baseSalary, hiringOrganization, validThrough, and jobLocation fields.
The pricing logic is automatic: a salary string like "$55,000 - $179,400 a year" becomes salaryMin: 55000, salaryMax: 179400, salaryType: "YEARLY", salaryCurrency: "USD". Hourly rates like "$44 - $54 an hour" are kept as hourly and labeled accordingly so downstream code can annualize fairly.
The scraper is HTTP-only (no headless browser) and uses TLS-fingerprint impersonation to look like a real Chrome session. It runs on Apify's residential proxy network out of the box, so you don't need to manage your own proxy pool. Memory footprint is tiny — 512 MB — making it 10× cheaper than browser-based competitors that rent 4 GB instances for the same job.
Data fields the Indeed scraper extracts
Every record contains these fields when present in the data:
Identity & links
jobkey— Indeed's unique job identifiertitle— Position titledisplayTitle— Title as styled on IndeednormalizedTitle— Indeed's internal normalized titlejobUrl— Direct redirect link to the listingapplyUrl— Third-party application URL when present
Company
companyName— Hiring companycompanyRating— Indeed's rating out of 5 when knowncompanyReviewCount— Total employee reviews on IndeedcompanyReviewLink— Indeed company reviews pagecompanyOverviewLink— Indeed company profile pagecompanyLogoUrl— Logo URL (when fetchDetails=true)companySameAs— External company URL from JSON-LD (when fetchDetails=true)
Location
formattedLocation— Display string ("Strongsville, OH 44136")jobLocationCity— Parsed cityjobLocationState— US state code or provinceaddressLocality,addressRegion,addressCountry,postalCode— Full address (when fetchDetails=true)remote— Boolean: is this a remote job?
Salary
salaryText— Raw display string ("$55,000 - $179,400 a year")salaryMin— Lower bound numbersalaryMax— Upper bound numbersalaryType—YEARLY/HOURLY/MONTHLY/WEEKLYsalaryCurrency— Currency code (typically"USD")salarySource— Source label:EXTRACTIONvs employer-stated- Optional duplicate fields from JSON-LD:
salaryMinLd,salaryMaxLd,salaryUnitLd,salaryCurrencyLd,salaryValueLd
Snippet & description
snippet— Clean text preview of the job posting (search result excerpt)snippetHtml— Original HTML previewjobDescription— Full description text (only with fetchDetails=true)jobDescriptionHtml— Original HTML markup (only with fetchDetails=true)
Timing
postedRelative— "30+ days ago", "22 days ago", "Just posted"postedDate— ISO 8601 timestamp derived from Indeed's pubDatecreatedDate— Original creation timestamp when Indeed exposes itdatePosted— ISO 8601 from JSON-LD (when fetchDetails=true)validThrough— Expiration date from JSON-LD when employer set it
Posting flags
sponsored— Paid placement?urgentlyHiring— Highlighted urgent listing?newJob— Marked as new by Indeed?expired— Closed posting?featuredEmployer— Premium employer statusisTopRatedEmployer— Top-rated badge from IndeedindeedApplyEnabled— Can apply via Indeed?directApply— Direct apply enabled (JSON-LD)openInterviewsJob— Indeed "Open Interviews" tagged
Job type & taxonomy
jobTypes— Array of types ("Full-time", "Contract", "Part-time", "Internship")employmentType— Normalized employment type (JSON-LD)industry— Industry classification (JSON-LD)skills— Array of skill tags from Indeed's taxonomy
Benefits
benefits— Array of ranked benefits ("Health insurance", "401(k)", etc.)
Use cases for this Indeed data API
- Recruitment talent radar — Build a daily-refreshing stream of new listings matching your hiring niche. Filter by
remote,salaryMin, andurgentlyHiringto surface the most actionable opportunities. - US compensation benchmarking — Aggregate
salaryMin/salaryMaxby city + role to produce reliable pay bands. ThesalaryTypefield lets you cleanly separate hourly vs annual data. - Hiring intelligence — Track which companies are scaling specific functions (e.g. AI/ML engineers, growth marketers, sales). Combine
companyNamewith theindustryfield for clean segmentation. - Resume-to-job ML training corpora — Pair
title,jobDescription,skills, and salary fields to train recommendation or matching models against fresh real-world data. - Lead generation for B2B services — Cold outreach to companies actively hiring in your niche (e.g. all USA companies hiring a "VP of Engineering"). Use
companyName+jobLocationCityto build geographic outreach lists. - Skill demand tracking — Weekly cron over the same keyword set, count
skillsoccurrences over time. Detect emerging technologies and tooling before they hit industry reports.
How to use this Indeed scraper
You can drive the scraper in two ways: keywords mode (easiest — give one or many search keywords and a location) or urls mode (advanced — paste already-filtered Indeed search URLs).
Mode 1 — Search by keywords
{"mode": "keywords","keywords": ["python developer", "data engineer"],"location": "United States","country": "us","maxJobs": 100,"fetchDetails": false}
Mode 2 — Filtered search by city + remote-only + salary floor
{"mode": "keywords","keywords": ["software engineer"],"location": "Austin, TX","country": "us","maxJobs": 200,"remoteOnly": true,"salaryMinUsd": 120000,"fetchDetails": true}
Mode 3 — Search by URLs
{"mode": "urls","searchUrls": [{ "url": "https://www.indeed.com/jobs?q=devops+engineer&l=San+Francisco%2C+CA&sc=0kf%3Aattr%28DSQF7%29%3B" }],"maxJobs": 50,"fetchDetails": true}
Input parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
mode | enum | "keywords" | "keywords" or "urls" |
keywords | array | ["python developer"] | Search keywords |
location | string | "United States" | US location filter |
country | enum | "us" | Indeed subdomain: us, uk, ca, in, au |
searchUrls | array | [] | Pre-built search URLs (urls mode) |
maxJobs | integer | 50 | Cap per keyword/URL (1–5000) |
fetchDetails | boolean | false | Open each detail page for full description + JSON-LD |
remoteOnly | boolean | false | Keep only remote-tagged jobs |
salaryMinUsd | integer | 0 | Filter jobs by salary floor (hourly auto-annualized) |
proxyConfiguration | object | RESIDENTIAL | Apify proxy. Residential recommended for Indeed |
Output example (single record, JSON)
{"jobkey": "36f2876acf50d7da","title": "Software Engineer Lead/Experienced Python Developer","companyName": "PNC Financial Services Group","companyRating": null,"companyReviewCount": null,"formattedLocation": "Strongsville, OH 44136","jobLocationCity": "Strongsville","jobLocationState": "OH","remote": false,"salaryText": "$55,000 - $179,400 a year","salaryMin": 55000,"salaryMax": 179400,"salaryType": "YEARLY","salaryCurrency": "USD","salarySource": "EXTRACTION","snippet": "We are seeking a highly experienced Python Developer for the Corporate Functions Technology team...","postedRelative": "30+ days ago","postedDate": "2026-04-22T00:00:00+00:00","sponsored": false,"urgentlyHiring": false,"newJob": false,"expired": false,"indeedApplyEnabled": false,"jobTypes": ["Full-time"],"benefits": ["Health insurance", "401(k)", "Paid time off"],"skills": ["Python", "PySpark", "REST API"],"jobUrl": "https://www.indeed.com/rc/clk?jk=36f2876acf50d7da&...","applyUrl": null}
How to call this Indeed scraper from your code
From the Apify API (curl)
curl -X POST "https://api.apify.com/v2/acts/makework36~indeed-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"mode": "keywords","keywords": ["data engineer"],"location": "New York, NY","maxJobs": 100,"fetchDetails": false}'
From Python (apify-client)
from apify_client import ApifyClientclient = ApifyClient("YOUR_APIFY_TOKEN")run = client.actor("makework36/indeed-scraper").call(run_input={"mode": "keywords","keywords": ["python developer", "rust developer"],"location": "United States","maxJobs": 200,"fetchDetails": True,"remoteOnly": True,"salaryMinUsd": 100000,})for job in client.dataset(run["defaultDatasetId"]).iterate_items():print(job["title"], job["companyName"], job["salaryMin"], job["salaryMax"])
From Node.js (apify-client)
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });const run = await client.actor('makework36/indeed-scraper').call({mode: 'keywords',keywords: ['software engineer'],location: 'Seattle, WA',maxJobs: 100,fetchDetails: false,});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(`Got ${items.length} jobs`);
Export to CSV
curl "https://api.apify.com/v2/acts/makework36~indeed-scraper/runs/last/dataset/items?format=csv&token=$APIFY_TOKEN" \-o indeed_jobs.csv
Performance & cost
The scraper is fully HTTP — no headless browser. Memory footprint is 512 MB, dramatically lower than the 4 GB needed by browser-based competitors.
| Mode | Time per page (≈24 jobs) | Time per detail | 100 jobs ETA |
|---|---|---|---|
| Search only (fast) | ~1–2 s | — | ~10 s |
With fetchDetails=true | ~1–2 s + ~3 s/job | ~3 s | ~3–4 min |
For 1,000 jobs in search-only mode, expect 6–8 minutes including proxy rotation overhead. Detailed runs are slower but still 5× faster than browser scrapers.
Indeed scraper comparison
| Feature | This actor | Browser-based with proxy | Headless w/ captcha solver |
|---|---|---|---|
| Output fields | 30+ structured | 20–25 | 20 |
| Salary parsed (Min/Max/Type) | ✅ | ❌ | partial |
| Hourly vs Yearly auto-detected | ✅ | ❌ | ❌ |
| Memory footprint | 512 MB | 4 GB | 4 GB |
| Pure HTTP (no browser) | ✅ | ❌ | ❌ |
| Captcha solver required | ❌ | ❌ | ✅ |
| Pricing model | PAY_PER_EVENT tiered | flat or rental | flat |
Step-by-step tutorial — your first run in 2 minutes
- Click Try for free at the top of this page.
- In the input form, leave
modeaskeywordsandcountryasus. - Replace the default keyword (e.g.
"software engineer") and setlocationto your target city. - Set
maxJobsto20for a quick first run. - Leave
fetchDetailsoff — keeps the run fast. - Click Start. The run finishes in 10–20 seconds.
- Open the dataset tab; you'll see a table with titles, companies, locations, salaries.
- Export as CSV, JSON or Excel from the Export button.
- Once happy with the output, increase
maxJobs, enablefetchDetails, or schedule a recurring run.
Advanced usage patterns
Pattern A — Daily talent radar by ZIP code
Schedule the actor daily with location: "94103" (or any 5-digit US ZIP). You get all new jobs in that ZIP delivered as a CSV each morning.
Pattern B — Multi-state compensation atlas
Loop over keywords and US states. Aggregate salaryMin/salaryMax grouped by state and salaryType. Visualize as a US heatmap of pay bands.
Pattern C — Skill demand tracker
Weekly cron over 5 broad role categories. Count skills array elements across runs. Plot top-rising and top-falling skills over time.
Pattern D — Remote-only feed for global candidates
Set remoteOnly: true + salaryMinUsd: 80000. Only the highest-quality remote jobs reach your dataset. Combine with email integration for daily delivery.
Pattern E — Competitor hiring tracker
Use keywords matching specific competitor names or roles they typically post. Track frequency of new postings; correlated to their growth phases.
Troubleshooting
Some salary fields are null.
About 30–40% of Indeed postings don't list salary in the search results. Enabling fetchDetails: true recovers salary on a portion of these via the JSON-LD baseSalary field, but employers who don't disclose at all will remain null.
The actor only returns ~24 jobs even though I asked for 200. Indeed paginates in steps of 10 (sometimes 24 per page in the desktop layout). If your query is rare, total results might genuinely be small. Check the search on indeed.com directly to confirm the available pool.
HTTP 403 errors in the logs. This is normal — Indeed rate-limits each IP after 1–2 requests. The actor automatically rotates Apify residential proxy sessions and retries. As long as the final job count is non-zero, the scraper recovered.
My run hit the proxy budget limit.
Each search page is ~1.8 MB. For 1,000 jobs (≈42 pages) expect ~75 MB of proxy traffic. Check your Apify account's residential proxy allowance, or set a tighter maxJobs value.
remoteOnly: true is filtering too aggressively.
Indeed's remoteLocation flag is set conservatively. Some jobs that the description says are remote aren't tagged as remote in the data. Use fetchDetails: true and post-filter by searching for "remote" in jobDescription.
I want only specific job types (e.g. only Full-Time).
Pre-filter using Indeed's URL filter (e.g. &jt=fulltime or &jt=contract) via mode: urls, or post-filter on the jobTypes array in the output.
Pricing
This actor uses PAY_PER_EVENT pricing with tiered volume discounts.
| Tier | Standard job (search only) | Detailed job (with fetchDetails) |
|---|---|---|
| FREE | $3.00 / 1K | $7.50 / 1K |
| BRONZE | $2.20 / 1K | $5.50 / 1K |
| SILVER | $1.60 / 1K | $4.00 / 1K |
| GOLD | $1.10 / 1K | $2.80 / 1K |
| PLATINUM | $0.85 / 1K | $2.20 / 1K |
| DIAMOND | $0.60 / 1K | $1.80 / 1K |
Plus a one-time $0.001 per actor run. A typical 200-job standard run costs $0.60 (FREE) or as little as $0.12 (DIAMOND).
FAQ
Why is this Indeed scraper cheaper than other actors? It's pure HTTP — no browser, no GPU rendering, no XVFB. That's a 10× memory saving versus browser-based competitors, which the pricing passes back to you.
Is scraping Indeed.com legal? This actor accesses publicly available search and listing pages — no login, no paywall bypass, no PII extraction beyond what employers post publicly. Always check Indeed's terms of service and consult counsel for your jurisdiction.
How fresh is the data? The scraper fetches in real time when you start a run. Indeed updates listings continuously throughout the day. Schedule the actor as often as your use case demands.
Can I scrape Indeed without writing code? Yes — use the input form on this page, click Start, then download the dataset as CSV or Excel. No Python or Node required.
Does this support Indeed Canada / UK / Australia / India?
Yes. Set country to ca, uk, au, or in and the scraper hits the matching Indeed subdomain (ca.indeed.com, uk.indeed.com, etc.).
Why does the actor need Residential proxies? Indeed blocks datacenter IPs aggressively. Residential proxies have IP addresses from real households, which Indeed accepts. Apify includes residential proxy access in most paid plans.
What if Indeed changes its data format?
The scraper uses defensive parsing with both the embedded mosaic-provider-jobcards blob and the schema.org JobPosting JSON-LD on detail pages. When Indeed changes one, the other usually still works. Fixes typically land within 24–48 hours.
Does the scraper deduplicate jobs?
Yes. Each jobkey is unique; the scraper tracks seen keys across pages and won't push duplicates.
Is there a rate limit? The actor inserts a small jitter between pages and rotates proxy sessions automatically. For very large runs (>5,000 jobs) consider splitting across multiple Apify Tasks scheduled minutes apart.
Can I scrape jobs from a specific company on Indeed?
Yes — use mode: urls and pass an Indeed company jobs URL (e.g. https://www.indeed.com/cmp/Google/jobs). The scraper treats it like any search page.
Changelog
- 0.1 (2026-05) — Initial release. Keywords + URLs modes. Search + detail JSON-LD. 30+ fields. Residential proxy default.
Related scrapers from the same author
makework36/naukri-scraper— Naukri.com India jobsmakework36/trustpilot-reviews-scraper— Trustpilot business reviewsmakework36/google-maps-scraper-full— Google Maps places + contact infomakework36/flight-price-scraper— Multi-source flight prices
Legal & ethics note
This Indeed scraper accesses publicly available information. It does not bypass authentication, paywalls, or extract personally identifiable information beyond what employers and Indeed display publicly. Users are responsible for complying with Indeed's terms of service, the Computer Fraud and Abuse Act, and any data protection regulations applicable in their jurisdiction (e.g. CCPA, GDPR if scraping EU jobs). The author of this actor accepts no responsibility for misuse.