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

Scrape Indeed jobs from 62 countries with full descriptions, parsed salaries, employer apply links and company data. Gets past Indeed's 1,000-result limit.

- **URL**: https://apify.com/deltaspider/indeed-scraper.md
- **Developed by:** [delta spider](https://apify.com/deltaspider) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 5 total users, 2 monthly users, 99.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.07 / 1,000 jobs

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

### What does Indeed Jobs Scraper do?

It collects job listings from Indeed in 62 countries and returns them as flat, ready-to-use rows. Search by keyword and location, or paste the URL of any Indeed search you have already filtered on the site. Each job comes with its full description, parsed salary, the employer's own application link, and the company's rating, size and revenue.

It is built for recruiters and sourcers, sales teams looking for companies that are hiring, job boards that need fresh listings, and analysts studying salaries and hiring demand.

### Why use it

- **The employer's application link.** Most jobs carry `applyUrl`, the page on the employer's own careers site or applicant tracking system, so you are not stuck with an Indeed redirect. It was present on 88% of jobs in our tests; the rest are applied to on Indeed itself, which `isEasyApply` tells you.
- **Salary as numbers.** `salaryMin`, `salaryMax`, `salaryPeriod` and `salaryCurrency` are parsed out for you, next to Indeed's original text. About three jobs in four carry a salary.
- **Company data in every row.** Rating and number of ratings, size, revenue, industry, website, logo and headquarters, from Indeed's company profiles. No second lookup needed.
- **Flat rows.** One level, no nested objects, so a CSV export opens cleanly in Excel or Google Sheets.
- **Past Indeed's 1,000-job limit.** When Indeed stops serving a search early, the Actor goes on through it by date range, newest first, so one search can return several thousand jobs.
- **Many searches, no duplicates.** Give it several searches in one run. A job that matches more than one is saved once.
- **Cheap.** 1,000 jobs cost $0.10. On the Apify platform they usually take one to four minutes.

### What data you get

| Group             | Fields                                                                                                                                                                                                        |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Job               | `id`, `title`, `url`, `applyUrl`, `isEasyApply`, `jobTypes`, `attributes` (skills, benefits, requirements), `occupations`, `descriptionText`, `descriptionHtml`, `language`                                   |
| Salary            | `salaryText`, `salaryMin`, `salaryMax`, `salaryPeriod`, `salaryCurrency`, `salaryIsEstimated`                                                                                                                 |
| Company           | `companyName`, `companyUrl`, `companyWebsite`, `companyLogo`, `companyRating`, `companyRatingCount`, `companyIndustry`, `companySize`, `companyRevenue`, `companyCeo`, `companyAddress`, `companyDescription` |
| Location          | `location`, `city`, `state`, `postalCode`, `country`, `latitude`, `longitude`, `isRemote`, `isHybrid`                                                                                                         |
| Dates and signals | `postedAt`, `firstSeenOnIndeedAt`, `isExpired`, `isUrgentHire`, `isHighVolumeHiring`                                                                                                                          |
| Search            | `searchQuery`, `searchLocation`, `searchCountry`, `scrapedAt`                                                                                                                                                 |

### How to scrape Indeed jobs

1. Enter a search query, a location, or both, and pick the country.
2. Or run your search on Indeed, set the filters you want there, and paste the URL into **Indeed search URLs**. Add as many URLs as you like.
3. Set **Maximum jobs per search**, or `0` for no limit.
4. Run it, then export the results as JSON, CSV or Excel.

### Input

| Field                   | Notes                                                                     |
| ----------------------- | ------------------------------------------------------------------------- |
| Search query            | Job title, skill or company. Indeed's search syntax works too, see below. |
| Location                | City, state or postcode. Leave empty to search the whole country.         |
| Country                 | Which Indeed site to search, 62 countries. Default `US`.                  |
| Maximum jobs per search | Default 100. `0` means no limit; a broad search can return thousands.     |
| Posted within           | Last 1, 3, 7 or 14 days.                                                  |
| Job type                | Full-time, part-time, contract, temporary or internship.                  |
| Work arrangement        | Remote or hybrid.                                                         |
| Sort by                 | Relevance or date.                                                        |
| Radius and unit         | Distance around the location, in miles or kilometres. Default 25 miles.   |
| Indeed search URLs      | Pasted Indeed search URLs, each run as its own search. See below.         |

```json
{
  "query": "data analyst",
  "location": "Chicago, IL",
  "country": "US",
  "maxItems": 500,
  "fromDays": "7",
  "jobType": "fulltime"
}
```

#### Pasted search URLs

Each pasted URL is its own search, separate from the query and location fields; those run as one more search if you fill them in. From the URL the Actor reads the query (`q`), location (`l`), `radius`, `sort`, posted within (`fromage`: 1, 3, 7 or 14 days), job type (`jt`) and the job type and remote filters Indeed puts in `sc`. The country comes from the domain, such as `uk.indeed.com`. Posted within, job type, work arrangement, sort and radius from the form apply when the URL does not set them. Other URL parameters, and values Indeed's app does not support (such as `fromage=30`), are ignored.

#### Indeed search syntax

The search query is passed to Indeed unchanged, so its operators work:

| Query                             | Finds                                        |
| --------------------------------- | -------------------------------------------- |
| `"data engineer"`                 | the exact phrase anywhere in the posting     |
| `title:("data engineer")`         | the phrase in the job title                  |
| `title:("data engineer") -senior` | data engineer titles, excluding senior roles |
| `company:Google`                  | jobs at one company                          |
| `nurse -travel`                   | nursing jobs that do not mention travel      |

### Usage examples

**Who is hiring data people in one city.** Query `title:("data analyst" or "data engineer")`, location `Austin, TX`, posted within 7 days. Group the rows by `companyName` and use `companyWebsite` and `companySize` to qualify them.

**Salary benchmark.** One search per city for the same title, then compare `salaryMin` and `salaryMax` where `salaryPeriod` is `YEAR`.

**Daily feed.** Sort by date, posted within 1 day, scheduled every morning, with the results sent to your own database or a Google Sheet.

**Several countries in one run.** Paste search URLs from `uk.indeed.com`, `de.indeed.com` and `ca.indeed.com`; each URL searches its own country.

### Sample output

```json
{
  "id": "ad701205f27056f5",
  "title": "Analytics Reporting Specialist",
  "url": "https://www.indeed.com/viewjob?jk=ad701205f27056f5",
  "applyUrl": "https://marcel.applytojob.com/apply/EBQUlqCxkd/Analytics-Reporting-Specialist",
  "isEasyApply": true,
  "companyName": "Marcel Digital",
  "companyWebsite": "https://www.marceldigital.com",
  "companyRating": 5,
  "companySize": "2 to 10",
  "companyRevenue": "$1M to $5M (USD)",
  "location": "Chicago, IL 60606",
  "city": "Chicago",
  "state": "IL",
  "country": "US",
  "latitude": 41.88263,
  "longitude": -87.63744,
  "isRemote": false,
  "isHybrid": false,
  "salaryText": "$75,000 - $90,000 a year",
  "salaryMin": 75000,
  "salaryMax": 90000,
  "salaryPeriod": "YEAR",
  "salaryCurrency": "USD",
  "jobTypes": ["Full-time"],
  "attributes": ["SQL", "Python", "BigQuery", "Looker", "3 years", "Senior level"],
  "occupations": ["Data & Technical Business Analysts"],
  "descriptionText": "Marcel Digital is an award-winning digital agency...",
  "postedAt": "2026-10-08T05:00:00.000Z",
  "searchQuery": "data analyst",
  "searchLocation": "Chicago, IL",
  "searchCountry": "US"
}
```

### What it costs

|            | Free plan | Paid plans    |
| ---------- | --------- | ------------- |
| Each job   | $0.0001   | from $0.00007 |
| 1,000 jobs | $0.10     | from $0.07    |

There is no monthly fee and no charge for starting a run. A search that finds nothing costs nothing. Set a maximum charge on the run and it stops cleanly when it is reached.

### Tips and limits

- **Big searches.** Indeed stops serving a search long before the total it shows, often after a few hundred jobs, and never past 1,000. When that happens the Actor runs the same search again for one date range at a time (the last 3 days, 3 to 7 days ago, 7 to 14, and so on back), which brings back far more: a UK-wide "software engineer" search went from 172 jobs to 2,645. The log says when it does this. Those extra jobs arrive newest range first, whatever the sort order.
- **Remote jobs in the US.** Indeed's US site currently leaves remote jobs out of searches that have a location. When a remote search with a location finds nothing, the Actor searches the whole country instead and says so in the log; those rows have an empty `searchLocation`, and each job's own location fields still tell you where it is.
- **Repeated jobs.** Indeed shows some jobs on more than one results page. Repeats are removed and are not charged; when Indeed cut the search short, the date ranges usually make up for them.
- **Not every job has every field.** Salary is the one that varies most. Treat everything except `id`, `title` and `url` as optional.

### Integrations and export

Results land in a standard Apify dataset. Export them as JSON, CSV, Excel or XML, read them through the API, or connect them to Make, Zapier, n8n, Google Sheets, Slack or your own webhook.

### FAQ

**How many jobs can one run collect?** The Actor sets no limit of its own: a broad search across a whole country often returns several thousand jobs, and a run can hold as many searches as you like. Indeed does not serve every job it lists, so very broad searches still come back incomplete; narrower searches (a city, a job type) get closer to the full set.

**Which countries are supported?** 62 Indeed country sites, including the US, UK, Canada, Australia, India, Germany, France, the Netherlands, Spain, Italy, Brazil, Mexico, Japan and Singapore.

**Does it need an Indeed account or cookies?** No. It collects only publicly listed jobs.

**Why does a job have both `applyUrl` and `isEasyApply`?** Some employers accept applications on Indeed and on their own site. `applyUrl` is their site; `isEasyApply` means Indeed's own apply flow is also offered.

# Actor input Schema

## `query` (type: `string`):

Job title, skill or company. Indeed operators work too: title:("data engineer"), company:Google, nurse -travel.

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

City, state or postcode. Leave empty to search the whole country.

## `country` (type: `string`):

Which Indeed country site to search.

## `maxItems` (type: `integer`):

Jobs to save for each search. 0 means no limit. When Indeed stops a search early, the Actor continues it by date range.

## `fromDays` (type: `string`):

Only jobs Indeed first saw within this window.

## `jobType` (type: `string`):

Only jobs of this type.

## `remote` (type: `string`):

Only remote or only hybrid jobs. If a remote search with a location finds nothing (Indeed's US site leaves remote jobs out of location searches), the whole country is searched instead; each row's location shows where the job is.

## `sort` (type: `string`):

Order Indeed returns jobs in.

## `radius` (type: `integer`):

Distance around the location.

## `radiusUnit` (type: `string`):

Unit for the radius.

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

Paste Indeed search result URLs. Each URL runs as its own search, separate from the query and location above. Posted within, job type, work arrangement, sort and radius above apply when the URL does not set them.

## Actor input object example

```json
{
  "query": "data analyst",
  "location": "New York, NY",
  "country": "US",
  "maxItems": 100,
  "sort": "relevance",
  "radius": 25,
  "radiusUnit": "miles"
}
```

# Actor output Schema

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

One row per job posting, with salary, company and location details.

# 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 = {
    "query": "data analyst",
    "location": "New York, NY",
    "maxItems": 100
};

// Run the Actor and wait for it to finish
const run = await client.actor("deltaspider/indeed-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 = {
    "query": "data analyst",
    "location": "New York, NY",
    "maxItems": 100,
}

# Run the Actor and wait for it to finish
run = client.actor("deltaspider/indeed-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 '{
  "query": "data analyst",
  "location": "New York, NY",
  "maxItems": 100
}' |
apify call deltaspider/indeed-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,deltaspider/indeed-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/0BKSczVKWP8XDvdvL/builds/4RfOjactSRnY3rxeZ/openapi.json
