Indeed Scraper - Jobs, Salaries & Companies USA avatar

Indeed Scraper - Jobs, Salaries & Companies USA

Under maintenance

Pricing

Pay per event

Go to Apify Store
Indeed Scraper - Jobs, Salaries & Companies USA

Indeed Scraper - Jobs, Salaries & Companies USA

Under maintenance

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

deusex machine

Maintained by Community

Actor stats

0

Bookmarked

3

Total users

2

Monthly active users

2 days ago

Last modified

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.

✨ Why use this scraper

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.

📤 Output fields

Every record contains these fields when present in the data:

  • jobkey — Indeed's unique job identifier
  • title — Position title
  • displayTitle — Title as styled on Indeed
  • normalizedTitle — Indeed's internal normalized title
  • jobUrl — Direct redirect link to the listing
  • applyUrl — Third-party application URL when present

Company

  • companyName — Hiring company
  • companyRating — Indeed's rating out of 5 when known
  • companyReviewCount — Total employee reviews on Indeed
  • companyReviewLink — Indeed company reviews page
  • companyOverviewLink — Indeed company profile page
  • companyLogoUrl — Logo URL (when fetchDetails=true)
  • companySameAs — External company URL from JSON-LD (when fetchDetails=true)

Location

  • formattedLocation — Display string ("Strongsville, OH 44136")
  • jobLocationCity — Parsed city
  • jobLocationState — US state code or province
  • addressLocality, 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 number
  • salaryMax — Upper bound number
  • salaryTypeYEARLY / HOURLY / MONTHLY / WEEKLY
  • salaryCurrency — Currency code (typically "USD")
  • salarySource — Source label: EXTRACTION vs 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 preview
  • jobDescription — 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 pubDate
  • createdDate — Original creation timestamp when Indeed exposes it
  • datePosted — 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 status
  • isTopRatedEmployer — Top-rated badge from Indeed
  • indeedApplyEnabled — 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

  1. Recruitment talent radar — Build a daily-refreshing stream of new listings matching your hiring niche. Filter by remote, salaryMin, and urgentlyHiring to surface the most actionable opportunities.
  2. US compensation benchmarking — Aggregate salaryMin/salaryMax by city + role to produce reliable pay bands. The salaryType field lets you cleanly separate hourly vs annual data.
  3. Hiring intelligence — Track which companies are scaling specific functions (e.g. AI/ML engineers, growth marketers, sales). Combine companyName with the industry field for clean segmentation.
  4. Resume-to-job ML training corpora — Pair title, jobDescription, skills, and salary fields to train recommendation or matching models against fresh real-world data.
  5. 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 + jobLocationCity to build geographic outreach lists.
  6. Skill demand tracking — Weekly cron over the same keyword set, count skills occurrences over time. Detect emerging technologies and tooling before they hit industry reports.

🚀 How to use

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

ParameterTypeDefaultDescription
modeenum"keywords""keywords" or "urls"
keywordsarray["python developer"]Search keywords
locationstring"United States"US location filter
countryenum"us"Indeed subdomain: us, uk, ca, in, au
searchUrlsarray[]Pre-built search URLs (urls mode)
maxJobsinteger50Cap per keyword/URL (1–5000)
fetchDetailsbooleanfalseOpen each detail page for full description + JSON-LD
remoteOnlybooleanfalseKeep only remote-tagged jobs
salaryMinUsdinteger0Filter jobs by salary floor (hourly auto-annualized)
proxyConfigurationobjectRESIDENTIALApify proxy. Residential recommended for Indeed

📋 Output example

{
"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
}

💻 Code examples

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 ApifyClient
client = 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

The scraper is fully HTTP — no headless browser. Memory footprint is 512 MB, dramatically lower than the 4 GB needed by browser-based competitors.

ModeTime per page (≈24 jobs)Time per detail100 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.

📊 Comparison

FeatureThis actorBrowser-based with proxyHeadless w/ captcha solver
Output fields30+ structured20–2520
Salary parsed (Min/Max/Type)partial
Hourly vs Yearly auto-detected
Memory footprint512 MB4 GB4 GB
Pure HTTP (no browser)
Captcha solver required
Pricing modelPAY_PER_EVENT tieredflat or rentalflat

💵 Pricing

This actor uses PAY_PER_EVENT pricing with tiered volume discounts.

TierStandard 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.