# Indeed Jobs Scraper (`itamartoledano/indeed-jobs-scraper`) Actor

Scrape Indeed.com job search results by URL. Get title, company, rating, location, remote type, salary range, job types, benefits, snippet, post date, and job & apply links, one item per job. Full description for the vjk job. Proxy support and security-check retries.

- **URL**: https://apify.com/itamartoledano/indeed-jobs-scraper.md
- **Developed by:** [Itamar Toledano](https://apify.com/itamartoledano) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.70 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Indeed Jobs Scraper

### What is Indeed Jobs Scraper and how does it work?

**Indeed Jobs Scraper** is an Apify Actor that extracts structured job listings from an Indeed.com job search page.

Paste an Indeed search URL, configure a proxy, and run the Actor. It fetches the page with a browser-like HTTP client, reads the job data Indeed embeds in the page, and stores **one dataset item per job**. You can download the results from the dataset or pull them through the Apify API.

Indeed search URLs look like this:

```text
https://www.indeed.com/jobs?q=google&l=&from=searchOnDesktopSerp&vjk=13fa6ca701bacefe
```

The host must be `www.indeed.com`, the path must be `/jobs`, and the URL needs a keyword (`q`), a location (`l`), or both. Other Indeed filters in the query string (job type, date posted, remote, radius, sort…) are passed through as-is, so the easiest way to build a URL is to search on Indeed and copy it from the address bar.

> The job opened in Indeed's right-hand pane (the `vjk` parameter) also gets its **full description** and complete benefits list. Other jobs get the short card snippet.

### Why scrape Indeed?

- **Job market research**: which companies are hiring for a role or in a city, and how many openings they post
- **Salary benchmarking**: salary text plus numeric min/max and pay period (yearly, hourly…)
- **Lead generation**: find companies that are actively hiring
- **Remote work tracking**: remote / hybrid flags per job
- **Job aggregation**: feed fresh listings into your own job board or alerts

### What data can Indeed Jobs Scraper extract?

| Data | Fields |
| --- | --- |
| Search | `input`, `search_query`, `search_location`, `page_number`, `position` |
| Job | `job_id`, `job_title`, `normalized_title`, `job_types`, `shifts`, `benefits` |
| Company | `company_name`, `company_rating`, `company_reviews_count`, `company_url` |
| Location | `location`, `country`, `is_remote`, `remote_type` |
| Salary | `salary_text`, `salary_min`, `salary_max`, `salary_type`, `salary_currency`, `salary_is_estimated` |
| Content | `snippet`, `description`, `description_html`, `has_full_description` |
| Dates | `posted_relative`, `posted_at`, `fetched_at` |
| Links | `job_url`, `apply_url` |
| Flags | `is_indeed_apply`, `is_sponsored`, `is_urgently_hiring`, `is_new`, `is_expired` |

**Salary note:** when the employer doesn't publish pay, Indeed sometimes shows its own estimate. Those jobs have `salary_is_estimated: true`.

### How many results can you scrape?

Each run scrapes **one search results page**, which is usually 15–20 jobs. Duplicate job cards on the page are removed.

Indeed requires signing in to see later pages (`&start=10` and beyond), so only the **first page** is supported. To cover more jobs, narrow your searches: run one per keyword, location, job type, or date-posted filter.

### How much will it cost?

Cost depends on compute, proxy traffic, and retries. Each run makes a single page request, so it is cheap. Run a few searches first, note the cost per run, and multiply by the number of searches you plan to run.

### Is it legal to scrape Indeed?

Scraping **publicly available** job listings is generally considered legal, but job posts can contain personal data such as recruiter names. Review Indeed's terms and your own compliance requirements (e.g. GDPR). See Apify's post on the [legality of web scraping](https://blog.apify.com/is-web-scraping-legal/).

### How do I scrape jobs on Indeed?

1. Search for jobs on [indeed.com](https://www.indeed.com) and copy the URL from the address bar
2. Open **Indeed Jobs Scraper** in Apify Console and paste it into `url`
3. Keep the default proxy (Apify residential, US) or pick your own
4. Click **Start**
5. Open the **Dataset** tab when the run finishes

#### Tips

- Indeed shows "Security Check" pages to datacenter traffic. Residential US proxies work best.
- Security-check pages are detected and retried automatically (default up to 4 attempts).
- Click a job on Indeed before copying the URL to include its `vjk`. That job then comes back with its full description.

### Input

| Field | Required | Description |
| --- | --- | --- |
| `url` | Yes | HTTPS Indeed search URL (`www.indeed.com/jobs?q=…&l=…`) |
| `proxyConfiguration` | Recommended | Apify Proxy or custom proxy URLs |

```json
{
  "url": "https://www.indeed.com/jobs?q=google&l=&from=searchOnDesktopSerp&vjk=13fa6ca701bacefe",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": ["RESIDENTIAL"],
    "apifyProxyCountry": "US"
  }
}
```

### Sample output

One item per job:

```json
{
  "source": "indeed",
  "input": "https://www.indeed.com/jobs?q=google&l=&from=searchOnDesktopSerp&vjk=13fa6ca701bacefe",
  "search_query": "google",
  "search_location": null,
  "page_number": 1,
  "position": 16,
  "job_id": "13fa6ca701bacefe",
  "job_title": "Software Engineer III, Google Distributed Cloud, Connected",
  "normalized_title": "Senior Software Engineer",
  "company_name": "Google",
  "company_rating": 4.3,
  "company_reviews_count": 6269,
  "company_url": "https://www.indeed.com/cmp/Google",
  "location": "Seattle, WA",
  "country": "US",
  "is_remote": false,
  "remote_type": null,
  "salary_text": "$147,000 - $210,000 a year",
  "salary_min": 147000,
  "salary_max": 210000,
  "salary_type": "yearly",
  "salary_currency": "USD",
  "salary_is_estimated": false,
  "job_types": ["Full-time"],
  "shifts": [],
  "benefits": ["Parental leave", "Health insurance", "401(k) matching", "Paid time off", "Vision insurance", "Dental insurance", "Disability insurance", "Paid holidays"],
  "snippet": "Health, dental, vision, life, disability insurance. Retirement Benefits: 401(k) with company match…",
  "description": "In accordance with Washington state law, we are highlighting our comprehensive benefits package…",
  "description_html": "<div>In accordance with Washington state law, …</div>",
  "has_full_description": true,
  "posted_relative": "Just posted",
  "posted_at": "2026-09-29T05:00:00Z",
  "job_url": "https://www.indeed.com/viewjob?jk=13fa6ca701bacefe",
  "apply_url": "https://www.indeed.com/applystart?jk=13fa6ca701bacefe&…",
  "is_indeed_apply": false,
  "is_sponsored": false,
  "is_urgently_hiring": false,
  "is_new": true,
  "is_expired": false,
  "fetched_at": "2026-09-29T16:47:53.511237Z"
}
```

Jobs other than the `vjk` one have `description: null`, `description_html: null`, and `has_full_description: false`. Their `benefits` come from the job card.

### Integrations

Connect Indeed Jobs Scraper to Make, Zapier, Slack, Google Sheets, Airbyte, GitHub, and more through [Apify integrations](https://apify.com/integrations), or trigger actions with [webhooks](https://docs.apify.com/integrations/webhooks) when a run finishes.

### Using the Apify API

Run the Actor and fetch results programmatically with the [Apify API](https://docs.apify.com/api/v2), using [`apify-client`](https://www.npmjs.com/package/apify-client) for Node.js or [`apify-client`](https://pypi.org/project/apify-client/) for Python. See the **API** tab for code examples.

### FAQ

#### Does it scrape other Indeed countries (uk.indeed.com, ca.indeed.com…)?

Not yet. Only `www.indeed.com` search URLs are accepted.

#### Why do most jobs have no full description?

Indeed's search page only includes the full description for the job opened in the side pane (`vjk`). The others come with the short card snippet.

#### Why does a URL with `&start=10` fail?

Indeed redirects logged-out visitors to its sign-in page for every results page after the first, so the Actor rejects those URLs up front.

#### What happens when Indeed shows a "Security Check"?

The page is missing the job-card data, so the Actor treats it as a bot check, retries, and fails the run if every attempt is blocked. Switching to residential proxies usually fixes it. A search that genuinely has no results finishes successfully with an empty dataset.

### Your feedback

Found a bug or have a feature request? Open an issue on the Actor's **Issues** tab in Apify Console.

# Actor input Schema

## `url` (type: `string`):

HTTPS Indeed job search URL. Host must be www.indeed.com, the path must be /jobs, and it needs a keyword (q) and/or location (l). Only the first results page is supported (Indeed requires sign-in for later pages). Add \&vjk=<job key> to also get that job's full description.

## `proxyConfiguration` (type: `object`):

Select Apify Proxy groups/country or provide custom proxy URLs. Indeed shows security checks to datacenter traffic, so residential US proxies are recommended. See https://docs.apify.com/sdk/python/docs/concepts/proxy-management

## Actor input object example

```json
{
  "url": "https://www.indeed.com/jobs?q=google&l=&from=searchOnDesktopSerp&vjk=13fa6ca701bacefe",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

## `dataset` (type: `string`):

One item per job (job\_id, job\_title, company, location, salary, job types, benefits, links, etc.).

# 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 = {
    "url": "https://www.indeed.com/jobs?q=google&l=&from=searchOnDesktopSerp&vjk=13fa6ca701bacefe",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("itamartoledano/indeed-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 = {
    "url": "https://www.indeed.com/jobs?q=google&l=&from=searchOnDesktopSerp&vjk=13fa6ca701bacefe",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

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

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

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

```

## CLI example

```bash
echo '{
  "url": "https://www.indeed.com/jobs?q=google&l=&from=searchOnDesktopSerp&vjk=13fa6ca701bacefe",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call itamartoledano/indeed-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,itamartoledano/indeed-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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