ZipRecruiter Jobs Scraper
Pricing
from $0.99 / 1,000 job seats
ZipRecruiter Jobs Scraper
Scrape ZipRecruiter job listings by keyword and location with filters for remote type, salary, employment type, experience level, and more. NO Proxy required.
Pricing
from $0.99 / 1,000 job seats
Rating
0.0
(0)
Developer
DataCach
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
19 hours ago
Last modified
Categories
Share
ZipRecruiter Jobs Scraper extracts structured job data from ZipRecruiter — one of the largest job boards in the United States — without needing an official API. Search by job title and location, run multiple searches in a single execution, apply powerful filters for remote type, salary range, employment type, experience level, and more, then collect results as clean, ready-to-use JSON.
Proxy rotation, Cloudflare session management, and pagination are all handled automatically. You focus on the data.
What does ZipRecruiter Jobs Scraper extract?
Each scraped listing is a fully normalised JSON record containing:
- Job basics — title, description snippet, posting date, and active status
- Company info — name, logo URL, and ZipRecruiter company page link
- Location — city, state, country, display label, and remote/hybrid/on-site classification
- Salary & pay — minimum and maximum annual figures, pay interval, currency, and a human-readable display string; flagged when salary is estimated by ZipRecruiter
- Employment type — full-time, part-time, contract, temporary, and more
- Benefits — medical, dental, vision, retirement, PTO, and others when listed
- Apply details — whether ZipRecruiter Quick Apply is available, external apply URL, and direct job page link
Filters are passed as native ZipRecruiter URL query parameters, so results are filtered server-side — the same data ZipRecruiter shows real users.
Why scrape ZipRecruiter job listings?
ZipRecruiter does not offer a public API for bulk job data access, making a scraper the only reliable programmatic path to this dataset. Common use cases include:
- Job market intelligence — track demand for specific roles, in-demand skills, and salary benchmarks across locations over time
- Competitor hiring analysis — monitor which companies in your sector are actively recruiting and which roles are being filled
- Compensation benchmarking — collect real pay ranges to calibrate hiring budgets or negotiate salaries with data
- Talent pipeline automation — surface new postings matching specific criteria automatically without checking the site manually
- Academic & economic research — build reproducible labor-market datasets for longitudinal studies
- Job board aggregation — sync ZipRecruiter listings into your own platform, app, or internal tool
Running on the Apify platform gives you built-in scheduling, monitoring, API access, proxy rotation, and integrations with tools like Google Sheets, BigQuery, Zapier, and Make — all without managing any infrastructure.
How to scrape ZipRecruiter jobs
Step-by-step tutorial
- Click "Try for free" at the top of this page to open the actor in Apify Console
- Enter your search — type a job title or keywords (e.g.
data engineer) in Job title / keywords, or provide a Multiple searches JSON array to run several keyword/location pairs in one go - Set a location — enter a city and state (e.g.
Austin, TX). The actor resolves the nearest matching location automatically via ZipRecruiter's autocomplete API - Apply filters — use the dropdowns to narrow by remote type, posting date, employment type, experience level, or apply type; set minimum and maximum salary if needed
- Configure pagination — set Max pages to control how many result pages are scraped per search; each page contains up to 20 jobs
- Click Start — a single-page run typically completes in under 30 seconds
- Download your data — open the Dataset tab and export as JSON, CSV, Excel, or JSONL; or access results programmatically via the Apify API
Input configuration
All fields are optional except search and location (unless searches is provided, in which case both are optional).
| Field | Type | Default | Description |
|---|---|---|---|
search | String | software engineer | Job title or keywords for a single search |
location | String | Miami, FL | City and state or region (e.g. New York, NY) |
searches | Array | [] | Multiple searches in one run — see format below; overrides search and location |
radius | Select | 25 miles | Search radius: 5, 10, 25, 50, or 100 miles |
remote | Select | All | Work location: Remote, Hybrid, or On-site |
datePosted | Select | Anytime | Recency: within 1, 5, 10, or 30 days |
minimumSalary | Integer | (none) | Minimum annual salary in USD (0–195,000) |
maximumSalary | Integer | (none) | Maximum annual salary in USD |
employmentType | Select | All | Full-time, Part-time, Contract, As-needed, Temporary, or Other |
experienceLevel | Multi-select | All | Junior, Mid, Senior, or No experience — combine freely |
applyType | Select | All | Quick apply only or all apply types |
maxResults | Integer | (none) | Hard cap on total results returned across all searches |
maxPages | Integer | 4 | Pages to scrape per search (each page = up to 20 jobs) |
startPage | Integer | 1 | Page number to start from (useful for resuming runs) |
Example input — single search
{"search": "data engineer","location": "New York, NY","radius": "25","remote": "only_remote","datePosted": "10","minimumSalary": 100000,"employmentType": "employment_type:full_time","experienceLevel": ["mid", "senior"],"maxPages": 5}
Example input — multiple searches
Use the searches field to run several keyword/location pairs in one execution. Each item requires a search key; location is optional and falls back to the top-level location field when omitted.
{"searches": [{ "search": "software engineer", "location": "Miami, FL" },{ "search": "data analyst", "location": "Austin, TX" },{ "search": "product manager", "location": "New York, NY" }],"radius": "25","maxPages": 3,"maxResults": 150}
Every result item includes a search_query and search_location field so you can tell at a glance which search produced each listing.
What data does ZipRecruiter Jobs Scraper return?
Results are stored in the Dataset tab and can be downloaded in JSON, CSV, Excel, or JSONL format. You can also query them via the Apify API or push them to any downstream tool.
Output example
{"search_query": "software engineer","search_location": "Miami, FL","extraction_date": "05-20-2026","extraction_datetime": "2026-05-20T14:32:07Z","source": "ZipRecruiter","title": "Senior Agentic (AI) Engineer","snippet": "5+ years of software engineering experience, with 2+ years building production LLM or agentic systems...","company_name": "Worth AI","company_url": "https://www.ziprecruiter.com/co/Worth-AI/Jobs","company_logo_url": null,"location_city": "Miami","location_state": "FL","location_country": "US","location_display": "Miami, FL","is_remote": true,"location_types": ["LOCATION_TYPE_NAME_REMOTE"],"employment_types": ["EMPLOYMENT_TYPE_NAME_FULL_TIME"],"employment_types_display": "Full-time","pay_min_annual": 107000,"pay_max_annual": 146900,"pay_display_short": "$107K - $147K / yr","pay_visible": true,"is_estimated_pay": true,"pay_source": "SOURCE_PREDICTED","benefits": ["BENEFIT_TYPE_NAME_MEDICAL", "BENEFIT_TYPE_NAME_DENTAL", "BENEFIT_TYPE_NAME_VISION"],"benefits_display": "Medical, Dental, Vision, Life, Retirement, PTO","posted_at_utc": "2026-05-15T16:48:33Z","posted_at_display": "4 days ago","first_seen_days_ago": 4,"is_new_job": true,"has_zip_apply": true,"is_external_apply": false,"apply_url": null,"job_page_url": "https://www.ziprecruiter.com/c/Worth-AI/Job/Senior-Agentic-(AI)-Engineer/-in-Miami,FL?jid=cc6bceaf667e789d"}
Output field reference
| Field | Type | Description |
|---|---|---|
search_query | String | Keyword used to find this listing (mirrors the search input) |
search_location | String | Location used to find this listing (mirrors the location input) |
extraction_date | String | Date the item was scraped, formatted as MM-DD-YYYY |
extraction_datetime | String | UTC timestamp of when the item was scraped (ISO 8601) |
title | String | Job title as listed |
snippet | String | Short description excerpt (may contain HTML fragments) |
company_name | String | Employer name |
company_url | String | Employer's page on ZipRecruiter |
company_logo_url | String | null | Employer logo image URL |
location_city | String | City |
location_state | String | State code (e.g. FL) |
location_country | String | Country code (e.g. US) |
location_display | String | Human-readable City, State label |
is_remote | Boolean | true when the job is remote |
location_types | Array | Location type codes (e.g. LOCATION_TYPE_NAME_REMOTE) |
employment_types | Array | Employment type codes |
employment_types_display | String | Human-readable employment type (e.g. Full-time) |
pay_min_annual | Number | null | Minimum annual salary in USD |
pay_max_annual | Number | null | Maximum annual salary in USD |
pay_display | String | null | Raw pay string from ZipRecruiter |
pay_display_short | String | null | Cleaned pay range (e.g. $120K - $160K / yr) |
pay_visible | Boolean | Whether pay is publicly shown |
is_estimated_pay | Boolean | true when salary is ZipRecruiter's estimate, not employer-provided |
pay_source | String | SOURCE_PROVIDED or SOURCE_PREDICTED |
benefits | Array | Benefit type codes when listed |
benefits_display | String | null | Human-readable benefit summary |
posted_at_utc | String | ISO 8601 UTC posting timestamp |
posted_at_display | String | Relative time string (e.g. 4 days ago) |
first_seen_days_ago | Integer | null | Days since posting (calculated at scrape time) |
is_new_job | Boolean | true when posted within the last 7 days |
has_zip_apply | Boolean | true when ZipRecruiter Quick Apply is available |
is_external_apply | Boolean | true when applying redirects to an external site |
apply_url | String | null | External application URL when is_external_apply is true |
job_page_url | String | Full ZipRecruiter listing URL |
listing_key | String | ZipRecruiter's unique listing identifier |
Advanced tips
Combine filters for precision targeting
Every filter you enable is applied by ZipRecruiter's own search engine before the actor paginates — so results are already scoped. Stacking remote: only_remote + datePosted: 1 + employmentType: full_time returns only postings that satisfy all three conditions simultaneously, shrinking the dataset to exactly the signal you need.
Monitor a market segment with scheduling
Connect this actor to Apify Scheduler to run daily or weekly searches automatically. Pair it with a Webhook to push new results to Slack, a Google Sheet, or your own API the moment each run completes — ideal for maintaining a live recruiting feed or salary tracker.
Run multiple searches in one go
Pass a searches array to execute several keyword/location combinations in a single run. All results land in the same dataset, each tagged with search_query and search_location so grouping and filtering downstream is trivial. Pair with maxResults to set a hard cap across the whole batch.
Filter out estimated salaries
The is_estimated_pay field is true whenever ZipRecruiter computed the salary rather than the employer providing it. When building compensation benchmarks, filter to is_estimated_pay == false (or pay_source == "SOURCE_PROVIDED") to work only with employer-disclosed figures.
Integrate with your stack
Results are immediately available via the Apify API and can be streamed to Google Sheets, BigQuery, Snowflake, Zapier, or Make without any custom glue code. The Apify platform's native integrations handle auth, pagination, and format conversion.
FAQ, legal disclaimer, and support
Is scraping ZipRecruiter legal?
This actor accesses only publicly available job listings — the same information visible to any unauthenticated visitor in a browser. Scraping publicly accessible web data is broadly lawful under U.S. case law (see hiQ Labs v. LinkedIn, 9th Circuit 2022) and in most other jurisdictions.
That said, you are responsible for using this tool in compliance with ZipRecruiter's Terms of Service, applicable data protection regulations (GDPR, CCPA), and any laws in your jurisdiction. This actor is intended for legitimate research, analytics, and business intelligence purposes only. Do not use it to collect personal data about individual job seekers or to circumvent access controls.
Why are some runs returning fewer results than expected?
Active filters reduce the result pool on ZipRecruiter's end before pagination. A combination of senior + full_time + posted within 1 day + only_remote in a specific city may legitimately surface fewer than 20 results. Try broadening the radius, relaxing one filter, or switching datePosted to Posted anytime to confirm whether your filters are simply returning a small natural result set.
Do I need to configure a proxy?
No. Residential proxy rotation is built in and always active — there is nothing to configure. ZipRecruiter uses Cloudflare bot protection, and rotating residential IPs is what keeps results reliable at scale. You never need to supply your own proxy credentials.
Can I run several searches at once?
Yes — natively. Pass a searches array to run multiple keyword/location pairs in a single execution. Each result is tagged with search_query and search_location, so grouping results by search is immediate. Use maxResults to set a hard cap across the whole batch, or maxPages to control depth per search.
Something isn't working or I need a custom solution
Open an issue in the Issues tab on this page with your input configuration, any error messages, and a sample URL if available. For bespoke data pipelines, large-scale recurring jobs, or custom output formats, feel free to reach out directly through the Issues tab.