# Indeed Job Scrapper (`dineshwadhwani/indeed-job-scrapper`) Actor

crape job listings from Indeed.com and Indeed India (in.indeed.com) by role, skill, and location. Returns deduplicated, capped results ready to pipe into spreadsheets, databases, ATS systems, or AI workflows.

Built for developers, recruiters, and data teams who need structured Indeed job data .

- **URL**: https://apify.com/dineshwadhwani/indeed-job-scrapper.md
- **Developed by:** [Dinesh Kumar Wadhwani](https://apify.com/dineshwadhwani) (community)
- **Categories:** AI, Automation, Jobs
- **Stats:** 2 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

$0.15 / actor start

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js/docs.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python/docs.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/integrations/mcp.md).

If your project is in a different language, use 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 — Multi-Role, Multi-Location, Global + India

Scrape job listings from Indeed.com and Indeed India (in.indeed.com) by role, skill, and location. Returns deduplicated, capped results ready to pipe into spreadsheets, databases, ATS systems, or AI workflows.

Built for developers, recruiters, and data teams who need structured Indeed job data without managing browser automation themselves. Supports multiple roles, multiple skills, and multiple locations in a single run — with role normalization built in so you get consistent results even when job titles are written differently across companies.

---

### Why this Actor

- **Multi-role search** — search up to 3 job titles in one run, combined with up to 3 supporting skills
- **Role normalization** — automatically expands common abbreviations (`VP` → `Vice President`, `Snr` → `Senior`, `dev` → `Developer`) so you reach the right jobs regardless of how companies write titles
- **Global + India** — works on both `indeed.com` and `in.indeed.com`
- **Hard deduplication** — uses Indeed's internal job key (`jk`) to deduplicate across search terms, locations, and pages. The same job never appears twice
- **100-job cap** — stops cleanly at 100 unique results per run, no runaway pagination
- **No proxy required** — works without residential proxies on standard Apify infrastructure

---

### What it does

This Actor searches Indeed job listings using:

- **Up to 3 roles** — each normalized and combined with skills to form targeted search queries
- **Up to 3 skills** — appended to each role to narrow results
- **Multiple locations** — searches each location independently, results pooled and deduplicated globally
- **One time frame** — filter by how recently jobs were posted

For each role + skill combination, the Actor builds a targeted search URL, loads the results page, extracts all job cards, deduplicates by job key, and paginates until the 100-job global cap is reached.

#### Role normalization

Before searching, the Actor expands common abbreviations:

| Input | Normalized |
|---|---|
| `VP Engineering` | `Vice President Engineering` |
| `SVP Product` | `Senior Vice President Product` |
| `Snr Developer` | `Senior Developer` |
| `Tech Lead` | `Technical Lead` |
| `Java Dev` | `Java Developer` |
| `JS Dev` | `JavaScript Developer` |
| `Head of Engg` | `Head of Engineering` |

---

### Input

| Field | Type | Required | Limit | Description |
|---|---|---|---|---|
| `roles` | `string[]` | ✅ Yes | 3 | Job titles to search for |
| `skills` | `string[]` | No | 3 | Supporting keywords appended to each role |
| `locations` | `string[]` | ✅ Yes | — | Cities, regions, or countries to search in |
| `timeFrame` | `string` | No | — | Days since posting: `1`, `3`, `7`, `14` or `""` for any time |
| `maxJobs` | `number` | No | 100 | Max results to collect (hard cap at 100) |

#### Example — Senior engineering leadership roles across India

