Indeed Jobs Scraper — Listings, Pay & Employers
Pricing
from $3.40 / 1,000 jobs
Indeed Jobs Scraper — Listings, Pay & Employers
Turn a list of roles and cities into a spreadsheet of live openings. Each row carries the employer and its rating, the pay range already parsed into numbers, the location, the posting date, the apply link, and whether the employer paid for the placement.
Pricing
from $3.40 / 1,000 jobs
Rating
0.0
(0)
Developer
The Netaji
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
14 days ago
Last modified
Categories
Share
Indeed Jobs Scraper
Search Indeed by role and city and export every matching job as a spreadsheet row. Each row carries the job title, the employer and its rating, the pay range already parsed into numbers, the location split into city and state, the posting date, the apply link, and whether the employer paid for the placement.
A run takes a list of search terms and a list of locations, and searches every term against every location. Four terms and five cities is twenty searches in one run.
Accepted input
queries is required and is a list of search terms, one per line — a role, a skill, or an
employer name. locations is a list of places, given as a city and state (Austin, TX), a
state, a postcode or remote; leave it empty for one nationwide search per term.
radius sets how many miles around each location to include, up to 100. days_ago
restricts results to postings first indexed within 1, 3, 7 or 14 days. job_type
selects fulltime, parttime, contract, temporary or internship. sort is either
relevance, which is the site's own default ordering, or date.
maxItems bounds the rows saved across the whole run and defaults to 100; a value of 0
removes the bound.
{"queries": ["software engineer", "backend developer"],"locations": ["Austin, TX", "Dallas, TX"],"days_ago": "7","job_type": "fulltime","maxItems": 100}
Response fields
{"search_query": "engineer","search_location": "Austin, TX","job_key": "c9827654f65af6b6","title": "Camera Optomechanical Engineer","normalized_title": "Engineer","company_name": "Saronic Technologies","company_rating": 3.9,"company_review_count": 1204,"company_slug": "Saronic-Technologies","company_id": "6b92e3265b43baa6","location_formatted": "Austin, TX","city": "Austin","state": "TX","country": "US","salary_min": 145000,"salary_max": 210000,"salary_period": "YEARLY","salary_text": "$145,000 - $210,000 a year","job_types": ["Full-time"],"attributes": { "job-types": ["Full-time"], "benefits": ["401(k)", "Paid time off"] },"created_at": "2026-02-20T04:32:27.426Z","posted_relative": "30+ days ago","sponsored": true,"ad_bid": 586719,"ad_bid_position": 3,"job_url": "https://www.indeed.com/viewjob?jk=c9827654f65af6b6"}
Fields absent from a posting are returned as null rather than omitted, so every row has the same shape.
salary_min and salary_max are numbers, not the string on the card, and salary_period
says what period they are quoted over. This matters more than it sounds: hourly and salaried
roles sit side by side in one result set, so two rows are only comparable once the period is
read. salary_text keeps the string exactly as the card rendered it.
search_query and search_location record which of the run's searches found the row. In a
run over twenty searches they are the difference between a dataset that can be grouped by
market and one that cannot.
sponsored, ad_bid and ad_bid_position describe the advertising behind a placement:
whether the employer paid for it, the bid, and where that bid placed the row. That makes
"which employers are buying visibility for this search, and at what rank" an answerable
question, and it is worth reading sponsored before treating result order as a ranking.
company_slug is the exact value Indeed Company Scraper
accepts, and job_key is the exact value
Indeed Job Description Scraper
accepts. Both compose from this Actor's output with no lookup step in between.
attributes holds every taxonomy the card carries, keyed by the site's own names: benefits,
shift patterns and encouraged-to-apply tags all arrive there. Which keys exist varies per
posting, so a posting listing no benefits has no benefits key at all rather than an empty
one.
Adding the full description
enrichJobDescription reads each saved job's own posting and merges it onto the row. It is
off by default, costs one further request per job, and is billed per job read, only after the
posting has been read.
It adds description_html, the posting as the employer wrote it, and description_text, the
same text with the markup removed and the line breaks kept — the form to hand to a keyword
filter or a language model. Alongside them come valid_through, date_posted,
employment_type, direct_apply, requisition_id, postal_code, street_address,
locations, company_url and company_logo.
valid_through is the useful one: it is the date the employer expects the posting to expire,
so a listing's freshness can be judged without fetching it again.
{"queries": ["registered nurse"],"locations": ["Austin, TX"],"maxItems": 25,"enrichJobDescription": true}
A job whose posting cannot be read keeps its search row unchanged and is not billed for the add-on.
Questions
How many jobs does one search return?
Roughly 40 to 50. Indeed serves exactly one page of results to a visitor without an account:
asking for the second page redirects to a sign-in wall, and Indeed's own "Next" link goes to
the same place. That ceiling belongs to Indeed rather than to this Actor, and no setting here
moves it. A measured search for engineer in Austin returned 48 jobs.
So how is a market covered in full?
By searching more, not deeper. Every term is run against every location, so the way to widen
a run is to add terms (software engineer, backend developer, platform engineer) and to
split a metro into its neighbouring cities, each of which gets its own page of results.
Changing sort from relevance to date also changes which jobs land on that single page,
so it is a coverage setting as much as an ordering one.
Why did a second run of the same search return partly different jobs? Because Indeed rotates them. The same search twice, back to back, returned 42 jobs and 41 sharing only 31 — about a quarter of a page turns over between identical requests. Re-running a saved input therefore does accumulate postings the first run never saw, which is unusual and worth exploiting on a market being tracked over time.
Why did the run save fewer rows than maxItems?
Either the searches ran out first, or the same job turned up under more than one of them. A
job returned by two searches is saved once, and the row records the first search that found
it. The run log states how many jobs each search returned before deduplication.
A search returned nothing at all — is that a failure? No. A search that matches nothing comes back as a normal, successful request with no results on it, and the run logs a warning naming the term and continues to the remaining searches. One dead term in a list of twenty does not end the run.
Is days_ago a free-text number of days?
No, and that is deliberate. Indeed acts on 1, 3, 7 and 14 and silently ignores
anything else, so accepting 10 would return an unfiltered result set that looked filtered.
Is radius useful without a location?
No. A nationwide search has no point to measure a radius from, so the value is ignored.
Is an Indeed account, cookie or API key required? No. Nothing of the kind is supplied to the Actor or needed by it.
Related Actors
Indeed Job Description Scraper
reads full postings from the job_key column. It is the right choice for a second pass over
a dataset already collected, since it spends no requests finding the jobs again.
Indeed Company Scraper profiles the
employers behind these rows from the company_slug column: ratings, CEO approval and the
work happiness survey.
Indeed Salary Scraper prices a job title across the whole country when the question is what a role pays rather than who is hiring for it.


