# ZipRecruiter Jobs Scraper (`khadinakbar/ziprecruiter-jobs-scraper`) Actor

Search public US ZipRecruiter listings by keyword, location, or a public search URL. Returns validated job records for talent intelligence and labor-market research.

- **URL**: https://apify.com/khadinakbar/ziprecruiter-jobs-scraper.md
- **Developed by:** [Khadin Akbar](https://apify.com/khadinakbar) (community)
- **Categories:** Jobs, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 ziprecruiter job record scrapeds

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## ZipRecruiter Jobs Scraper

ZipRecruiter Jobs Scraper is an Apify Actor for searching public US ZipRecruiter listings by keyword, location, or a public ZipRecruiter search URL. It accepts a job search phrase and a place name, or a ZipRecruiter search link, and returns one dataset record per public job listing. Each record can include job title, company name, location, remote flag, employment type, description, salary text and parsed salary fields when publicly exposed, posting time, canonical job URL, application URL when exposed, source URL, and scrape time. The outcome is a validated job dataset for talent intelligence and labor-market research.

### Best fit and connected workflows

This Actor fits workflows that start with a public job-market question and end with structured records ready for analysis, review, or downstream automation.

Common routing patterns:

- Recruitment research by role and location, such as a keyword search for a specific skill set in a city or Remote.
- Labor-market monitoring that compares job titles, compensation text, employment types, and posting recency.
- Hiring intelligence pipelines that enrich public job listings before feeding them into dashboards or internal review steps.
- Lead-generation-style workflows that use public job posting signals to identify active employers and roles.

Related Apify Actors:

- Use [APEC Jobs Scraper](https://apify.com/khadinakbar/apec-jobs-scraper) - a good alternative when the research brief matches that job board, geography, or audience.
- Use [Ashby Jobs Scraper](https://apify.com/khadinakbar/ashby-jobs-scraper) - a good alternative when the research brief matches that job board, geography, or audience.
- Use [Bayt Jobs Data Scraper for MENA Listings](https://apify.com/khadinakbar/bayt-jobs-scraper) - a good alternative when the research brief matches that job board, geography, or audience.

### Practical scenario

Maya is a talent researcher tracking software engineering demand in Austin, TX. She starts with the keyword `senior data engineer`, location `Austin, TX`, and a cap of 25 records. The dataset returns fields like `title`, `companyName`, `salaryText`, `salaryMin`, `salaryMax`, `postedAt`, and `jobUrl`. Maya uses those fields to compare active employers and compensation ranges, then sends the canonical `jobUrl` list into an internal review sheet for follow-up.

### Input

The Actor accepts these input fields:

| Field | Type | Purpose |
| --- | --- | --- |
| `keywords` | string | Free-text job search terms, such as `senior data engineer`. Defaults to `software engineer`. |
| `location` | string | Place name for the search, such as `Austin, TX` or `Remote`. Defaults to `Remote`. |
| `startUrls` | array | Optional public ZipRecruiter search URLs. When provided, they override keyword-built search. |
| `maxResults` | integer | Hard cap on persisted job records. Accepts 1 to 100. |
| `includeJobDetails` | boolean | Visits selected public job pages to improve description, compensation, and employment-type coverage when available. Defaults to `true`. |

Focused JSON input example:

```json
{
  "keywords": "senior data engineer",
  "location": "Remote",
  "startUrls": [
    {
      "url": "https://www.ziprecruiter.com/jobs-search?search=data+engineer&location=Remote"
    }
  ],
  "maxResults": 25,
  "includeJobDetails": true
}
```

### Output

One dataset record represents one public ZipRecruiter job listing. The Actor writes validated records to the default dataset and also exposes machine-readable execution artifacts in the default key-value store.

| Field | Type | Purpose |
| --- | --- | --- |
| `jobId` | string | Stable identifier from the public listing or canonical public job URL. |
| `title` | string | Public job title. |
| `companyName` | string or null | Hiring organization when exposed. |
| `location` | string or null | Public location text. |
| `isRemote` | boolean or null | Remote indicator when the listing states it. |
| `employmentType` | string or null | Public employment type such as `FULL_TIME` or `Contract` when exposed. |
| `description` | string or null | Public job description or teaser normalized to plain text. |
| `salaryText` | string or null | Salary text shown on the public listing. |
| `salaryMin` | number or null | Parsed lower salary bound when safely available. |
| `salaryMax` | number or null | Parsed upper salary bound when safely available. |
| `salaryCurrency` | string or null | Currency code inferred from public salary text. |
| `salaryPeriod` | string or null | Pay period inferred from public salary text. |
| `postedAt` | string or null | ISO 8601 posting timestamp when publicly exposed. |
| `postedText` | string or null | Human-readable recency text shown by ZipRecruiter. |
| `applyUrl` | string or null | Public application or destination URL when exposed. |
| `jobUrl` | string | Canonical public ZipRecruiter job URL. |
| `sourceUrl` | string | Search or detail URL from which the record was collected. |
| `scrapedAt` | string | ISO 8601 collection time. |

Illustrative output record:

```json
{
  "jobId": "J3V4B26MF8XNC1W2TQP",
  "title": "Senior Software Engineer",
  "companyName": "Example Company",
  "location": "Austin, TX",
  "isRemote": true,
  "employmentType": "FULL_TIME",
  "description": "Build reliable web services and developer tools.",
  "salaryText": "$120,000 - $160,000 annually",
  "salaryMin": 120000,
  "salaryMax": 160000,
  "salaryCurrency": "USD",
  "salaryPeriod": "year",
  "postedAt": "2026-07-18T00:00:00.000Z",
  "postedText": "Posted 2 days ago",
  "applyUrl": "https://www.ziprecruiter.com/c/Example/Job/Senior-Software-Engineer/-in-Austin,TX",
  "jobUrl": "https://www.ziprecruiter.com/c/Example/Job/Senior-Software-Engineer/-in-Austin,TX",
  "sourceUrl": "https://www.ziprecruiter.com/jobs-search?search=software+engineer&location=Remote",
  "scrapedAt": "2026-07-19T14:30:00.000Z"
}
```

### How it works

This Actor uses a residential Camoufox browser session to search public US ZipRecruiter listings. It supports two routing modes: keyword-plus-location search, or direct collection from public ZipRecruiter search URLs. When `includeJobDetails` is enabled, it visits selected public job pages to improve the available description, compensation, and employment-type fields. It persists validated job records to the dataset and records execution artifacts in key-value storage for automation-friendly readback.

### Pricing

ZipRecruiter Jobs Scraper uses Pay per event plus Apify platform usage. The billed event types are:

- Actor start
- ZipRecruiter job record scraped

The `job-scraped` event is charged only when one complete, validated job record is persisted to the dataset. The start event is charged once per run and is scaled by allocated memory. For example, a run that persists twenty job records charges twenty job-scraped events plus one start event. Apify platform usage is billed separately, and the live Pricing tab is the current source of truth for the complete charge configuration.

### Use with AI agents (MCP)

This Actor is usable through Apify MCP as a tool for collecting structured public ZipRecruiter job data. The exact Actor identity is `khadinakbar/ziprecruiter-jobs-scraper`.

Tool description:

- Search public US ZipRecruiter listings by keyword, location, or public search URL.
- Return validated dataset records with provenance fields such as `sourceUrl` and `scrapedAt`.
- Support bounded collection with `maxResults` and optional job-page enrichment via `includeJobDetails`.

> Collect up to 25 public ZipRecruiter listings for "data engineer" in Remote using `khadinakbar/ziprecruiter-jobs-scraper`. Return the dataset rows and summarize title, company, location, salary text, salary bounds when present, posting time, and canonical job URL. Preserve `sourceUrl` and `scrapedAt` for each record.

Output interpretation:

- Use `jobUrl` as the canonical public listing route.
- Use `sourceUrl` to trace the exact search or detail page that produced each record.
- Use `scrapedAt` to understand collection time.
- Use `salaryText` for the public salary display, and `salaryMin` / `salaryMax` when the text can be parsed safely.
- Use `postedAt` or `postedText` for recency analysis.

Scope and pagination:

- `maxResults` is a hard cap on persisted job records.
- `startUrls` can target public ZipRecruiter search pages directly.
- The Actor returns one record per persisted job listing, so downstream tools can process the dataset row by row.
- Pricing is event-based, so larger caps generally mean more job-scraped events. Check the live Pricing tab before running a large collection.

### API example

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({
  token: process.env.APIFY_TOKEN,
});

const run = await client.actor('khadinakbar/ziprecruiter-jobs-scraper').call({
  keywords: 'product manager',
  location: 'New York, NY',
  maxResults: 20,
  includeJobDetails: true,
});

const datasetId = run.defaultDatasetId;
const { items } = await client.dataset(datasetId).listItems();

console.log(items);
```

### Best results and outcome guidance

- Use a clear role phrase, such as a job title or skill cluster, for cleaner search results.
- Pair the keyword with a city/state or `Remote` to keep the search focused.
- Start with a smaller `maxResults` value when validating a new query shape.
- Turn on `includeJobDetails` when you want richer public fields like description or salary text.
- Use a public ZipRecruiter search URL in `startUrls` when you already have a search page you want to reproduce.

### Design note

I found that the dataset contract marks `jobId`, `title`, `jobUrl`, `sourceUrl`, and `scrapedAt` as required, which makes provenance and canonical linking part of every record.

### FAQ

#### When should I use keywords and location instead of `startUrls`?

Use `keywords` and `location` when you want a fresh search built from a role phrase and place name. Use `startUrls` when you already have a public ZipRecruiter search page and want the Actor to collect from that exact route.

#### What does one dataset record represent?

One dataset record represents one public ZipRecruiter job listing. It is a validated row with a canonical job URL and source provenance.

#### Which fields are most useful for labor-market analysis?

`title`, `companyName`, `location`, `isRemote`, `employmentType`, `salaryText`, `salaryMin`, `salaryMax`, `postedAt`, and `jobUrl` are the most common analysis fields.

#### Can this Actor be used in an AI agent workflow?

Yes. It is usable through Apify MCP and returns structured public job data that agents can read back from the dataset.

#### How do I estimate cost before a run?

Set `maxResults`, then check the live Pricing tab for the current event configuration. Event charges are tied to the run start and each persisted job record.

### Responsible use

Use this Actor for lawful collection and analysis of publicly available job-listing data, in line with applicable law, data-protection obligations, and ZipRecruiter's terms.

# Actor input Schema

## `keywords` (type: `string`):

Free-text terms sent to ZipRecruiter job search, such as 'senior data engineer'. Enter a role, skill, or phrase; the default is 'software engineer'. It accepts at most 120 characters. This is not a job URL or a company-only lookup.

## `location` (type: `string`):

Place name used with the keyword search, for example 'Austin, TX' or 'Remote'. Leave it blank to let ZipRecruiter choose its normal US search scope. The default is 'Remote'. This is not an ISO country code or a precise radius setting.

## `startUrls` (type: `array`):

Optional public ZipRecruiter search URLs to scrape directly, for example 'https://www.ziprecruiter.com/jobs-search?search=data+engineer\&location=Remote'. Each URL must use a ZipRecruiter domain and overrides the keyword-built search when supplied. Leave it empty for the standard keyword mode. This is not for individual job pages or non-ZipRecruiter URLs.

## `maxResults` (type: `integer`):

Hard cap on persisted jobs and per-job event charges. Enter an integer from 1 to 100, for example 25. The default is 10 and the maximum event cost is shown before collection starts. This is not a page count and cannot produce more than 100 records.

## `includeJobDetails` (type: `boolean`):

Visit each selected public job page to improve description, compensation, and employment-type coverage when ZipRecruiter exposes it. Set true for richer records or false for faster listing-only results. The default is true. This does not bypass login, application, or account walls.

## Actor input object example

```json
{
  "keywords": "senior data engineer",
  "location": "Austin, TX",
  "startUrls": [
    {
      "url": "https://www.ziprecruiter.com/jobs-search?search=data+engineer&location=Remote"
    }
  ],
  "maxResults": 25,
  "includeJobDetails": true
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `output` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "keywords": "software engineer",
    "location": "Remote",
    "maxResults": 1,
    "includeJobDetails": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("khadinakbar/ziprecruiter-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "keywords": "software engineer",
    "location": "Remote",
    "maxResults": 1,
    "includeJobDetails": False,
}

# Run the Actor and wait for it to finish
run = client.actor("khadinakbar/ziprecruiter-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "keywords": "software engineer",
  "location": "Remote",
  "maxResults": 1,
  "includeJobDetails": false
}' |
apify call khadinakbar/ziprecruiter-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=khadinakbar/ziprecruiter-jobs-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/mviq48L01UkzQVxdL/builds/re86Up0LaSo2JSqUR/openapi.json
