# Indeed Job Postings Scraper (`bonpleincapital/indeed-jobs-scraper`) Actor

Indeed job postings scraper, 22 countries: title, company, location, salary, link. Filter by keyword, place, date. Pay per job. Indeed may refuse some requests: fewer results possible

License: personal use only; resale and redistribution prohibited.
Created with the help of artificial intelligence.

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

## Pricing

from $2.40 / 1,000 job posting returneds

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 Job Scraper

This **Indeed job scraper** turns a few job keywords into a clean list of **Indeed** job postings (title, company, location, salary, job type, posting date and link) that you can download as JSON, CSV or Excel, or read through the Apify API. It works on 22 country sites of Indeed (United States, United Kingdom, Canada, Australia, Germany, France, Spain, Italy and more), so you can follow hiring trends, build a job board, watch competitors' openings or feed a recruiting pipeline without copying pages by hand.

### What can this Actor do?

- Search **Indeed** by keyword, country and location, and read as many result pages as you want.
- Return structured data for each posting: job title, company name, company rating, location, salary text with minimum, maximum, period and currency when Indeed shows them, job types, remote flag, posting date, a short snippet and the public link.
- Filter by posting age (last 1, 3, 7 or 14 days) and keep only the postings that show a salary.
- Remove duplicates across pages and searches, so each job is paid for once.
- Behave like a polite visitor: a normal browser identity, cookies kept for the session, pauses between pages and a new identity if a page is refused.
- Try it on the Apify free plan: the prefilled input reads one page and costs a fraction of a cent.

Only public search pages are read. The Actor never logs in, never reads private data, and never tries to solve a captcha or a challenge page: if Indeed refuses a request several times in a row, the run ends with a clear status message and you only pay for the results that were produced.

### How to use it

1. Click **Try for free** and open the **Input** tab.
2. Enter one or more job keywords in **Job search keywords**, for example `python developer` or `nurse`.
3. Add the **Indeed countries** to search as two-letter codes (`us`, `gb`, `fr`, `de`, `jp`...). Each country site is searched in its own language and layout.
4. Optionally set a **Location**, **Posted within (days)** and **Only jobs with a salary**. Keep **Maximum number of jobs** low (5 to 10) for a first test.
5. Leave **Use Apify Proxy** on, then click **Start**. A small run ends in about one to three minutes.
6. Open the **Output** tab (table view) and download the jobs as JSON, CSV or Excel, or call the Actor from the API, Make, Zapier or n8n.

#### How the data is read

- **Different card formats:** the job cards are read from the data embedded in the page, from the page's structured job data, or from the visible cards, whichever the country site serves.
- **Salary and company:** salary minimum, maximum, period and currency come from Indeed's data when present, and are otherwise parsed from the displayed text (`$110,000 - $140,000 a year`, `45.000 € par an`, `£15.50 an hour`, `CHF 80'000 pro Jahr`, `月給 30万円`, `5 - 8 Lakh per year`). The company name, rating and review count are kept when Indeed shows them, and left empty (never invented) when it hides them.
- **Protection pages:** Indeed sometimes shows a Cloudflare challenge. The Actor does not solve or bypass it. It waits when it gets HTTP 429, retries up to seven times per page with a fresh browser identity and a residential proxy address in the country of the site, and stops within about three minutes with a status message listing the HTTP codes it received (403, 429...) if the page stays refused. Results already collected are kept and only they are billed.

### Input

| Field | Meaning |
| --- | --- |
| `queries` | Job titles or keywords, each one searched separately |
| `countries` | Indeed country codes such as `us`, `gb`, `fr`, `de` |
| `location` | City, region or zip code (optional) |
| `postedWithinDays` | Only jobs from the last N days (optional) |
| `onlyWithSalary` | Skip postings without a salary |
| `maxItems` | Maximum number of jobs in total |
| `maxPagesPerSearch` | Result pages to read for each keyword and country |
| `useApifyProxy` | Route requests through Apify Proxy (recommended) |

```json
{
  "queries": ["python developer"],
  "countries": ["us", "gb", "ca"],
  "maxItems": 5,
  "maxPagesPerSearch": 1,
  "useApifyProxy": true
}
```

### Output

Each result is one dataset item. Example:

```json
{
  "jobKey": "a80654465f93f95d",
  "title": "Senior Python Developer",
  "company": "Nitka Technologies",
  "companyRating": 3.9,
  "companyReviewCount": 120,
  "location": "Remote",
  "salaryText": "$110,000 - $140,000 a year",
  "salaryMin": 110000,
  "salaryMax": 140000,
  "salaryPeriod": "year",
  "salaryCurrency": "USD",
  "jobTypes": ["Full-time"],
  "remote": true,
  "postedDate": "2026-07-30",
  "postedText": "Posted 3 days ago",
  "snippet": "We offer 100% remote, full-time work with a flexible schedule...",
  "url": "https://www.indeed.com/viewjob?jk=a80654465f93f95d",
  "country": "US",
  "searchQuery": "python developer"
}
```

### How much does it cost?

This Actor uses **pay per event** pricing: you pay a small amount for each job posting returned, and nothing for results that are not produced. For 1,000 job postings you pay 1,000 `result` events, about **$4.00 per 1,000 results** (see the **Pricing** tab for the current price), plus a small amount of Apify platform usage (proxy traffic). Apify's free plan gives you monthly credits to try the Actor before you pay.

### FAQ

#### Is it legal to use this Actor?

The Actor only reads public Indeed search pages. You are responsible for using the results lawfully and in line with Indeed's terms. Company names and job texts are public business information, but if you store or process personal data (for example a recruiter's name found in a job text), you must respect the GDPR and local privacy laws.

#### Why did a run return fewer jobs than expected?

Indeed shows about 10 to 15 jobs per page and may refuse some requests. The Actor retries with a new browser identity and a new proxy address, but it never tries to solve captchas. If a run ends with a "refused" status, try again later, with fewer pages, or keep the proxy option on.

#### What does an input with filters look like?

```json
{
  "queries": ["registered nurse", "data analyst"],
  "countries": ["fr", "de", "jp"],
  "location": "",
  "postedWithinDays": 7,
  "onlyWithSalary": true,
  "maxItems": 100,
  "maxPagesPerSearch": 3,
  "useApifyProxy": true
}
```

A salary shown in another currency or language is parsed the same way. For example `CHF 80'000 pro Jahr` gives `salaryMin` 80000, `salaryPeriod` `year`, `salaryCurrency` `CHF`; `£15.50 an hour` gives 15.5, `hour`, `GBP`.

