Indeed Jobs Scraper — Listings, Pay & Employers avatar

Indeed Jobs Scraper — Listings, Pay & Employers

Pricing

from $3.40 / 1,000 jobs

Go to Apify Store
Indeed Jobs Scraper — Listings, Pay & Employers

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

The Netaji

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

14 days ago

Last modified

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.

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.