# Indeed Jobs Scraper & API - 60 Countries (`atlasdata/indeed-jobs-scraper-reliable`) Actor

Indeed jobs API & scraper for 60 Indeed country sites: search by keyword, location, radius, date posted, job type, remote and salary, or paste Indeed URLs. Parsed salary, company rating, benefits, full description, direct apply URL. About 1,000 jobs/min, $0.06 per 1,000 jobs.

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

## Pricing

from $0.06 / 1,000 job scrapeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 & API - 60 Countries

**An Indeed jobs API for 60 countries: search by keyword and location and get clean job records with parsed salary, company rating and apply URL, for $0.06 per 1,000 jobs.**

Scrape **Indeed job listings** from **60 Indeed country sites** (indeed.com, uk.indeed.com, de.indeed.com, fr.indeed.com, ca.indeed.com, au.indeed.com, in.indeed.com ...) by **keyword, location and radius**, with Indeed's filters for **date posted, job type (full-time, part-time, contract, temporary, internship), remote and minimum salary**. You can also paste **Indeed search URLs**.

Every job comes as a clean record: job key, title, **company, company rating and review count**, location (city, state, postcode, country), **salary parsed into min / max / period / currency** (plus a yearly equivalent), job type, schedule, **benefits**, experience level, posted date, the **full description**, the Indeed job URL and the **direct apply URL**, and a remote flag.

The Actor reads Indeed's own job-search data feed, not the Cloudflare-protected web pages, so runs are fast (about **1,000 jobs per minute**) and are not stopped by "Security Check" pages. It connects through Apify proxies. If Indeed starts throttling a connection, the Actor switches to residential proxies on its own. Both are included in the price.

### Who it's for and use cases

Built for recruiters and staffing agencies, HR and salary analysts, job boards and job-alert products, B2B sales teams looking for companies that are hiring, and developers who need job data through an API.

