# Indeed Jobs Scraper | 18 Fields, 17 Countries, No Login (`themineworks/indeed-scraper`) Actor

Scrape public Indeed job listings by keyword and location: title, company, location, salary, job type, posted date, description, apply URL. No login. Pay per job.

- **URL**: https://apify.com/themineworks/indeed-scraper.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Jobs, Lead generation, MCP servers
- **Stats:** 67 total users, 28 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 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.
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?

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

## Indeed Jobs Scraper: 18 Fields, 17 Countries, No Login

💰 From $3.00 / 1,000 results.

Scrape public Indeed job listings by keyword and location with no login required: title, company, location, salary, job type, posted date, description snippet, apply URL, and 10 more fields, across 17 country sites.

### What it does

Indeed's search results are public, but a plain, unproxied HTTP request into them is blocked by a PerimeterX security check backed by an interactive Cloudflare Turnstile challenge. This actor routes each request through Apify's UNBLOCKER proxy group, which clears that layer server-side (no browser needed on our end), then reads the job data straight out of the page's own embedded JavaScript model rather than scraping rendered HTML, so the fields you get back are the same ones Indeed's own front end uses internally.

Each search page is solved with a fresh proxy session, and a page is retried a few times if the first attempt gets a block/challenge response. Jobs are deduplicated by Indeed's own job key across pages, and the actor stops cleanly once a page returns no new jobs or a page can't be solved after retrying, rather than paying to keep retrying a degraded proxy pool. The first page of results is normally enough to satisfy a typical request; deeper pagination is solved less reliably and may stop early on a large `maxResults`.

You give it a query, an optional location, and a country. Every returned record carries the `search_query` and `search_location` that produced it, so a multi-search dataset stays attributable to what generated each row.

### Input

