Indeed Jobs Scraper — Salaries, Benefits & Company Data avatar

Indeed Jobs Scraper — Salaries, Benefits & Company Data

Pricing

from $3.00 / 1,000 jobs

Go to Apify Store
Indeed Jobs Scraper — Salaries, Benefits & Company Data

Indeed Jobs Scraper — Salaries, Benefits & Company Data

Indeed jobs scraper and API: every posting with its full description, the employer's salary and Indeed's estimate in USD, benefits and schedule, company industry, size, revenue, CEO and website. 74 countries, pasted Indeed URLs, filters that never bill, a new-jobs monitor. $3 per 1,000 jobs.

Pricing

from $3.00 / 1,000 jobs

Rating

0.0

(0)

Developer

Spool

Spool

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

3 days ago

Last modified

Share

Indeed jobs scraper and API: every posting with its full description, the employer's pay annualised in USD, benefits, schedule and skills as Indeed tags them, and the company's industry, size, revenue, CEO and website, from any of Indeed's 74 country sites. Rows are deduplicated, located and classified (department, seniority, job category, employment type, years of experience, visa sponsorship, education, 190 technologies), filtered before anything is charged, and delivered page by page while the next page is still loading.

Data Engineer FanDuel $116,000–$145,000 /yr hybrid Commuter assistance · 401(k) via FanDuel
Corporate Accountant Lancashire County Council £42,123–£47,665 /yr onsite Company pension · Employee discount via the council's site
Contact Center Representative Aloha Pacific FCU $18.00–$23.98 /hr remote Health insurance · Paid holidays via Aloha Pacific FCU

What a run costs. $0.003 per job row, so 1,000 jobs are $3, the same on every plan. The default run below asks for 200 jobs and costs about $0.60. Duplicates, rows a filter removed and empty pages cost nothing.

Try it in one minute

  1. Press Try for free and keep the prefilled input, or paste this:
    { "searchTerms": ["data analyst"], "location": "Chicago, IL" }
  2. Press Start. Indeed is read 100 postings at a time through its own JSON API, each page is enriched and delivered as it lands.
  3. Open the Output tab: the Jobs, Salaries, Benefits and schedule, Companies and Technologies views each show their own columns. Export as JSON, CSV or Excel, or read the dataset from the API.

Measured on the platform, 31 October 2026, build 1.0, four runs started in the same minute: the default search (software engineer, whole United States, 200 rows) delivered 200 jobs in 4.8 seconds, first rows at 2.2 seconds, every row with a description, 97 with the employer's pay; data engineer in New York, 200 rows in 32 seconds, 187 with pay; customer service representative, remote, employer pay required: 200 rows in 59 seconds, 400 postings read, the 159 without pay removed before billing; accountant in Manchester on uk.indeed.com, 100 rows in 7 seconds.

Why this one

This ActorA typical Indeed scraper
SourceIndeed's own JSON API, the one its mobile app uses, 100 postings per request with the full descriptionHTML pages, 15 per page, the description fetched one by one
Paythe employer's stated pay as min, max, interval and currency, annualised and in USD; ranges written only in the text read out too; the recruiter's own pay text keptone salary string, or none
Benefits, schedule, skills, workplace typeevery attribute Indeed shows, sorted into benefits, schedule, skills and pay typesnot delivered
Companyindustry, size, revenue, CEO, website, logo, header image, address, description, Indeed company pagename and maybe a logo
Where the posting came frompostedVia: the employer's site, an ATS or a boardnot delivered
Classificationdepartment, seniority, job category, employment type, years of experience, visa sponsorship, education, 190 technologiesnone
Filters14 filters applied before billing; removed rows cost nothingboard-side filters only
Countries74 Indeed sites, by name or from a pasted URLoften US only
Pasted Indeed URLsyes, any country site; keywords, place, radius, date, remote, job type and level read from the URLsometimes
Only what is newmonitor mode remembers what a search already deliveredno
Deliverypage by page, first rows in secondsall at the end

What you get

