# Indeed Comprehensive Crawler (`memo23/apify-indeed`) Actor

The most comprehensive Indeed crawler Extract every field Indeed exposes: salary, job type, benefits, company rating & reviews, hiring insights, GPS coordinates, full company profile (CEO, revenue, industry, website), the real external apply URL. Search by URL, keyword or region across 60+ countries

- **URL**: https://apify.com/memo23/apify-indeed.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Jobs, Lead generation, Agents
- **Features:** Limited permissions
- **Stats:** 224 total users, 7 monthly users, 100.0% runs succeeded, 6 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.19 / 1,000 results

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 Comprehensive Crawler — Jobs, Salaries & Company Intelligence

The most complete Indeed scraper: paste an Indeed search URL and extract **every field Indeed exposes** — salary, job type, benefits, requirements, company rating & reviews, hiring insights, GPS coordinates, a full company profile (CEO, revenue, industry, website), and the **real external apply URL** resolved past Indeed's redirect to the employer's own site / ATS.

> Other versions of this scraper:
>
> - **Fast Indeed Scraper (Search by URL):** [apify.com/memo23/apify-indeed-cheerio-ppr](https://apify.com/memo23/apify-indeed-cheerio-ppr)
> - **Search by keyword (no URL needed):** [apify.com/memo23/apify-indeed-cheerio-keywords-ppr](https://apify.com/memo23/apify-indeed-cheerio-keywords-ppr)

***

### Why use this scraper

- **Maximum depth.** Built to capture the complete job record and the complete company record in one pass.
- **Every filter, for free.** You paste a real Indeed URL, so every filter — keyword, location, radius, date, remote, job type, experience level, salary, sort — is honored exactly as on Indeed.
- **Gets ALL results.** Pulls the full result set, well past Indeed's ~25-jobs-per-page cap.
- **Resolved external apply URL.** Follows the redirect chain to the **final employer/ATS apply URL** — rare among Indeed scrapers, essential for recruiting and lead-gen.
- **Company intelligence.** CEO (with photo), founding year, revenue, employee-size range, industry, website, rating and review count.
- **Region auto-expansion.** A country/region URL is fanned out into per-city searches and deduplicated — typically **2–5× more unique jobs**.
- **Clean output.** Flat or nested JSON, exportable to CSV / Excel.

***

### What it does

Give it one or more Indeed search URLs. It loads the search, pulls every reachable listing, opens each job for full detail, enriches with the company profile, optionally resolves the external apply URL, removes duplicates, and returns structured records for analytics, job boards, ATS/CRM imports, salary studies, and market research.

***

### How to get your Indeed URL

1. Go to [indeed.com](https://www.indeed.com) (or your country's Indeed, e.g. `de.indeed.com`).
2. Search and apply any filters you want.
3. Copy the URL and paste it into **Start URLs**. The scraper reproduces that exact search and returns the full result set.

***

### Supported inputs

| Input | What it does |
|---|---|
| **Start URLs** | One or more Indeed search (or job) URLs — all filters honored |
| **Include company details** | Add the full company profile (CEO, revenue, industry…) — on by default for this actor |
| **Expand to cities** | Fan a country/region URL into per-city searches for 2–5× more results |
| **Resolve external apply URL** | Follow redirects to the real employer/ATS apply link |
| **Strict keyword match** | Keep only jobs whose title/description match the URL's keyword |
| **One job per company** | Return at most one job per employer — unique companies only |
| **Only external jobs** | Keep only jobs that apply on an external site |
| **Flatten output** | Flat top-level fields (great for CSV) vs the raw nested model |
| **Max jobs** | Cap the number of results |

***

### Use cases

- **Recruiting & sourcing** — live openings with the direct apply URL and full company profile.
- **Lead generation** — companies actively hiring, enriched with CEO, industry, size, website.
- **Salary benchmarking** — structured salary ranges with currency and pay period.
- **Job boards & aggregators** — a fresh, deduplicated feed of postings.
- **Market & talent research** — hiring demand by role, location, and seniority over time.

***

### How it works

1. Each Start URL (and, with expansion, its per-city variants) is loaded via Indeed's mobile endpoints.
2. The actor pulls the full result set, beyond the first page.
3. Each job is opened for full detail — description, salary, company, ratings, location/GPS.
4. The company profile is enriched (CEO, revenue, industry, website…).
5. If enabled, it resolves the external apply URL by following Indeed's redirect chain.
6. Results are deduplicated by job key and written to the dataset (flat or nested).

***

### Input configuration

Set inputs in the visual **Input** tab, or pass JSON via the API. Minimal example:

```json
{
  "startUrls": [
    { "url": "https://www.indeed.com/jobs?q=data+scientist&l=New+York&fromage=7" }
  ],
  "includeCompanyDetails": true,
  "resolveExternalApplyUrl": true,
  "maxJobs": 1000
}
```

***

### Output overview

Each row is one job, fully flattened (with `flattenOutput`) or as the raw nested model. You get the job, its salary, the company and its full profile, the location with coordinates, and apply links. A live sample is always available on the actor's **Output** tab after any run.

#### Key output fields

| Field | Description |
|---|---|
| `positionName` / `normTitle` | Job title |
| `company` | Employer name |
| `salary`, `salaryMin`, `salaryMax`, `salaryType`, `currency` | Parsed compensation |
| `jobType` | Full-time / Part-time / Contract / … |
| `remote` | Remote flag |
| `location`, `city`, `countryCode`, `postalCode`, `latitude`, `longitude` | Where the job is |
| `datePublished`, `dateOnIndeed` | When it was posted |
| `jobDescription`, `jobDescriptionHtml` | Full description (text + HTML) |
| `requirements`, `benefits` | Parsed requirements & benefits |
| `companyRating`, `reviewsCount` | Employer rating & review count |
| `companyDetailsCeoName`, `companyDetailsRevenue`, `companyDetailsIndustry`, `companyDetailsWebsite`, `companyDetailsEmployeesCount`, `companyDetailsFoundedYear` | Full company profile |
| `externalApplyUrl`, `externalApplyLink` | Resolved external/ATS apply URL |
| `url`, `jobUrl` | Canonical Indeed listing URL |

***

### FAQ

**How is this different from the Fast Indeed Scraper?**
Same core engine; this version is tuned for **maximum depth** — full company intelligence by default and the most complete per-job record. If you want the leanest/fastest run, use the [Fast Indeed Scraper](https://apify.com/memo23/apify-indeed-cheerio-ppr).

**Do all Indeed filters work?**
Yes — whatever is in the URL you paste (date, remote, salary, job type, experience level, sort…) is applied exactly as on Indeed.

**Prefer not to build a URL?**
Use the [Search-by-keyword version](https://apify.com/memo23/apify-indeed-cheerio-keywords-ppr).

**Can I export to CSV / Excel?**
Yes — via Apify's dataset export (JSON, CSV, Excel) or the API.

***

### Support

- [Report an issue](https://console.apify.com/actors/QNo4EnLhQ77U5VQf8#/issues)
- Request a customization or a private API (no Apify fee, usage only): <muhamed.didovic@gmail.com>
- Need a different site scraped? Email me: <muhamed.didovic@gmail.com>

***

### Explore more of my scrapers

- [Fast Indeed Jobs Scraper — Search by URL](https://apify.com/memo23/apify-indeed-cheerio-ppr)
- [Indeed Jobs Scraper — Search by Keyword (no URL needed)](https://apify.com/memo23/apify-indeed-cheerio-keywords-ppr)
- [Indeed Company Reviews Scraper](https://apify.com/memo23/apify-indeed-reviews-ppr)

***

### ⚠️ Disclaimer

This scraper collects only **publicly available** job data from Indeed. It does not access private, gated, or personal data, and is intended for lawful purposes such as recruitment, market research, and analytics. You are responsible for using the scraped data in compliance with Indeed's terms and applicable laws (including data-protection regulations).

***

**Keywords:** indeed scraper, indeed jobs scraper, comprehensive indeed crawler, scrape indeed, indeed api, job scraper, job listings, salaries, company intelligence, CEO data, remote jobs, recruitment data, lead generation, ATS apply url, job board feed.

# Actor input Schema

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

URLs to start with.

## `includeCompanyDetails` (type: `boolean`):

Set to true if you want to scrape company details.

## `resolveExternalApplyUrl` (type: `boolean`):

When enabled, jobs that redirect to a client site or ATS (have a `thirdPartyApplyUrl`) will be followed through Indeed's redirect chain so that the final external apply URL is captured into the `externalApplyUrl` field. Adds one extra HTTP request per applicable job.

## `onlyExternalJobs` (type: `boolean`):

Set to true if you want to only external sources when scraping.

## `maxJobs` (type: `integer`):

Maximum number of jobs to extract per start URL. With several start URLs (or a region expanded into cities), the run can return up to this number times the number of URLs. The run also stops early if it reaches the maximum cost per run you set.

## `flattenOutput` (type: `boolean`):

Set to true to output a flat data structure with all nested objects flattened into top-level fields. When enabled, nested objects are flattened (e.g., salary details, location, company info become individual fields). When disabled, the raw nested API response is preserved.

## `expandToCities` (type: `boolean`):

When enabled (default), search URLs whose location is a country or large region (e.g. `l=Scotland`, `l=United Kingdom`, `l=East+of+England+Region`) are automatically fanned out into a list of major-city search URLs and the results deduped by `jobId`. Indeed caps mobile SERP pagination per query, so the union of city-level queries typically yields 2-5x more total results than the parent region query. Indeed's UI emits `radius=0` (exact-match) for region chips, which would return near-zero jobs at the city level, so a `radius=0` on the parent URL is automatically bumped to `radius=25` (Indeed's UI default) for the city queries. Set to `false` to disable fan-out and scrape the exact URL you provided. No effect when the location is already a city, postcode, or empty.

## `strictMatch` (type: `boolean`):

When enabled, drops any job whose title or description does not contain your search keyword(s). Indeed's own search pads every result page with loosely-related and sponsored jobs (e.g. a 'Real Estate Agent' or 'CDL Driver' for a `typescript` search) — those appear in the output by default because the scraper returns exactly what Indeed returns. Turn this on to keep only genuine keyword matches. Keys on the `q` of your search URL. Leave off (default) to get Indeed's full result set unchanged.

## `uniqueCompanies` (type: `boolean`):

When enabled, the output contains at most one job per company — every row is a distinct employer. Dedupes on Indeed's encrypted company id (so 'Acme Inc' and 'Acme Inc.' count as one), falling back to the company name. Note: because many listings share an employer, reaching a target number of unique companies means scanning more jobs, so a narrow search may return fewer unique companies than `maxJobs`. Leave off (default) to return every job.

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

Specifies proxy servers that will be used by the scraper in order to hide its origin.<br><br>For details, see <a href='https://apify.com/apify/web-scraper#proxy-configuration' target='_blank' rel='noopener'>Proxy configuration</a> in README.

## Actor input object example

```json
{
  "startUrls": [
    {
      "url": "https://www.indeed.com/jobs?q=Teacher&l=California"
    }
  ],
  "includeCompanyDetails": false,
  "resolveExternalApplyUrl": true,
  "onlyExternalJobs": false,
  "maxJobs": 20,
  "flattenOutput": false,
  "expandToCities": true,
  "strictMatch": false,
  "uniqueCompanies": false,
  "proxy": {
    "useApifyProxy": true
  }
}
```

# 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 = {
    "startUrls": [
        {
            "url": "https://www.indeed.com/jobs?q=Teacher&l=California"
        }
    ],
    "proxy": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/apify-indeed").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 = {
    "startUrls": [{ "url": "https://www.indeed.com/jobs?q=Teacher&l=California" }],
    "proxy": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("memo23/apify-indeed").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 '{
  "startUrls": [
    {
      "url": "https://www.indeed.com/jobs?q=Teacher&l=California"
    }
  ],
  "proxy": {
    "useApifyProxy": true
  }
}' |
apify call memo23/apify-indeed --silent --output-dataset

```

## MCP server setup

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

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/QNo4EnLhQ77U5VQf8/builds/3RDmlwYMtAlUiqsj6/openapi.json
