Rapid Indeed & ZipRecruiter Scraper
Pricing
from $0.50 / 1,000 result (company or job record)s
Rapid Indeed & ZipRecruiter Scraper
Scrape Indeed and ZipRecruiter in one run: company hiring signals with live job totals, fresh job postings by company or keyword with exact timestamps and salaries, and company profile enrichment. CSV-ready output for recruiting outreach, lead scoring, and market research. X402, MPP, MCP
Pricing
from $0.50 / 1,000 result (company or job record)s
Rating
0.0
(0)
Developer
Pika Choo
Maintained by CommunityActor stats
1
Bookmarked
3
Total users
0
Monthly active users
12 days ago
Last modified
Categories
Share
Indeed & ZipRecruiter Scraper — Jobs, Hiring Signals & Company Profiles
Scrape Indeed and ZipRecruiter job postings, company hiring signals and company profiles in one run for $0.50 per 1,000 records. No API key, no login, no browser extension: give it a list of companies or keywords and get back fresh jobs with salaries and exact posting timestamps, live job totals per employer, and CSV-ready rows. Built for recruiting outreach, sales lead scoring, talent-market research and AI agent pipelines.
Who uses this Indeed & ZipRecruiter scraper
- Recruiters and staffing agencies who want to know which target accounts started hiring in the last 24 to 48 hours, with the actual job titles and pay.
- Sales and RevOps teams using hiring velocity as a buying signal to score and prioritise accounts.
- Talent-market and compensation analysts pulling posting volume and salary ranges per role, per region, per board.
- Data and CRM teams enriching company records with industry, headcount, revenue, HQ, founding year and employee rating.
- AI agent builders who need a structured Indeed API or ZipRecruiter API substitute that an LLM can call through MCP.
Three scan modes in one actor
| Mode | You provide | You get |
|---|---|---|
| Companies (default) | A list of company names (optionally with websites) | Hiring signal per company (active-posting counts per board plus the ZipRecruiter live job total), full company profile, and the latest jobs posted in the last N hours or the latest 10 |
| Keywords | Up to 10 search terms | Fresh job postings matching each keyword across both boards, with salary, location, remote flag and exact posting timestamps |
| Profiles | A list of company names | Company profiles only: industry, size, revenue, HQ, founding year, rating, live job count. Fast and lightweight |
Why this scraper
- Two job boards, one dataset. Indeed and ZipRecruiter results are merged, deduplicated and labeled per source.
- Real posting timestamps. ZipRecruiter jobs carry exact hour-precise
posted_attimestamps taken from the page itself. Repost and refresh bumps are detected and reported separately asreposted_at, so a "fresh" job is genuinely fresh. - True 24h / 48h recency filtering. Filtering is done by timestamp, which is more accurate than the boards' own date filters.
- Employer-verified matching. Jobs are matched to the target company by website domain plus normalized name, so common names ("Kelly", "Volt") do not pull in unrelated employers.
- Live job totals. The company's real ZipRecruiter posting count, not a page-limited sample, which is a direct hiring-volume signal.
- Company profiles from both boards. Industry, employee count, revenue, description, logo, HQ, founding year, employee rating, socials and website.
- CSV-ready output. Every job also lands as a flat one-row-per-job record, so exports open clean in Excel or Google Sheets.
- Resilient by design. Automatic retries, browser crash recovery, IP rotation and per-site timeouts. Partial results are saved incrementally.
What you get: output fields
Company record (record_type: "company", modes: companies / profiles)
| Field | What it tells you |
|---|---|
company_query / matched_company_name | The name you searched and the canonical employer name found on the boards |
has_active_postings | The core hiring signal: is this company hiring right now? |
active_jobs_found / active_jobs_by_site | Employer-verified postings returned this run, in total and split per board |
active_jobs_total_by_site.zip_recruiter | The company's real total of open ZipRecruiter postings, hiring volume at a glance |
posted_last_48h / posted_last_48h_count | Whether, and how many, postings fall inside your recency window |
profile.* | Industry, employee count, revenue, description, logo, HQ, founding year, employee rating, website, socials (Indeed company_* keys and ZipRecruiter zr_* keys side by side) |
latest_jobs | The returned jobs, nested (also emitted as flat rows) |
sites_with_errors | Which board, if any, failed for this company so you can retry selectively |
scraped_at | Run timestamp (UTC) |
Job record (record_type: "job", all modes)
| Field | What it tells you |
|---|---|
title, company, location | The posting basics |
date_posted / posted_at | Original posting date, plus the exact UTC timestamp where the board exposes one |
reposted_at | Present when the employer bumped or refreshed an older ad. A re-engagement signal, never disguised as a new posting |
salary_min, salary_max, salary_interval, salary_currency | Structured pay data (direct or parsed from the posting) |
job_type, is_remote, job_level | Employment type, remote flag and seniority where the board provides them |
job_url | Direct employer application link when available, board link otherwise |
site | Which board the row came from: indeed or zip_recruiter |
description | Full job description in Markdown or HTML (only when includeDescription is on) |
Keyword summary (record_type: "keyword", keyword mode): jobs_found,
jobs_by_site and jobs_returned per search term, so you can see posting
volume per board and how many matches fell inside the window.
Sample JSON output
One company record per target (companies / profiles mode):
{"record_type": "company","company_query": "Paychex","matched_company_name": "Paychex","has_active_postings": true,"active_jobs_found": 38,"active_jobs_by_site": { "indeed": 17, "zip_recruiter": 21 },"active_jobs_total_by_site": { "zip_recruiter": 593, "indeed": null },"posted_last_48h": true,"posted_last_48h_count": 17,"profile": {"company_industry": "Human Resources","company_num_employees": "10,000+","company_revenue": "$1B to $5B (USD)","zr_total_jobs": 593,"zr_rating": 7.27,"zr_headquarters": "Rochester, NY, US","zr_year_founded": "1971"},"latest_jobs": [ { "title": "Payroll Specialist", "posted_at": "2026-07-07T06:55:00Z", "job_url": "https://..." } ],"scraped_at": "2026-07-08T09:12:44Z"}
One flat job record per posting (all modes, when emitJobRecords is on):
{"record_type": "job","company_query": "Paychex","title": "Payroll Specialist","company": "Paychex","location": "Rochester, NY, US","date_posted": "2026-07-07","posted_at": "2026-07-07T06:55:00Z","site": "zip_recruiter","job_type": "fulltime","is_remote": false,"salary_min": 45000,"salary_max": 58000,"salary_currency": "USD","salary_interval": "yearly","job_url": "https://..."}
Input
| Field | Type | Default | Notes |
|---|---|---|---|
scanMode | companies | keywords | profiles | companies | See modes above. |
companies | array | none | Company names; add the website for precise matching: "Kelly Services | kellyservices.com". Via the API you may also pass {name, website} objects. |
keywords | array | none | Search terms (keyword mode, max 10). Indeed operators supported: "exact phrase", -exclude, (a OR b). |
location | string | United States | Search location (ZipRecruiter covers the US and Canada). |
recencyMode | last48h | latest10 | last48h | Jobs in the recency window, or the 10 most recent regardless of age. |
hoursOld | integer | 48 | Recency window in hours (1 to 720). |
maxJobsPerCompany | integer | 50 | Per company or keyword, per site cap (max 200). |
sites | array | both | indeed, zip_recruiter. |
includeDescription | boolean | false | Attach full job descriptions (adds latency on Indeed). |
descriptionFormat | markdown | html | markdown | Format of the description when included. |
emitJobRecords | boolean | true | Also push each job as its own flat row for clean CSV export. |
countryIndeed | string | usa | Indeed country domain (usa, uk, canada, ...). |
matchThreshold | number | 0.82 | Fuzzy-match strictness (0.5 to 1) for employer-name matching. |
proxyConfiguration | object | Residential | Residential proxy strongly recommended; ZipRecruiter rate-limits datacenter IPs. |
Data freshness notes
- ZipRecruiter rows are filtered by their exact posting timestamp (hour-precise). Indeed reports dates, so its rows are day-precise.
- ZipRecruiter ingests new postings in daily batches, so its freshest jobs are typically 12 to 48 hours old. For guaranteed two-board coverage use a 48-hour window; a 24-hour window is primarily driven by Indeed.
- Job counts per run are bounded by
maxJobsPerCompany.active_jobs_total_by_site.zip_recruiteris the company's real total from its ZipRecruiter page; Indeed does not expose a total, so its value isnull.
How much does it cost to scrape 1,000 Indeed or ZipRecruiter records?
Pricing is pay-per-event, so you only pay for what lands in your dataset:
| Event | Price |
|---|---|
| Result (one company record or one job record) | $0.0005 |
| Actor start (per GB of memory, minimum one) | $0.00005 |
Worked example: 1,000 records. A run that returns 20 company records and 980 job rows costs 1,000 x $0.0005 = $0.50 in results, plus $0.0002 for the actor start at 4 GB. Apify platform usage (compute units and residential proxy traffic) is billed separately at your plan's rates and is typically a few cents for a run of this size. Every Apify account includes free monthly platform credit, so small daily monitoring runs are often close to free.
Tips to keep cost predictable: use profiles mode when you only need company
data (one record per company, no job rows), lower maxJobsPerCompany, and turn
off emitJobRecords if you only want the nested latest_jobs inside each
company record.
Use with AI agents and MCP
This scraper is exposed as a tool over the Model Context Protocol, so Claude, ChatGPT, Cursor, or any MCP-capable agent can look up hiring signals and fresh jobs without you writing glue code. Connect to:
https://mcp.apify.com/?tools=fetch-actor-details,openclawai/indeed-ziprecruiter-scraper
Once connected, prompts like "Which of these 20 companies posted new jobs in the last 48 hours, and what are they paying?" run the actor and return structured rows the agent can reason over. A step-by-step setup guide with agent examples is at datapika.com/actors/indeed-ziprecruiter-scraper.
The actor also supports X402 and MPP pay-per-call flows for agents that pay per request instead of holding an Apify subscription.
Integrations: API, Python, JavaScript, Zapier, Make
- REST API. Start a run with
POST /v2/acts/openclawai~indeed-ziprecruiter-scraper/runsand read the dataset from/v2/datasets/{datasetId}/items?format=csv(orjson,xlsx). Use thejobsandcompaniesdataset views for pre-flattened tables. - Python client.
pip install apify-client, thenApifyClient(token).actor("openclawai/indeed-ziprecruiter-scraper").call(run_input={...}). - JavaScript client.
npm i apify-client, thennew ApifyClient({ token }).actor("openclawai/indeed-ziprecruiter-scraper").call({...}). - Schedules and webhooks. Run it every morning after the boards refresh and fire a webhook when the run finishes.
- No-code. Zapier, Make, Google Sheets, Airtable and Slack integrations are available from the actor's Integrations tab on Apify.
Results export as JSON, CSV or Excel directly from the dataset. The flat job rows are designed to open clean in a spreadsheet with zero rework.
What teams build with it
- Recruiting and staffing outreach. Run your target-account list daily;
when
posted_last_48h_countgoes positive, that account enters your campaign with the actual job titles and salaries in the first line. - Candidate-matching pipelines. Feed the flat job rows (title, salary, location, remote flag, timestamps) straight into an AI matching engine and email the shortlist while the posting is hours old.
- Sales lead scoring. Hiring velocity is one of the strongest buying signals; score accounts by live job totals and fresh-posting counts.
- Talent-market and compensation research. Keyword mode across regions gives posting volume and salary ranges per role, per board.
- CRM enrichment. Profiles mode fills industry, size, revenue, HQ, founding year and rating for thousands of records without touching the job feed.
FAQ
Does Indeed have an official API for job postings?
Indeed retired its public Job Search API and the current Publisher and Indeed Apply programs are limited to approved partners, so there is no self-serve official Indeed API for pulling job listings or employer data. This scraper reads the public job search and company pages instead and returns the same information as structured JSON, without an API key or partner agreement.
Does ZipRecruiter have an official API?
ZipRecruiter's API is for partner job boards and publishers that syndicate listings, not for querying jobs or company pages on demand. This actor gives you a ZipRecruiter data feed with salaries, exact posting timestamps and the employer's live job total, which the partner API does not expose.
How much does it cost to scrape 1,000 jobs?
$0.50 in result events, plus a fraction of a cent for the actor start and standard Apify platform usage. See the pricing section above for the full breakdown and cost-saving tips.
How fast is it and are there limits?
A companies-mode run on 10 companies with the default 48-hour window usually
finishes in a few minutes; profiles mode is faster because it skips the job
feed. Keyword mode accepts up to 10 terms per run and maxJobsPerCompany caps
each company or keyword at 200 postings per board. There is no cap on the
number of companies per run, but very large lists are best split across
scheduled runs so each one finishes inside the default 60-minute timeout.
Is it legal to scrape Indeed and ZipRecruiter?
The actor only reads publicly visible pages and never logs in, bypasses paywalls, or collects personal data about candidates. Job postings and company profiles are public business information. You are responsible for using the output in line with the boards' terms, applicable data-protection law (GDPR, CCPA) and your own outreach regulations. See the legal note below.
What output formats are available?
JSON, CSV, Excel, XML, RSS and HTML straight from the Apify dataset. Two
dataset views (jobs and companies) give you pre-flattened tables, and
emitJobRecords guarantees one clean row per job for spreadsheet exports.
How accurate is the company matching?
Jobs are matched by the employer's website domain first (when you supply
Name | website), with a normalized-name fallback controlled by
matchThreshold. Generic names ("Kelly", "Volt") will not pull in unrelated
employers.
Why do the two boards show different freshness?
Indeed timestamps postings same-day; ZipRecruiter ingests in daily batches, so its newest postings are typically 12 to 48 hours old. A 48-hour window gives full two-board coverage.
What is a repost and why does it matter?
Boards let employers "bump" old ads to the top. This actor reports the original
posting date (what the job page itself shows) and surfaces the bump separately
as reposted_at, so your "posted in the last 24 hours" list contains only
genuinely new jobs.
Can I search jobs without a company list?
Yes. scanMode: "keywords" searches both boards by term, with the same recency
filtering and flat output.
What locations are covered?
Indeed supports country selection via countryIndeed (for example usa, uk,
canada). ZipRecruiter covers the US and Canada.
Legal and ethical use
This actor collects publicly available job postings and company information for business intelligence, recruiting and research purposes. It does not access private accounts, candidate profiles or any data behind a login. Respect the job boards' terms of service and robots directives, rate-limit your schedules to what you actually need, and make sure any outreach you build on this data complies with CAN-SPAM, GDPR, CCPA and similar regulations in your jurisdiction.
Support
Open an issue from the actor's Issues tab on Apify or use the Console chat if a board changes its layout or you need a new field. Update notes are published with each build on the actor's page.