| Field | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `query` | string | yes | "software engineer" | Job title, skill, or keyword to search for (Indeed's "what" field). |
| `location` | string | no | "New York" | City, state, ZIP, or "Remote" (Indeed's "where" field). Leave empty for nationwide. |
| `country` | string | no | "US" | Which of the 17 supported Indeed country sites to search (US, GB, CA, IN, AU, DE, FR, NL, IE, SG, NZ, ES, IT, BR, MX, ZA, AE). Sets the Indeed domain (ccTLD). |
| `maxResults` | integer | no | 45 | Maximum job listings to return. Each solved search page yields roughly 15 to 45 jobs. |
| `proxy` | object | no | UNBLOCKER | Indeed hard-blocks datacenter and unproxied traffic. Apify's UNBLOCKER proxy group is required and is the default. |

### Example input

```json
{
  "query": "software engineer",
  "location": "New York",
  "country": "US",
  "maxResults": 45
}
```

### Example output

Field list and example are taken from a real run, not a mock-up.

```json
{
  "job_id": "82075119d56dbfed",
  "job_url": "https://www.indeed.com/viewjob?jk=82075119d56dbfed",
  "title": "Apprentice Electrician",
  "company": "Huckleberry Electric",
  "location": "Lynnwood, WA",
  "remote": false,
  "salary": "$21 - $28 an hour",
  "job_type": "Full-time",
  "posted": "30+ days ago",
  "posted_date": "2026-06-11T05:00:00.000Z",
  "description": "Want to become a highly skilled residential electrician. Assist journeyman electricians with residential service and installation projects.",
  "company_rating": 4.2,
  "company_review_count": 38,
  "urgently_hiring": false,
  "sponsored": true,
  "search_query": "electrician",
  "search_location": "Seattle, WA",
  "scraped_at": "2026-07-27T08:55:11.044Z"
}
```

| Field | Description |
| --- | --- |
| `job_id` | Indeed job key, unique per posting |
| `job_url` | Canonical Indeed job posting URL |
| `title` | Job title |
| `company` | Company name |
| `location` | Job location |
| `remote` | Whether the job is flagged remote |
| `salary` | Salary text exactly as Indeed shows it |
| `job_type` | Employment type: Full-time, Part-time, Contract, and so on |
| `posted` | Relative posting time, e.g. "3 days ago" |
| `posted_date` | Absolute posting date as an ISO timestamp, when Indeed provides it |
| `description` | Job description snippet, plain text |
| `company_rating` | Company star rating on Indeed, when shown |
| `company_review_count` | Number of company reviews on Indeed, when shown |
| `urgently_hiring` | Indeed's "Urgently hiring" flag |
| `sponsored` | Whether the listing is a sponsored result |
| `search_query` | The query this job was found under |
| `search_location` | The location this job was found under |
| `scraped_at` | ISO timestamp when this record was captured |

### Use cases

**Recruitment market mapping.** Run the same query weekly across cities to see who's hiring, at what salary, and how fast postings turn over.

**Compensation benchmarking.** The `salary` string is captured verbatim as Indeed shows it, so you can band roles by title and location without running a survey.

**Competitor headcount signals.** Track a named company's postings over time as a leading indicator of expansion or a new team standing up.

**Lead generation for staffing agencies.** Companies posting `urgently_hiring` roles are in-market right now, not just browsing.

**Job-board aggregation.** Feed a niche board or newsletter with fresh, structured listings instead of scraping an RSS feed.

**Labour-market research.** Quantify remote versus on-site mix by filtering the `remote` boolean across a set of queries and locations.

### Do I need an Indeed account or API key?

No. The actor reads publicly visible search results. There's no login step and you never supply credentials.

### Which countries are supported?

Set `country` to one of the 17 supported Indeed sites: US, GB, CA, IN, AU, DE, FR, NL, IE, SG, NZ, ES, IT, BR, MX, ZA, or AE. `location` is passed through as typed, so it accepts anything the site's own location box accepts.

### Why is salary a string rather than a number?

Because Indeed publishes it as a string and the shape varies: hourly ranges, annual ranges, "From £X", or nothing at all. Parsing it to a number would force a guess and quietly lose the unit, so the field is preserved exactly as displayed and left for you to parse against your own rules.

### How current are the results?

They're fetched live at run time. `posted` keeps Indeed's own relative wording, and `posted_date` gives you a sortable ISO timestamp derived from it when Indeed provides one.

### What does it cost?

Pay per event: $0.0048 per job delivered on the base rate, down to $0.003 per job on Gold-tier Apify plans and above. Billing fires only after a record is validated and stored, so a blocked page, an empty search, or a duplicate is never charged.

#### What a run with no results costs

Every run is charged one Actor Start event of $0.00005, including a run that returns nothing. The per-result charge is separate and genuinely does not fire on an empty, blocked or duplicate result, so a run that finds nothing costs $0.00005 and no more.

### Use in Claude, ChatGPT & any MCP agent

```
https://mcp.apify.com/?tools=themineworks/indeed-scraper
```

Or call it programmatically with the Apify client:

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('themineworks/indeed-scraper').call({
  query: 'software engineer',
  location: 'New York',
  country: 'US',
  maxResults: 45,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

### Legal and compliance

This actor collects only publicly available information, the same data any visitor can see without logging in. It doesn't access private or authenticated areas, doesn't attempt to bypass paywalls, and collects no personal data beyond what the source already publishes openly. You're responsible for using the output in line with the source site's terms and the data protection law that applies to you.

Found a bug or have a feature request? Open an issue on the actor's Apify Console page or reach out through the Apify profile.

# Actor input Schema

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

Job title, skill, or keyword to search for (Indeed's 'what' field), e.g. "software engineer" or "registered nurse".

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

City, state, ZIP, or 'Remote' (Indeed's 'where' field), e.g. "Austin, TX" or "10001". Leave empty for nationwide.

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

Which Indeed country site (ccTLD) to search, e.g. uk.indeed.com for GB.

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

Maximum number of job listings to return. Each solved search page yields ~15-45 jobs.

## `proxy` (type: `object`):

Indeed hard-blocks datacenter and unproxied traffic (PerimeterX + Cloudflare Turnstile). Apify's UNBLOCKER proxy group is required and is the default — it renders server-side, so no browser is needed.

## Actor input object example

```json
{
  "query": "software engineer",
  "location": "New York",
  "country": "US",
  "maxResults": 45,
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}
```

# Actor output Schema

## `results` (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 = {
    "query": "software engineer",
    "location": "New York",
    "proxy": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "UNBLOCKER"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/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": "software engineer",
    "location": "New York",
    "proxy": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["UNBLOCKER"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/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": "software engineer",
  "location": "New York",
  "proxy": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "UNBLOCKER"
    ]
  }
}' |
apify call themineworks/indeed-scraper --silent --output-dataset

```

## MCP server setup

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