- **Job market and salary research**: who is hiring for a role in a city, how many postings there are, and what they pay (hourly, monthly or yearly, in local currency).
- **Lead generation for recruiters and staffing agencies**: companies hiring right now, with their Indeed rating, size and industry.
- **Job boards and alerts**: feed fresh postings with apply links into your own site, Slack or a spreadsheet. Schedule a daily run with *Date posted = Last 24 hours*.
- **Competitor and employer monitoring**: track the roles a company opens across countries.
- Pairs with our [**Google Jobs Scraper**](https://apify.com/atlasdata/google-jobs-scraper-reliable) when you want postings from every job board, not only Indeed.

### How to use it

1. Enter one or more **keywords** (`nurse`, `data analyst`, `warehouse`). Each keyword is a separate search.
2. Enter a **location** (`Austin, TX`, `London`, `München`) and pick the **country** (Indeed site). You can leave the location empty to search a whole country.
3. Optionally set **radius**, **date posted**, **job type**, **remote only**, **minimum salary** and **sort**.
4. Set **max jobs per search** and run.

Jobs go to the dataset (views: *Overview*, *Salaries*, *Descriptions & apply links*). A per-search summary goes to the `OUTPUT` record in the key-value store.

#### Paste Indeed URLs

Copy the URL of any Indeed results page from any country, for example `https://uk.indeed.com/jobs?q=chef&l=Manchester&fromage=7`. The country site, `q`, `l`, `radius`, `fromage` (date), `jt` / `sc` (job type, remote) and `sort` are taken from the URL.

#### How many jobs can I get?

Indeed shows a limited number of results for one search. For larger requests the Actor splits the search into posting-date windows and removes duplicates. In our tests **2,000 nurse jobs across the US** took 108 seconds. Narrow searches stop when Indeed has no more matches, and `OUTPUT` says how many were found. **You only pay for unique jobs saved.**

### Input examples

Simple search:

```json
{
  "keywords": ["software engineer"],
  "location": "New York, NY",
  "maxResults": 100
}
```

Part-time jobs from the last 3 days within 10 miles:

```json
{
  "keywords": ["barista", "cashier"],
  "location": "Seattle, WA",
  "radius": 10,
  "datePosted": "3",
  "jobType": "part-time"
}
```

Remote jobs paying at least $120,000 a year:

```json
{
  "keywords": ["data engineer"],
  "remoteOnly": true,
  "minSalary": 120000,
  "maxResults": 200
}
```

Germany, by URL:

```json
{
  "startUrls": ["https://de.indeed.com/jobs?q=Pflegefachkraft&l=Hamburg&fromage=7"]
}
```

### What data you get

Fill rates are measured on 4543 jobs from our final test runs (1543 with descriptions), across 16 countries.

| Field | What it is | Filled |
|---|---|---|
| `jobKey` | Indeed job key (stable ID, used for de-duplication) | 100% |
| `title` | Job title | 100% |
| `companyName` | Employer | 100% |
| `companyRating / companyReviewCount` | Indeed company rating (1-5) and number of reviews | 91% |
| `companyUrl / companyLogoUrl / companyIndustry / companySize` | Indeed company page, logo, industry, employee count | 91% |
| `location / city / state / postalCode / countryCode` | Location as shown and its parts | 100% |
| `isRemote / workModel` | Remote flag, "remote" or "hybrid" | 100% |
| `salary` | Salary as shown ("$51 - $56 an hour") | 62% |
| `salaryMin / salaryMax / salaryPeriod / salaryCurrency` | Parsed salary numbers, hour/day/week/month/year, ISO currency | 62% |
| `salaryAnnualMin / salaryAnnualMax` | Yearly equivalent of the salary | 62% |
| `jobType / jobTypes` | Full-time, Part-time, Contract, Temporary, Internship, PRN ... | 89% |
| `schedule` | Shifts and schedule (Day shift, Monday to Friday, Weekends as needed ...) | 47% |
| `benefits` | Health insurance, Paid time off, 401(k) matching ... | 58% |
| `experienceLevel` | Entry level, Mid-level, Senior level ... | 85% |
| `attributes / occupations` | All Indeed tags (skills, licenses, education, benefits) and occupation categories | 100% |
| `postedAt / datePublished` | When the job was posted on Indeed (ISO time) and the original publication date | 100% |
| `description` | Full job description as plain text (optional HTML in descriptionHtml) | 100% |
| `jobUrl` | Indeed job page | 100% |
| `applyUrl / applyIsExternal / isIndeedApply` | Direct apply URL on the employer / ATS site (or the Indeed page for Indeed Apply jobs) | 100% |
| `isUrgentHire / source / language` | Urgently hiring flag, posting source, posting language | 100% |
| `searchQuery / searchLocation / country / position / scrapedAt` | Search that found the job, its rank and scrape time | 100% |

`postedAt` is when the job appeared on Indeed. `salaryAnnualMin` / `salaryAnnualMax` convert the salary to a yearly amount (hour x 2080, day x 260, week x 52, month x 12) so jobs can be compared. `salaryIsEstimate: true` means Indeed estimated the pay because the employer did not state it.

### Output example (shortened)

```json
{
  "jobKey": "49e1aa5388c6f358",
  "title": "Staff Nurse",
  "companyName": "The Harris Center for Mental Health and IDD",
  "companyRating": 3.4,
  "companyReviewCount": 444,
  "companyUrl": "https://www.indeed.com/cmp/The-Harris-Center-For-Mental-Health-and-Idd",
  "companyLogoUrl": null,
  "companyIndustry": "Health Care",
  "companySize": "1,001 to 5,000",
  "location": "Houston, TX 77087",
  "city": "Houston",
  "state": "TX",
  "postalCode": "77087",
  "countryCode": "US",
  "isRemote": false,
  "workModel": null,
  "salary": "From $80,860 a year",
  "salaryMin": 80860,
  "salaryMax": null,
  "salaryPeriod": "year",
  "salaryCurrency": "USD",
  "salaryIsEstimate": false,
  "salaryAnnualMin": 80860,
  "salaryAnnualMax": null,
  "jobType": "Full-time",
  "jobTypes": [
    "Full-time"
  ],
  "experienceLevel": "Mid-level",
  "schedule": [],
  "benefits": [
    "Paid time off",
    "Employee assistance program",
    "Employee discount",
    "Loan forgiveness",
    "Flexible schedule"
  ],
  "attributes": [
    "Nursing policy compliance",
    "Collaborate with healthcare professionals",
    "Managed Registered Nurses (RNs)",
    "Nursing",
    "Staff supervision",
    "Trauma-sensitive practices"
  ],
  "occupations": [
    "Healthcare Occupations",
    "Patient Care Nursing Occupations",
    "Nursing Occupations",
    "Registered Nurses"
  ],
  "postedAt": "2026-10-27T09:00:54.488Z",
  "datePublished": "2026-10-26",
  "isUrgentHire": false,
  "isIndeedApply": true,
  "jobUrl": "https://www.indeed.com/viewjob?jk=49e1aa5388c6f358",
  "applyUrl": "https://prd01-hcm01.prd.mykronos.com/ta/6140328.careers?ShowJob=2185052379",
  "applyIsExternal": true,
  "source": "The Harris Center for Mental Health and IDD",
  "language": "en",
  "description": "Join The Harris Center for Mental Health and IDD as a Staff Nurse, RN and unleash your innovative spirit! As part of our interdisciplinary team, you'll provide nursing care to individuals with mental and developmental di...",
  "searchQuery": "registered nurse",
  "searchLocation": "Houston, TX",
  "country": "us",
  "position": 12,
  "scrapedAt": "2026-10-27T11:38:21.973Z"
}
```

### Run summary (OUTPUT record)

Each search gets one status: `SUCCEEDED`, `PARTIAL`, `NO_DATA` (Indeed has no jobs for it) or `FAILED`. The summary also has the job count, the number of requests, how many jobs your filters removed, a note when fewer jobs exist than you asked for, and network statistics (proxy used, retries). If every search fails, the run is marked as failed, so you never get an empty "successful" run.

### Pricing

Pay per event, no subscription. Proxies are included:

| Event | Price | When |
|---|---|---|
| Actor start | $0.0005 per GB of memory ($0.0005 at the default 256 MB) | Once per run |
| Job | $0.00006 | Every unique job saved to the dataset |

That is **$0.06 per 1,000 jobs**, plus the start fee. Duplicates are never charged. A search with no results costs only the start fee. Apify's "Maximum cost per run" is respected, and the scraper stops cleanly when it is reached.

Examples: 100 jobs ≈ $0.0065. 10,000 jobs ≈ $0.60.

### FAQ

**Do I need an Indeed account, cookies or my own proxy?** No. Keep the default proxy setting. Proxies are included in the price.

**Which countries work?** 60 Indeed country sites, including the US, UK, Canada, Australia, India, Germany, France, Netherlands, Spain, Italy, Brazil, Mexico, Japan, Singapore, South Africa and the UAE. Pick one in *Country*, or paste a URL from that country's site.

**Why do I get fewer jobs than the number shown on the Indeed website?** The website count is an estimate that also includes loosely related postings. The Actor returns the jobs Indeed actually serves for the search, without duplicates.

**How do salary filters work?** Indeed does not have a reliable salary filter, so *Minimum salary* is applied to the parsed salary (yearly equivalent, in the job's own currency). Jobs without a salary are skipped when it is set.

**Are the descriptions complete?** Yes. `description` is the full text of the posting. Turn on *Also include description HTML* to get the original formatting too.

**Can I call it as an API?** Yes. Every run can be started through the Apify API. To get results back in one HTTP call, POST your input to `run-sync-get-dataset-items`:

```bash
curl -X POST "https://api.apify.com/v2/acts/atlasdata~indeed-jobs-scraper-reliable/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"keywords": ["software engineer"], "location": "New York, NY", "maxResults": 50}'
```

The response is the dataset as JSON. Apify's JavaScript and Python clients, Make, Zapier and n8n integrations work too.

**Can AI agents use it (MCP)?** Yes. Add the Apify MCP server to Claude, Cursor or any MCP client with `https://mcp.apify.com?tools=atlasdata/indeed-jobs-scraper-reliable` and the Actor becomes a tool your agent can call.

**Can I run it on a schedule?** Yes. Use Apify Schedules (for example daily with a recent *date posted* filter) and send the dataset to Google Sheets, Slack, a webhook or your database with Apify integrations.

### Limits and honest caveats

- **Results per search**: Indeed serves a limited set per search. Larger results come from date-window splitting (see above). Very narrow searches cannot reach a high `maxResults`.
- **Combined filters**: Indeed applies one filter type per request. When you combine *date posted* with *job type* / *remote*, one is applied by Indeed and the other is applied on our side, so some extra requests may be needed. The results are correct, and you only pay for matching jobs.
- **Salary, rating, benefits**: present only when Indeed shows them (see fill rates).
- **Speed**: about 1-3 seconds per 100 jobs plus Actor start. 50 jobs ≈ 3 s per run.
- **Test results**: 36/36 final test runs on the current build passed (16 Indeed country sites, every filter, URL input, a no-results search and a forced block that switched to residential proxy). Median run time 3.2 s; 1,000 jobs in 24 s; 2,000 jobs in 108 s.

### Related atlasdata actors

**Job data scrapers**

- [Google Jobs Scraper & API - Salary & Apply Links](https://apify.com/atlasdata/google-jobs-scraper-reliable)
- [Glassdoor Jobs Scraper & API - Salaries & Ratings](https://apify.com/atlasdata/glassdoor-jobs-scraper-reliable)

**Ad library scrapers (competitor ad tracking)**

- [Google Ads Transparency Scraper & Ad Library API](https://apify.com/atlasdata/google-ads-transparency-scraper-reliable)
- [TikTok Ads Library Scraper & TikTok Ads API](https://apify.com/atlasdata/tiktok-ad-library-scraper-reliable)
- [Facebook Ads Library Scraper & Meta Ads API](https://apify.com/atlasdata/facebook-ad-library-scraper-reliable)
- [LinkedIn Ads Library Scraper & API](https://apify.com/atlasdata/linkedin-ad-library-scraper-reliable)

**Search trends**

- [Google Trends Scraper & API - No 429 Errors](https://apify.com/atlasdata/google-trends-scraper-reliable)

# Actor input Schema

## `keywords` (type: `array`):

Each entry is one Indeed search (what you would type into "What"): e.g. "nurse", "data analyst", "warehouse". Leave empty to get all jobs in a location. Required unless you paste Indeed URLs below.

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

City, state, region or postcode (what you would type into "Where"), e.g. "Austin, TX", "London", "München". Leave empty to search the whole country. Type "Remote" or use the Remote option for remote jobs.

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

Which Indeed country site to search (indeed.com, uk.indeed.com, de.indeed.com ...). The location must be in this country.

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

Distance around the location: miles on indeed.com (US) and uk.indeed.com, kilometres elsewhere. 0 = exact location only.

## `datePosted` (type: `string`):

Only jobs posted on Indeed within this period.

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

Indeed's job type filter.

## `remoteOnly` (type: `boolean`):

Only jobs Indeed tags as Remote.

## `minSalary` (type: `integer`):

Optional. Keeps only jobs that show a salary whose yearly equivalent (hourly x 2080, monthly x 12 ...) reaches this amount, e.g. 80000. Jobs without a salary are skipped. Leave empty to keep all jobs.

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

Order of the first results, like on Indeed.

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

Stop after this many unique jobs for each keyword / URL. Large numbers are fine: broad searches return thousands of jobs (the Actor splits them by posting date automatically). You only pay for jobs saved.

## `includeDescription` (type: `boolean`):

Full description as plain text. Turn off for smaller, faster datasets. Same price.

## `includeDescriptionHtml` (type: `boolean`):

Adds the original HTML of the description (descriptionHtml).

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

Optional. Paste Indeed search result URLs from any Indeed country, e.g. https://www.indeed.com/jobs?q=nurse\&l=Houston%2C+TX\&fromage=3. The country site, keywords (q), location (l), radius, date (fromage), job type (jt / sc), remote and sort are taken from the URL. Other settings above apply when the URL does not set them.

## `maxConcurrency` (type: `integer`):

How many Indeed requests run at the same time.

## `maxRetries` (type: `integer`):

Failed or blocked requests are retried with back-off.

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

Optional. By default the Actor connects directly and switches automatically to Apify datacenter and then residential proxies if Indeed starts blocking (included in the price). Set a proxy here only if you want to force one.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "location": "New York, NY",
  "country": "us",
  "radius": 25,
  "datePosted": "any",
  "jobType": "any",
  "remoteOnly": false,
  "sort": "relevance",
  "maxResults": 50,
  "includeDescription": true,
  "includeDescriptionHtml": false,
  "maxConcurrency": 4,
  "maxRetries": 6
}
```

# Actor output Schema

## `jobs` (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": "New York, NY",
    "maxResults": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("atlasdata/indeed-jobs-scraper-reliable").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": "New York, NY",
    "maxResults": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("atlasdata/indeed-jobs-scraper-reliable").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 '{
  "keywords": [
    "software engineer"
  ],
  "location": "New York, NY",
  "maxResults": 50
}' |
apify call atlasdata/indeed-jobs-scraper-reliable --silent --output-dataset

```

## MCP server setup

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

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/vkDdllrci25AV4ScR/builds/1vTXgBhooybSGQEqh/openapi.json