```json
{
  "roles": ["VP Engineering", "Head of Engineering"],
  "skills": ["SaaS", "Platform"],
  "locations": ["Bangalore", "Pune", "Hyderabad"],
  "timeFrame": "7",
  "maxJobs": 100
}
````

This produces search queries including:

- `Vice President Engineering` in each location
- `Vice President Engineering SaaS` in each location
- `Vice President Engineering Platform` in each location
- `Head of Engineering` in each location
- (and so on for each role × skill combination)

All results are deduplicated globally — if the same job appears in multiple searches, it is saved only once.

#### Example — Full-stack developer roles globally

```json
{
  "roles": ["Full Stack Developer", "Software Engineer"],
  "skills": ["React", "Node.js"],
  "locations": ["London", "Berlin", "Remote"],
  "timeFrame": "3",
  "maxJobs": 50
}
```

***

### Output

Each result is saved as a flat JSON record to the Apify dataset:

```json
{
  "matchedSearchTerm": "Vice President Engineering SaaS",
  "title": "Vice President of Engineering",
  "company": "Acme Corp",
  "location": "Bengaluru, Karnataka",
  "url": "https://in.indeed.com/rc/clk?jk=fcc1e677b4ff9df1...",
  "jobKey": "fcc1e677b4ff9df1"
}
```

| Field | Description |
|---|---|
| `matchedSearchTerm` | The exact search query that produced this result |
| `title` | Job title as listed on Indeed |
| `company` | Hiring company name |
| `location` | Location as shown on the job card |
| `url` | Direct link to the job listing on Indeed |
| `jobKey` | Indeed's internal job ID — used for deduplication |

Results are ready to export as CSV, JSON, or connect directly to Google Sheets, Airtable, or a webhook.

***

### How it works

The Actor uses Crawlee's `PlaywrightCrawler` with browser fingerprinting enabled to render Indeed's JavaScript-heavy search results pages. For each search term and location combination:

1. Builds a targeted Indeed search URL with role, skill, location, and time frame
2. Loads the page in a headless Chromium browser
3. Waits for job cards to render, then scrolls to load lazy content
4. Extracts job title, company, location, and URL from each card
5. Deduplicates using Indeed's `jk` job key parameter
6. Paginates (10 results per page) until the global cap is reached or no more results exist
7. Stops cleanly — no runaway requests, no duplicate entries

***

### Performance

| Input | Results | Notes |
|---|---|---|
| 2 roles × 2 skills × 2 locations, last 7 days | Up to 100 unique jobs | Typical run |
| 1 role × no skills × 1 location, any time | Up to 100 unique jobs | Fastest run |

Runtime and cost depend on how many search term × location combinations are generated and how many pages need to be visited to reach 100 unique results. Runs with high overlap between search terms (same jobs appearing across multiple queries) complete faster due to early deduplication.

> 💡 **Tip:** Set memory to **1024 MB** in your Apify actor settings. Indeed's pages are JavaScript-heavy and require a full browser render — 512 MB is insufficient and will cause instability.

***

### Use cases

- **Recruiters & talent teams** — monitor competitor job postings or track hiring velocity by role and location
- **Job seekers** — run daily searches across multiple cities and pipe results to a spreadsheet or notification system
- **HR analytics** — benchmark job title conventions, required skills, and hiring demand across geographies
- **Market research** — track which companies are hiring for specific roles and skills
- **ATS integrations** — pull and deduplicate job listings before importing into applicant tracking systems
- **AI pipelines** — feed structured job data into LLM workflows for summarisation, matching, or classification

***

### Scheduling & automation

This Actor works well on a schedule. To run it daily:

1. Open the Actor and click **Schedule**
2. Set your preferred cron (e.g. `0 8 * * *` for 8am daily)
3. Use `timeFrame: "1"` (last 24 hours) on daily schedules to only collect fresh listings
4. Connect the output dataset to Google Sheets, a webhook, or a downstream Apify Actor

***

### Limitations

- Returns up to **100 unique jobs per run**. For higher volumes, split searches across multiple runs with different role or location sets.
- Job descriptions are **not included** — only the data visible on the search results card (title, company, location, URL). Use the output URL to fetch full descriptions in a separate step.
- Indeed's page structure can change without notice. If results drop to 0 unexpectedly, check the run log — screenshot debugging files are saved automatically to help diagnose layout changes.
- Performance varies by search specificity. Very narrow searches (rare role + specific skill) may return fewer than 100 results even across multiple pages — this is expected behavior, not an error.

***

### FAQ

**Does this work for both India and global Indeed?**
Yes — works on both `in.indeed.com` and `indeed.com`. Use Indian city names for India-specific searches, or global cities and "Remote" for worldwide searches.

**Does it require residential proxies?**
No — this Actor works on standard Apify infrastructure without residential proxies.

**How does deduplication work?**
Each job is identified by Indeed's internal `jk` job key, extracted from the job URL. If the same job appears across multiple search terms, locations, or pages, it is saved only once.

**Can I search for remote jobs?**
Yes — add `"Remote"` as one of your locations.

**What does role normalization do?**
Before searching, the Actor expands common abbreviations and variants into full titles — so `VP Eng` becomes `Vice President Engineer`, ensuring you reach listings regardless of how companies write the title.

**Is this Actor maintained?**
Yes — actively maintained. If Indeed changes its HTML structure and selectors break, an update ships promptly.

***

### Input schema reference

```json
{
  "roles": ["VP Engineering", "Head of Engineering"],
  "skills": ["SaaS", "B2B"],
  "locations": ["Bangalore", "Remote"],
  "timeFrame": "7",
  "maxJobs": 100
}
```

`timeFrame` values:

| Value | Meaning |
|---|---|
| `1` | Last 24 hours |
| `3` | Last 3 days |
| `7` | Last 7 days |
| `14` | Last 14 days |
| `""` (empty) | Any time |

# Actor input Schema

## `roles` (type: `array`):

Add up to 3 job titles or roles to search for (e.g. "Software Engineer", "Data Analyst"). At least one is required.

## `skills` (type: `array`):

Add up to 3 supporting skills or keywords (e.g. "Python", "AWS", "React"). Optional — appended to the role in the search query.

## `locations` (type: `array`):

Add up to 3 cities or regions to search in (e.g. "Bangalore", "Pune", "Remote"). At least one is required.

## `timeFrame` (type: `string`):

Only return jobs posted within this time window.

## Actor input object example

```json
{
  "roles": [
    "Software Engineer"
  ],
  "skills": [
    "AI"
  ],
  "locations": [
    "India"
  ],
  "timeFrame": ""
}
```

# 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 = {
    "roles": [
        "Software Engineer"
    ],
    "skills": [
        "AI"
    ],
    "locations": [
        "India"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("dineshwadhwani/indeed-job-scrapper").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 = {
    "roles": ["Software Engineer"],
    "skills": ["AI"],
    "locations": ["India"],
}

# Run the Actor and wait for it to finish
run = client.actor("dineshwadhwani/indeed-job-scrapper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "roles": [
    "Software Engineer"
  ],
  "skills": [
    "AI"
  ],
  "locations": [
    "India"
  ]
}' |
apify call dineshwadhwani/indeed-job-scrapper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=dineshwadhwani/indeed-job-scrapper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Indeed Job Scrapper",
        "description": "crape job listings from Indeed.com and Indeed India (in.indeed.com) by role, skill, and location. Returns deduplicated, capped results ready to pipe into spreadsheets, databases, ATS systems, or AI workflows.\n\nBuilt for developers, recruiters, and data teams who need structured Indeed job data .",
        "version": "0.0",
        "x-build-id": "7gbB1XSq5frQn5oKs"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/dineshwadhwani~indeed-job-scrapper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-dineshwadhwani-indeed-job-scrapper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/dineshwadhwani~indeed-job-scrapper/runs": {
            "post": {
                "operationId": "runs-sync-dineshwadhwani-indeed-job-scrapper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/dineshwadhwani~indeed-job-scrapper/run-sync": {
            "post": {
                "operationId": "run-sync-dineshwadhwani-indeed-job-scrapper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "roles",
                    "locations"
                ],
                "properties": {
                    "roles": {
                        "title": "Job Role(s)",
                        "minItems": 1,
                        "maxItems": 3,
                        "type": "array",
                        "description": "Add up to 3 job titles or roles to search for (e.g. \"Software Engineer\", \"Data Analyst\"). At least one is required.",
                        "default": [
                            "Software Engineer"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "skills": {
                        "title": "Skill(s)",
                        "maxItems": 3,
                        "type": "array",
                        "description": "Add up to 3 supporting skills or keywords (e.g. \"Python\", \"AWS\", \"React\"). Optional — appended to the role in the search query.",
                        "default": [
                            "AI"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "locations": {
                        "title": "Location(s)",
                        "minItems": 1,
                        "maxItems": 3,
                        "type": "array",
                        "description": "Add up to 3 cities or regions to search in (e.g. \"Bangalore\", \"Pune\", \"Remote\"). At least one is required.",
                        "default": [
                            "India"
                        ],
                        "items": {
                            "type": "string"
                        }
                    },
                    "timeFrame": {
                        "title": "Time Frame",
                        "enum": [
                            "",
                            "1",
                            "3",
                            "7",
                            "14"
                        ],
                        "type": "string",
                        "description": "Only return jobs posted within this time window.",
                        "default": ""
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
