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

Export Indeed job listings with salary, location, job type and posting date. Returns roughly 4x a single Indeed search by fanning the query across filters. No Indeed account needed.

- **URL**: https://apify.com/spookyweb/indeed-jobs.md
- **Developed by:** [丂卩ㄖㄖҜㄚ](https://apify.com/spookyweb) (community)
- **Categories:** Jobs, Lead generation, AI
- **Stats:** 2 total users, 1 monthly users, 33.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 job 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/platform/actors/running/actors-in-store#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

Export Indeed job listings as structured data: title, company, location, salary, job type, posting date and a description snippet. No Indeed account needed.

### What you get

One row per job, deduplicated:

| Field | Notes |
|---|---|
| `jobId` | Indeed's own job key, stable across runs |
| `title`, `company`, `location` | |
| `remote` | True when the listing is remote, from the flag or the location text |
| `jobTypes` | Full-time, Part-time, Contract and so on, as Indeed lists them |
| `salaryText` | The salary exactly as shown, for example "£45,000 - £55,000 a year" |
| `salaryMin`, `salaryMax`, `salaryCurrency` | Parsed figures where Indeed gives them |
| `postedRelative`, `postedAt` | "2 days ago", plus an ISO timestamp when available |
| `snippet` | The short description Indeed shows on the card |
| `url` | Direct link to the listing |

### How it gets more than 15 jobs

An Indeed search shows 15 jobs, and page two requires a signed in account. Rather than ask you for Indeed credentials, this actor runs your search across several filters that split the results a different way, then merges and deduplicates them.

A typical city and job title returns around 60 unique jobs. The run stops early once the filters stop producing anything new, so you are not charged for queries that add nothing.

If you need more than that for one job title, run it per city rather than trying to go deeper in one place.

### Pricing

You pay per unique job returned. Duplicates across filters are removed before charging, so one job is charged once no matter how many filters it appeared in. Set `maxResults` to cap what a run can cost.

Runs that return nothing cost nothing.

### Input

```json
{
  "query": "data analyst",
  "location": "London",
  "country": "uk",
  "maxResults": 100
}
```

Either `query` or `location` is required.

| Field | Type | Default | What it does |
|---|---|---|---|
| `query` | string | | What to search for, exactly as you would type it into the Indeed search box |
| `location` | string | | A city, region or postcode to search near |
| `country` | string | `uk` | Which national Indeed site to search, as a two letter code. Match it to the location |
| `maxResults` | integer | `100` | The most jobs to return, which is also the most a run can charge |

### Output

One row per job in the dataset. A typical row:

```json
{
  "jobId": "d21e90a08011fc27",
  "title": "Data Analyst",
  "company": "Example Analytics Ltd",
  "location": "London",
  "remote": false,
  "jobTypes": ["Full-time"],
  "salaryText": "£45,000 - £55,000 a year",
  "salaryMin": 45000,
  "salaryMax": 55000,
  "salaryCurrency": "GBP",
  "salaryPeriod": "year",
  "postedRelative": "3 days ago",
  "postedAt": "2026-08-07T00:00:00.000Z",
  "snippet": "We are looking for a data analyst to join...",
  "url": "https://uk.indeed.com/viewjob?jk=d21e90a08011fc27"
}
```

Download it from the run as JSON, CSV or Excel, or read it straight from the API.

### Run it from the API

```bash
curl -X POST "https://api.apify.com/v2/acts/spookyweb~indeed-jobs/run-sync-get-dataset-items?token=YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query": "data analyst", "location": "London", "country": "uk", "maxResults": 100}'
```

Or with the Apify client:

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

const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('spookyweb/indeed-jobs').call({
  query: 'data analyst',
  location: 'London',
  country: 'uk',
  maxResults: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### Notes

Occasionally a run is blocked before it starts, which shows up as an error saying every request was blocked. That is a bad proxy address rather than a problem with your input, and running it again normally works.

# Actor input Schema

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

What to search for, exactly as you would type it into the Indeed search box, for example "data analyst", "registered nurse" or "python developer". Broader terms return more results because each search is capped, so prefer "analyst" over a long phrase. Either this or a location is required.

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

A city, region or postcode to search near, for example "London", "Greater Manchester" or "SW1A 1AA". Leave empty to search the whole country. Either this or a job title is required.

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

Which national Indeed site to search, given as a two letter country code such as uk, us, ie, de or fr. This decides both the site searched and the country the request is routed through, so it should match the location you are searching.

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

The most jobs to return, which is also the most you can be charged for since charging is per unique job returned. A single Indeed search shows 15 jobs, so this actor runs the search across several filters to go beyond that; expect roughly 60 unique jobs for a typical city and job title. The run stops early once filters stop producing new jobs.

## Actor input object example

```json
{
  "query": "data analyst",
  "location": "London",
  "country": "uk",
  "maxResults": 40
}
```

# Actor output Schema

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

One row per item: job listings with salary and type.

## `runSummary` (type: `string`):

Counts and stop reason for the run.

# 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": "London",
    "maxResults": 40
};

// Run the Actor and wait for it to finish
const run = await client.actor("spookyweb/indeed-jobs").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": "London",
    "maxResults": 40,
}

# Run the Actor and wait for it to finish
run = client.actor("spookyweb/indeed-jobs").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": "London",
  "maxResults": 40
}' |
apify call spookyweb/indeed-jobs --silent --output-dataset

```

## MCP server setup

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

```

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/BkcKc9frZp43LeRM7/builds/ydPvCXKPs03TiGDnR/openapi.json