Every row carries the job, the pay, the employer and the classification:

  • The job: title, company, location (with city, region, country, postalCode, streetAddress where Indeed has them), workplaceType (remote, hybrid, onsite), jobType and jobTypes, jobLevel when Indeed tags one (entry, mid, senior), datePosted (the employer's publish date) and dateOnIndeed (the day it reached Indeed), postedDaysAgo, jobUrl on Indeed, jobUrlDirect on the employer's site when the posting lives there, applyUrl, postedVia (the employer's site, an ATS, or Indeed itself), the full description in Markdown, HTML or plain text.
  • The pay: salaryMin, salaryMax, salaryInterval, salaryCurrency, salarySource (employer, or description when read from the text), salaryMinAnnual/salaryMaxAnnual, salaryMinUsd/salaryMaxUsd, salaryText as the recruiter wrote it, payTypes (bonus pay, commission, tips, holiday pay). Indeed's own estimate lands in estimatedSalary* with hasEstimatedSalary when the API returns one, which in our measurements it rarely does.
  • Benefits, schedule, skills: attributes (every label Indeed shows), benefits, schedule, skills (the requirement labels Indeed lists alongside), workSchedule.
  • The employer: companyUrl (Indeed company page), companyWebsite, companyIndustry, companyNumEmployees, companyRevenue, companyCeo, companyLogo, companyHeaderImage, companyDescription, companyAddresses.
  • Classification: department, seniority, jobCategory, employmentType, yearsExperienceMin/Max, visaSponsorship, educationLevel, tech, techCategories, emails found in the text.
  • Bookkeeping: searchTerm (which of your terms found it), matchedLocation, sourceSearchUrl, dedupeKey, firstSeenAt (monitor mode), keywordMatchPercent when you score against keywords.

Salaries you can compare

The employer's stated pay goes to salary* with salarySource: "employer", as min, max, interval and currency, then annualised (hourly x 2,080, daily x 260, weekly x 52, monthly x 12) and converted to USD with the day's rates, so a Berlin posting in EUR and a Toronto one in CAD sort on one column. When the employer states nothing in the pay fields but writes a range in the text, the range is read out and marked salarySource: "description". salaryText keeps the pay exactly as the recruiter wrote it. Indeed's own estimate, the one its site shows under "Estimated", is a separate thing: when Indeed's API returns it, it lands in estimatedSalary* and never in the employer's fields; in our measurements the API returned it for none of the postings read, so count on the employer's pay, which 50 to 95 percent of postings state depending on the trade. requireSalary keeps only employer-stated pay.

Benefits, schedule, workplace

Indeed tags each posting with attribute labels: Health insurance, 401(k), Paid time off, Monday to Friday, Day shift, Weekends as needed, Cash register, Forklift, Bilingual, Hybrid work, Remote, In person, Entry level. All of them are in attributes; the ones that are benefits are in benefits, the ones about days and shifts in schedule, the pay types (bonus, commission, tips) in payTypes, the requirement labels in skills, the level in jobLevel, and workplaceType says remote, hybrid or onsite. remoteOnly uses Indeed's own remote filter first, then every row is judged again by its location, attributes and text; a row with no remote evidence is removed before billing.

74 countries

country picks the Indeed site: usa (default), canada, uk, ireland, australia, new zealand, india, singapore, hong kong, japan, south korea, taiwan, philippines, malaysia, indonesia, thailand, vietnam, pakistan, bangladesh, germany, france, netherlands, belgium, luxembourg, switzerland, austria, italy, spain, portugal, denmark, sweden, norway, finland, poland, czech republic, slovakia, hungary, romania, bulgaria, croatia, slovenia, greece, cyprus, malta, estonia, latvia, lithuania, ukraine, turkey, israel, united arab emirates, saudi arabia, qatar, kuwait, bahrain, oman, egypt, morocco, nigeria, south africa, brazil, mexico, argentina, chile, colombia, peru, ecuador, venezuela, uruguay, costa rica, panama, china. Results come in the site's language; descriptions are delivered as published.

Paste a search URL

Copy the address bar from any Indeed search and put it in searchUrls. Keywords, place, radius, the date window (fromage), remote, job type and experience level are read from it, and the country from the host (uk.indeed.com, de.indeed.com). One search per URL, up to 20; every row says which URL found it in sourceSearchUrl.

Filters that never bill

Indeed applies its own date window, remote, job type and Indeed Apply filters before anything is read. Everything else is applied here, after the rows are read and before anything is charged. A row with no evidence for a filter (no date, no seniority cue) is kept; silence is not a mismatch. RUN_SUMMARY.filterRemoved shows the count per filter.

FilterKeeps
requireSalaryemployer-stated pay only (Indeed's estimate does not count)
minSalaryUsdannualised pay at or above the number
requireTechpostings that mention any of the technologies
excludeTitleKeywords / requireTitleKeywordsby words in the title
excludeCompanies / targetCompaniesby employer, parent names included
excludeCitiesdrops places you do not want inside a wide radius
excludeAgenciesdrops staffing and recruiting agencies
maxAgeDaysby the employer's publish date
experienceLeveljunior, mid, senior, lead, as classified from the title
strictKeywordMatchonly postings whose title or text carries every word of your term
remoteOnlyrows with remote evidence (Indeed's filter, then location, attributes, text)
jobTypeIndeed's job type, checked again against the posting

Monitor mode: only what is new

onlyNew: true remembers what a search already delivered, in a key-value store in your own account, and later runs deliver only postings not seen before. Schedule the run daily and the dataset is your feed of new Indeed jobs. Rows seen before are not delivered and not charged. monitorName names the memory when you run several monitors.

Alerts

webhookUrl receives a digest when a run delivers rows: how many, the top titles and companies, the salary range, links to the dataset. A Slack or Discord webhook gets a readable message; any other URL gets JSON.

Rows arrive page by page

Indeed answers 100 postings per request. Each page is enriched and delivered as it lands, so the first rows are in the dataset within seconds and RUN_SUMMARY.waves says when each page arrived. Several terms and places are paged at the same time, each until its share of results is met; when the filters leave the run short, the searches that still have pages take turns until the target, and, if your own words run dry, the same role is searched under its other names (a row found that way must carry the related title in its own title; expandTerms: false turns this off).

Every option

OptionDefaultWhat it does
searchTermsjob titles or keywords, one search each (up to 10)
locationcity, state, postal code or country as typed on Indeed; empty = the whole country
locationsmore places; every term is searched in every place (up to 10 places)
countryusawhich Indeed site, by name (74)
searchUrlspasted Indeed search URLs; when given, the fields above are ignored
results200jobs to deliver per run, after deduplication and filters (1 to 10,000)
postedWithinHoursIndeed's date window: 24, 72, 168 ...
remoteOnlyfalseIndeed's remote filter plus the evidence check
jobTypefulltime, parttime, contract, temporary, internship, perdiem, volunteer
indeedApplyOnlyfalseonly postings applied to through Indeed
radiusMiles50distance around the place
includeEstimatedSalarytruedeliver Indeed's estimate in the estimatedSalary* fields when the API returns one
descriptionFormatmarkdownmarkdown, html or text
requireSalary, minSalaryUsd, requireTech, excludeTitleKeywords, requireTitleKeywords, excludeCompanies, targetCompanies, excludeCities, excludeAgencies, maxAgeDays, experienceLevel, strictKeywordMatchthe filters above
resumeKeywordsscore every row against these words (matchedKeywords, keywordMatchPercent)
sortBysalary_desc or date_desc inside each delivered page
expandTermstruesearch related titles when your words leave the target short
onlyNew, monitorNamefalsemonitor mode
webhookUrlalert digest
useApifyProxy, proxyConfigurationApify residentialIndeed refuses Apify's own addresses, so residential sessions are used

How much does it cost?

$0.003 per job row delivered, on every plan. Nothing else is charged except Apify's standard Actor start.

RunRowsPrice
Default (200 rows)200$0.60
A daily monitor that finds 30 new postings30$0.09
A 1,000-row sweep1,000$3.00
A salary study, 150 rows that state pay150$0.45, the rows without pay were never charged

Compute and proxy traffic are covered by the row price. Set a maximum total charge on the run if you want a hard cap; rows beyond it are not delivered and not charged, and a notice row says how many were held back.

Use it from an AI agent, the API or an integration

The Actor is listed for agentic payments and works as an MCP tool through Apify's MCP server. From code:

from apify_client import ApifyClient
client = ApifyClient("<YOUR_APIFY_TOKEN>")
run = client.actor("spool/indeed-scraper").call(run_input={"searchTerms": ["data engineer"], "location": "New York, NY", "results": 300})
for job in client.dataset(run["defaultDatasetId"]).iterate_items():
print(job["title"], job["company"], job["salaryMinUsd"], job["applyUrl"])
const { ApifyClient } = require('apify-client');
const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });
const run = await client.actor('spool/indeed-scraper').call({ searchTerms: ['data engineer'], location: 'New York, NY' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();

Schedule it, connect the dataset to Google Sheets, Make, Zapier or n8n through Apify's integrations, or point the alert webhook at Slack.

What it covers, honestly

  • Indeed's matching is Indeed's. A search for "electrician" returns what Indeed ranks for it, including adjacent trades. strictKeywordMatch keeps only rows whose title or text carries your words; requireTitleKeywords narrows to the title.
  • Two dates. datePosted is the employer's publish date; dateOnIndeed is the day the posting reached Indeed, which is what postedWithinHours filters on. They can differ by days for postings Indeed picks up from employer sites.
  • Indeed's pay estimate is rarely in this API's answer. The fields exist and fill when it is; do not plan on them. The employer's stated pay is what you get, on 50 to 95 percent of postings depending on the trade.
  • Company rating and review counts are not part of this API answer and are not delivered.
  • Remote evidence. On remote searches, rows that carry no remote cue in their location, attributes or text are removed before billing. Indeed's remote tag counts as a cue.
  • Deep runs page 100 at a time; a 1,000-row search is ten requests per term. Very broad searches with heavy filters read more pages than they deliver; RUN_SUMMARY.postingsScanned says how many.
  • Pay ranges written in the text are read by rules and marked salarySource: "description"; check them before you rely on them.

The Actor reads publicly listed job postings that Indeed shows to anyone, without logging in, through the same API Indeed's app uses, paced through residential sessions. It stores what the posting says. Email addresses that appear in a posting's text are delivered as published; handle them under the law that applies to you. You are responsible for how you use the data, including Indeed's terms of use and the data protection rules of your jurisdiction.

FAQ

Why do I see titles I did not type? Indeed's own matching, or, when your words left the target short, related titles of the same role. searchTerm on every row says which term found it; strictKeywordMatch or expandTerms: false narrows it.

Why is the salary empty when Indeed's site shows one? What the site shows is Indeed's estimate, which its API rarely returns; the salary* fields carry what the employer stated or wrote in the text, and salaryText the recruiter's own words.

Can I get more than 1,000 rows? Yes, results goes to 10,000. Indeed returns at most about 1,000 postings per search, so use several terms or places for more.

Does it work outside the US? Yes, 74 country sites by name or pasted URL. Salaries are converted to USD at the day's rates; the original currency is kept.

How fast is it? The first page lands in a few seconds; a 200-row run finishes in well under a minute; 1,000 rows in a couple of minutes. RUN_SUMMARY.waves shows when each page arrived.

What if a run hits its time limit? It stops itself a margin before the limit, delivers what it had, writes its summary and ends as succeeded with status: stopped-at-time-limit.

Changelog

1.0.0 — 2026-10-31. First release. Indeed through its own JSON API, 100 postings per request with full descriptions; employer pay annualised in USD, pay ranges read from the text, the recruiter's pay text kept; benefits, schedule, skills, pay types, level and workplace type from Indeed's attributes; company industry, size, revenue, CEO, website, logo and header image; where the posting came from; 74 countries; pasted search URLs; 14 filters that never bill; monitor mode; alert webhook; related-title fill with the title rule; page-by-page delivery. Measured: 200 rows in 4.8 s (default), 200 filtered remote rows with pay in 59 s, 100 UK rows in 7 s.

Support

Issues tab on this page, or the email on the spool profile. Bugs are fixed in days, with the fix in the changelog.

More from spool

  • Job Board Scraper & API: one search across LinkedIn, Indeed, Glassdoor and 30 more sources, the employer's own posting attached.
  • Job Search Scraper: live jobs straight from company career pages, 1,100 verified employer boards.
  • Career Page Scraper & ATS Jobs API: Greenhouse, Lever, Ashby, Workday, SmartRecruiters and 12 more ATS platforms, no proxy.