Indeed Jobs Scraper - Full Description, Salary, 22 Countries avatar

Indeed Jobs Scraper - Full Description, Salary, 22 Countries

Under maintenance

Pricing

$1.99 / 1,000 job postings

Go to Apify Store
Indeed Jobs Scraper - Full Description, Salary, 22 Countries

Indeed Jobs Scraper - Full Description, Salary, 22 Countries

Under maintenance

Search Indeed by keyword, location and country site: full job description, salary text plus parsed min/max/period/currency, company rating, job types, remote flag, posting date. No login or cookies. Deduplicated across keywords and filters; incomplete rows are marked and free, never shown as empty.

Pricing

$1.99 / 1,000 job postings

Rating

0.0

(0)

Developer

Lantern Lab

Lantern Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Categories

Share

Indeed Jobs Scraper

Search Indeed by keyword, location and country site and get each job back with its full description, salary text plus parsed min / max / period / currency, company name and rating, job types, remote or hybrid flag and posting date. 22 Indeed country sites (US, UK, Canada, Australia, Germany, France, India and more). No Indeed login, no cookies of yours.

Price: $1.99 per 1,000 jobs. Partial job rows, keyword status rows and the run summary are free, and so is a keyword that finds nothing.

Quick example

Input:

{
"keywords": ["nurse", "data analyst"],
"location": "Texas",
"country": "us",
"maxItems": 100
}

One job row (recordType: "job", shortened):

{
"recordType": "job",
"jobKey": "c0942dff5a2b832c",
"url": "https://www.indeed.com/viewjob?jk=c0942dff5a2b832c",
"title": "Nurse (Ambulatory Care)",
"companyName": "US Military Treatment Facilities under DHA",
"companyRating": 2.3,
"location": "El Paso, TX",
"salaryText": "$98,624 - $125,249 a year",
"salaryMin": 98624,
"salaryMax": 125249,
"salaryPeriod": "year",
"currency": "USD",
"jobTypes": ["Full-time"],
"isRemote": false,
"remoteType": null,
"postedAt": "2026-10-23T05:00:00.000Z",
"postedAtText": "1 day ago",
"descriptionText": "Summary\n\nAbout the Position: This position is located at William Beaumont Army Medical Center, El Paso, Texas. ...",
"country": "US",
"keyword": "nurse",
"searchLocation": "Texas",
"site": "us",
"matchedFilter": null,
"partial": false,
"collectedAt": "2026-10-24T17:51:43.120Z"
}

Limits

  • Depth: about 100-250 distinct jobs per keyword and location. Indeed shows a visitor who is not signed in only the first page of any search; asking for page 2 sends you to Indeed's sign-in page. This Actor does not sign in. To reach past page 1 it reads the first page of the same search under Indeed's own filters, one at a time (newest first, last 1/3/7/14 days, each job type, experience level, salary band, topic, wider radius...), and keeps only jobs it has not seen. Measured 2026-10-24: "nurse / Texas" reached 228 distinct jobs, "nurse / London" 119. For more jobs, add keywords or locations (e.g. several cities instead of one state). When a keyword ends below maxItems for this reason, its query_status row says depthLimitReached: true.
  • Salary is shown only when Indeed shows it: the employer gave it, or Indeed read it out of the posting (salarySource: "extraction"). About 3 in 4 jobs in our tests. Missing salaries are null, never estimated.
  • companyRating is null for employers without Indeed reviews; jobTypes is empty when Indeed shows no type.
  • postedAt is the day Indeed lists as the posting date (midnight in the site's time zone, as an instant); postedAtText is what Indeed shows ("Just posted", "3 days ago").
  • Public data only: no recruiter names, e-mails or phone numbers are collected as fields. The description is the employer's posting as Indeed publishes it.
  • Runs a real Chrome browser on the Apify residential proxy in the site's country, because Indeed answers plain HTTP clients and datacenter IPs with a Cloudflare "Security Check" page. When Indeed refuses a request, the Actor waits, then retries from a fresh IP. If Indeed changes its bot check, rows may come back partial or refused; they are marked as such, never as "no results".
  • When nothing matches, Indeed's "did not match any jobs" page sometimes still lists a few unrelated jobs; this Actor writes none of them and reports the keyword as empty.
  • Indeed's firewall rejects some keywords outright (measured for one containing <script>). Such a keyword is written as partial with partialReason: "query_rejected" and is not retried; remove characters such as < and >. Ordinary punctuation (C++ & "R&D") works.
  • No scheduling or monitoring built in; use Apify schedules.

What it does

  1. For each keyword, reads page 1 of Indeed's search for that keyword, location and your filters (datePosted, jobType, remoteOnly).
  2. If fewer than maxItems jobs were found and expandWithFilters is on, reads page 1 of the same search narrowed by one of the filters Indeed itself offers on that page, until maxItems jobs are written or 8 filtered pages in a row add nothing new.
  3. Reads the full description of every new job: one request per page of jobs, not one per job.
  4. Writes one row per job, deduplicated across all keywords and filters of the run.

Input

FieldDefaultWhat it does
keywords-Job titles, skills or companies, one per line. Repeats run once.
locationemptyCity, state, region or postcode. Empty = whole country site.
countryusIndeed site: us, uk, ca, au, de, fr, in, ie, nz, sg, nl, es, it, at, ch, be, jp, br, mx, za, ae, pl.
datePostedany1, 3, 7 or 14 days.
jobTypeanyfulltime, parttime, contract, temporary, internship, permanent.
remoteOnlyfalseOnly jobs Indeed tags as remote.
includeDescriptiontrueFull description per job. Off = Indeed's short snippet only.
maxItems100Max jobs per keyword (up to 1,000; see the depth limit above).
expandWithFilterstrueReach past page 1 through Indeed's filters. Off = page 1 only (up to ~45 jobs on the US site, ~15 elsewhere).
maxUpstreamRequestsderivedHard ceiling on requests to Indeed, retries included.
proxyConfigurationresidentialApify residential proxy; the exit country follows country.

Output

Three kinds of rows, told apart by recordType:

  • job - one per job. Main fields: jobKey, url, title, companyName, companyRating, companyReviewCount, companyUrl, location, city, state, postalCode, country, salaryText, salaryMin, salaryMax, salaryPeriod (hour / day / week / month / year), currency, salarySource, jobTypes, isRemote, remoteType (remote / hybrid / null), postedAt (= publishedAt), postedAtText, descriptionText, descriptionHtml, snippet, sponsored, urgentlyHiring, easyApply, plus the search that found it first (keyword, searchLocation, site, matchedFilter) and collectedAt. Charged.
    • partial: true with partialReason means the job was listed but its description could not be read in this run. Not charged.
  • query_status - one per keyword: outcome (found / empty / partial), jobs written, repeated listings skipped, search pages and filters read, depthLimitReached, and a statusText that explains it in a sentence. Free.
  • RUN_SUMMARY - the last row, also stored in the run's key-value store: totals, partial rows by reason, requests to Indeed, refusals and IP rotations, and why the run stopped if it stopped early. Free.

A keyword is partial (never empty) when Indeed refused requests, the request ceiling or your maximum charge was reached, or a page did not read as expected. A run that collected nothing because Indeed refused every request ends as failed, not as an empty success.