#### What does an input with a location look like?

```json
{
  "queries": ["warehouse operator"],
  "countries": ["us"],
  "location": "Austin, TX",
  "maxItems": 20,
  "maxPagesPerSearch": 2,
  "useApifyProxy": true
}
```

If one country site refuses the requests, the Actor moves on to the next country after a share of its time budget, so the other countries still return their jobs.

#### What if a salary or company field is empty?

Indeed does not show a salary or a company on every posting. The field is then `null`: the Actor never guesses a value. Use `onlyWithSalary` to skip postings without a salary.

#### Why do I sometimes get a 403 or a "refused" status?

Indeed protects its pages and may answer HTTP 403 to automated visitors. This Indeed job scraper reads the page like a normal visitor (browser-like headers, cookies, residential proxy, pauses) and retries with a fresh session, but it does not solve or bypass captchas and challenge pages. When Indeed insists, the run ends with a clear status message and you pay only for the jobs actually returned.

#### Does it work the same in every country?

The same fields are returned for all 22 country sites. Each site is queried with its own language header, and the salary currency defaults to the country's currency when Indeed shows a salary without one.

#### Does it need my Indeed account?

No. It never uses a login and never reads private pages.

#### Can I use it through the API?

Yes. Every run can be started and read through the Apify API and its Python and JavaScript clients.

#### What if something does not work?

Open an issue in the **Issues** tab with your input and the run link. Issues are answered as fast as possible.

***

Created with the help of artificial intelligence.

# Changelog

This Actor's version history is a separate document: https://apify.com/bonpleincapital/indeed-jobs-scraper/changelog.md

# Actor input Schema

## `queries` (type: `array`):

One or more job titles or keywords, for example "python developer" or "nurse". Each one is searched separately.

## `countries` (type: `array`):

Country sites of Indeed to search (ISO codes: us, gb, ca, au, de, fr, es, it, nl, ie, in, be, ch, at, pl, sg, nz, za, mx, br, ae, jp).

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

City, region or zip code, in the language of the country site. Leave empty for the whole country.

## `postedWithinDays` (type: `integer`):

Only jobs posted in the last N days (Indeed accepts 1, 3, 7 or 14). Leave empty for any date.

## `onlyWithSalary` (type: `boolean`):

Skip postings that show no salary information.

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

Stop after this many job postings in total. Keep it low to test the Actor cheaply.

## `maxPagesPerSearch` (type: `integer`):

How many result pages (about 10-15 jobs each) to read for each keyword and country.

## `useApifyProxy` (type: `boolean`):

Route requests through Apify Proxy. Recommended: Indeed often refuses data center addresses.

## Actor input object example

```json
{
  "queries": [
    "python developer"
  ],
  "countries": [
    "us",
    "gb"
  ],
  "location": "Austin, TX",
  "onlyWithSalary": false,
  "maxItems": 8,
  "maxPagesPerSearch": 2,
  "useApifyProxy": true
}
```

# Actor output Schema

## `results` (type: `string`):

One dataset item per result, shown in the Overview view.

# 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 = {
    "queries": [
        "python developer"
    ],
    "countries": [
        "gb",
        "ca",
        "us",
        "au"
    ],
    "location": "",
    "maxItems": 8,
    "maxPagesPerSearch": 2
};

// Run the Actor and wait for it to finish
const run = await client.actor("bonpleincapital/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 = {
    "queries": ["python developer"],
    "countries": [
        "gb",
        "ca",
        "us",
        "au",
    ],
    "location": "",
    "maxItems": 8,
    "maxPagesPerSearch": 2,
}

# Run the Actor and wait for it to finish
run = client.actor("bonpleincapital/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 '{
  "queries": [
    "python developer"
  ],
  "countries": [
    "gb",
    "ca",
    "us",
    "au"
  ],
  "location": "",
  "maxItems": 8,
  "maxPagesPerSearch": 2
}' |
apify call bonpleincapital/indeed-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bonpleincapital/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/rRO0SUYNqHm3PKNu3/builds/5GdU8CMCc5l8G6nVI/openapi.json
