ZipRecruiter Scraper - US Jobs and Salaries
Pricing
from $2.00 / 1,000 jobs
ZipRecruiter Scraper - US Jobs and Salaries
Search US ZipRecruiter jobs by keyword and location or filtered search URLs. Get company, posting date, visible salary ranges with annualized pay, benefits and remote flags as structured rows for recruiters, staffing teams and salary research.
ZipRecruiter Scraper
ZipRecruiter Scraper turns US job searches into structured listings for recruiters, staffing teams and salary research. Search by keyword and location, or use your existing filtered ZipRecruiter search URLs. Each row includes the job identity, canonical link, title, company, location, posting dates and the salary information visible on the search card, with hourly pay also converted to an annual figure.
What ZipRecruiter Scraper collects
The actor returns one row per unique job, following the order of the search results. You can compare employers, track advertised openings, collect remote roles and analyze stated pay without manually copying individual cards. The same stable job identifier helps you compare separate runs. Export the default dataset as JSON, CSV or Excel, or read it through the Apify dataset API for your recruitment workflow.
A row contains the original publication timestamp separately from the refresh timestamp. This matters when a long-running advertisement appears near the top after being refreshed. Use posted_at to analyze original publication dates and refreshed_at when you want to inspect the date associated with the card's relative age.
ZipRecruiter Scraper input
Supply search with location, or supply start_urls. For a keyword search, the location must be a US city, state or ZIP code. Use Remote for a nationwide search for remote opportunities. An empty location is rejected because it would not define the geographic scope of your request. The remote search location does not guarantee that every returned row has the same workplace arrangement; inspect each row's labels.
For example, the following input matches a collected Austin search:
{"search": "software engineer","location": "Austin, TX","limit": 20}
Set limit to the total number of unique jobs you want, from 1 to 1000. The default is 50, shared across all search URLs in the request. The actor collects additional pages automatically and removes duplicate listing identifiers before delivery. If the source has fewer jobs, you receive the available unique listings.
For keyword searches you can add days with 1, 3, 5, 10 or 30; radius in miles from 1 to 500; remote_only; and employment_type: "full_time". The days filter follows the source's search behavior and may reflect a refreshed advertisement rather than the original posting date. Other employment filters can be carried in an existing source search URL.
With start_urls, include full HTTPS search URLs from www.ziprecruiter.com/jobs-search containing a nonempty search and location. Supply up to twenty URLs. Existing filters remain in place, and collection starts from page one even if the URL contains a page number. Keep URL filters in the URL instead of adding separate filter input fields.
This filtered URL input collected twenty full-time data analyst listings in Chicago on 6 October 2026. It has no posting-age window, so older advertisements remain eligible:
{"start_urls": ["https://www.ziprecruiter.com/jobs-search?search=data+analyst&location=Chicago%2C+IL&refine_by_employment=employment_type%3Afull_time"],"limit": 20}
The aliases query, keyword and searchJobKeyword are accepted for search; searchLocation for location; maxItems and max_items for limit; and startUrls for URLs. The latter also accepts objects containing a url field. daysPosted, radiusMiles and remoteOnly are additional filter aliases. The canonical input name takes precedence if you supply both versions.
Output: ZipRecruiter jobs and salary data
The dataset contains job_id, zip_job_id, url, title, company, company_url, company_logo_url, location, location_full, city, state, state_code, postal_code and country_code. Every row also carries source, platform and fetched_at, so you can identify its origin and collection time in combined datasets.
Some remote listings have no location information. Those jobs remain in the dataset with null location fields, while is_remote follows the source's workplace labels. The canonical url is also null when the card does not provide one. A listing explicitly marked with a country outside the US is skipped with a warning.
This excerpt is from an actual remote copywriter search collected on 6 October 2026. The search reported 336 jobs; 19 of the 20 cards on the first page carried a US location, and this one carried none:
{"job_id": "mGPfwjF67evNQrDYdKFp3Q","title": "Copywriter","url": null,"company": "Frontline Strategies","location": null,"city": null,"state_code": null,"country_code": null,"posted_at": "2026-08-27T00:02:33Z","refreshed_at": "2026-09-26T00:02:33Z","employment_type": "FULL_TIME","benefits": ["medical", "vision", "dental", "paid_time_off", "retirement"],"workplace_types": ["remote"],"is_remote": true,"easy_apply": true}
This excerpt is from the actual Austin response collected on 5 October 2026. That search reported 581 matching jobs; the first page of 20 contained 12 cards with a visible salary.
{"job_id": "jY6iEud1OO3vXCDLlk-jJw","title": "Software Engineer - AI Trainer","company": "DataAnnotation","location": "Austin, TX","posted_at": "2026-10-02T21:35:03Z","salary_min": 75,"salary_max": 150,"salary_period": "HOUR","salary_currency": "USD","salary_min_annual": 150000,"is_remote": true,"url": "https://www.ziprecruiter.com/c/DataAnnotation/Job/Software-Engineer-AI-Trainer/-in-Austin,TX?jid=951b3f57fcde473c"}
A second row from the same response shows a yearly salary parsed from the posting, the benefits list and an on-site role:
{"job_id": "4IdarCj6ctPN4k2THJXVdg","title": "Senior Software Engineer- PaaS Engineering","company": "Visa","location": "Austin, TX","posted_at": "2026-09-16T15:27:00Z","salary_min": 110700,"salary_max": 110700,"salary_period": "YEAR","salary_source": "parsed","salary_is_estimated": false,"employment_type": "FULL_TIME","benefits": ["medical", "vision", "dental", "paid_time_off", "life_insurance", "retirement"],"workplace_types": ["in_person"],"is_remote": false}
Date fields include posted_at, refreshed_at and posted_ago. Employment information includes the first employment_type, the full employment_types list, workplace_types, is_remote, is_hybrid, benefits, easy_apply and is_active. The short_description field is the search-card teaser, not a complete job description. Search context and position fields (search, search_location, search_url, page, position) help you connect each listing to the request that collected it.
Salary fields are salary_min, salary_max, salary_currency, salary_period, salary_min_annual, salary_max_annual, salary_text, salary_source and salary_is_estimated. Periods use HOUR, DAY, WEEK, MONTH or YEAR. The annualized amounts come from ZipRecruiter. They should be treated as the source's comparison values, rather than a promise about a candidate's actual annual earnings.
Only visible salary information is delivered. Employer-provided and text-parsed salaries have salary_is_estimated: false. A visible prediction has salary_is_estimated: true and salary_source: "predicted". When the card has no visible salary, all salary fields are null. This lets you exclude estimates or missing salaries from a pay comparison without confusing them with zero pay.
The filtered Chicago search above reported 137 matching jobs. Of the 20 rows it returned, 13 showed a salary and 2 of those were marked as estimates, like this one:
{"job_id": "E2jHyPZmYCDS5Q91ZT7x8w","title": "Sr. Data Analyst, e-Commerce Media Performance","company": "Central Garden & Pet","location_full": "Chicago, IL US 60654","posted_at": "2026-09-16T23:42:31Z","salary_text": "$88K - $111K/yr","salary_min": 88700,"salary_max": 111900,"salary_period": "YEAR","salary_source": "predicted","salary_is_estimated": true,"easy_apply": true,"search_url": "https://www.ziprecruiter.com/jobs-search?search=data+analyst&location=Chicago%2C+IL&refine_by_employment=employment_type%3Afull_time","position": 13}
Use cases for a ZipRecruiter scraper
- Recruiting and sourcing. Build a daily list of new openings for a role and city, then see which employers are hiring and how often they refresh their ads.
- Staffing agencies. Find companies with many open requisitions in your territory, including contract roles, and reach out while the demand is fresh.
- Salary research. Compare advertised hourly and yearly pay by title, state or employer. The annualized fields put hourly and yearly offers on one scale, and the source label separates employer pay from estimates.
- Labor market analysis. Track the share of remote and hybrid jobs, the spread of benefits and the age of postings across searches and over time, keyed on the stable
job_id. - Job boards and aggregators. Feed structured US listings with canonical links into your own search, alerts or matching pipeline.
Compared with other ways to get ZipRecruiter data
Copying cards by hand works for a few jobs, but not for a weekly salary benchmark across roles and cities. ZipRecruiter's own partner integrations require an agreement with ZipRecruiter and do not hand you a spreadsheet of search results. Open-source multi-board libraries cover several job sites, but you run, schedule and maintain them yourself, and they often flatten pay into one text field.
This actor focuses on ZipRecruiter job search in the United States and keeps the details that matter for pay analysis: minimum and maximum as numbers, the pay period, ZipRecruiter's annualized values, the salary source, and whether the figure is an estimate. It separates the original posting date from the refresh date, removes duplicate listings across pages and searches, and needs no login, cookies or browser extension. Results go straight into an Apify dataset, so you can schedule runs, call it as an API, or connect it to Google Sheets, Make, Zapier or a webhook. It does not fetch full job descriptions, apply links or company reviews.
Pricing
The actor uses pay-per-event pricing: one run-start event and one job event per delivered unique dataset row. The event prices are shown in the actor's Pricing tab. Duplicate listings do not create extra job events. A search with no results has zero job events; the run-start event still applies. Non-paying users receive at most ten rows per run. The total limit applies across searches, rather than separately to each URL, so a run with three search URLs and a limit of 50 is charged for at most 50 jobs.
FAQ
Is there an official ZipRecruiter API for job search data?
ZipRecruiter's partner integrations require an agreement with ZipRecruiter. This actor works as a ready-made ZipRecruiter jobs API: start it through the Apify API with a keyword and location, and read the results as JSON from the dataset.
Can I collect full job descriptions?
This version collects search-card information. short_description is a teaser. The actor does not fetch every individual job page to obtain the complete description, so workflows that require the full text should account for that limitation.
How are remote and hybrid jobs marked?
is_remote is true when the source marks the job as remote or remote optional. is_hybrid is true for a hybrid source label. The complete workplace_types list is also retained. A role may offer remote flexibility without being exclusively remote.
Why does a salary field contain null?
The card may not display pay, or the relevant source value may be absent. Hidden internal estimates are not returned as advertised salary. Null means unavailable salary information, and does not mean that the position is unpaid.
Does it work outside the United States?
No. The actor collects ZipRecruiter's US job search. A row has country_code: "US" when the source provides it, or null when the listing has no country information. Locations must be a US city, state, ZIP code or Remote.
Can I combine several searches?
Yes. Supply several search URLs and one total limit. Listing identifiers are deduplicated across the request. Keep individual searches focused when you want to compare locations or employers, because one shared limit can be reached before later searches are visited.
What happens if a later page cannot be collected?
Already collected jobs remain available. The response records partial collection with warnings and a continuation value when more work remains. Apify follows supported continuation requests automatically within its run budget. Job events count delivered rows rather than unreturned listings.