# Indeed Jobs Scraper (`metaretica-owner/indeed-jobs-scraper`) Actor

Extract Indeed job listings at 100 jobs/sec across all 63 countries. No proxies needed. Returns the full job payload including compensation models, geodata, occupation taxonomy, employer recruit data, and hidden fields not available via standard scraping.

- **URL**: https://apify.com/metaretica-owner/indeed-jobs-scraper.md
- **Developed by:** [Metaretica](https://apify.com/metaretica-owner) (community)
- **Categories:** Jobs, Automation, Developer tools
- **Stats:** 14 total users, 2 monthly users, 93.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.40 / 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/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 — 100 jobs/sec · All 63 countries · Full field coverage

Extract job listings directly from Indeed's internal API — including fields not exposed in the public UI — at up to **100 jobs per second**, across all 63 countries Indeed operates in. No proxies required. Works with or without a search query.

**[Try it free →](https://console.apify.com)**

***

### What does this Indeed scraper do?

This Actor extracts the full job listing payload for any country Indeed supports, including fields not surfaced in the standard Indeed UI. Output includes compensation models, administrative geodata, employer-submitted recruit data, occupation taxonomies, and auction metadata.

You can run it two ways:

- **With a query** — search for specific roles, companies, or keywords, filtered by country, location, date range, and more
- **Without a query** — retrieve the full job stock for any of the 63 supported countries

Because the data is deeply nested (compensation union types, admin1–4 location hierarchy, multi-field recruit block, occupations array), **JSON is the recommended output format**. CSV and Excel exports are available through the Apify platform but will flatten or truncate nested fields.

***

### What data does this scraper extract?

The Actor returns the complete job listing payload per result. Below is a full field reference.

#### Job essentials

| Field | Description |
|---|---|
| `job.key` | Indeed's unique job key (`jk`) |
| `job.title` | Original job title as submitted by the employer |
| `job.displayTitle` | Indeed's formatted display title |
| `job.normalizedTitle` | Indeed's normalized title (lowercase, canonical form) |
| `job.normalizedCategory` | Broad category (e.g. `food`, `tech`) |
| `job.language` | Language code of the listing (e.g. `fr`, `en`) |
| `job.expired` | Whether the listing is still active |
| `job.datePublished` | Original publication timestamp (milliseconds) |
| `job.dateOnIndeed` | Timestamp when the job was ingested into Indeed's index |
| `job.dateLastAnnotated` | Timestamp of Indeed's last internal annotation update |
| `job.refNum` | Employer's own reference number for the listing |
| `job.url` | Employer's original job posting URL |
| `job.attributes` | Array of `{ key, label }` tags (job type, benefits, skills, etc.) |

#### Employer

| Field | Description |
|---|---|
| `job.employer.name` | Company name as registered on Indeed |
| `job.employer.key` | Indeed's internal employer key |
| `job.sourceEmployerName` | Employer name as it appears in the source feed |

#### Recruit block (employer-submitted data)

The `recruit` block contains data submitted directly by the employer, which may differ from Indeed's own normalized fields.

| Field | Description |
|---|---|
| `job.recruit.title` | Employer's own job title (may differ from `job.title`) |
| `job.recruit.employerName` | Employer name from the recruit feed |
| `job.recruit.viewJobUrl` | Direct URL to the employer's job posting |
| `job.recruit.experience` | Experience requirement string |
| `job.recruit.expirationDate` | Employer-set expiration date |
| `job.recruit.workSchedule` | Work schedule information |
| `job.recruit.detailedSalary` | Detailed salary from the employer's own data |
| `job.recruit.commuteInformation` | Commute details when provided |
| `job.recruit.photoUrl` | Array of employer-provided photo URLs |

#### Compensation

Compensation is returned as a structured object. The `baseSalary.range` field uses union types — each result will be one of `Range` (min + max), `AtLeast` (min only), `AtMost` (max only), or `Exactly` (single value).

| Field | Description |
|---|---|
| `job.compensation.baseSalary.range` | Salary range union: `{ min, max }` / `{ min }` / `{ max }` / `{ value }` |
| `job.compensation.baseSalary.unitOfWork` | Pay period: `YEAR`, `MONTH`, `HOUR`, etc. |
| `job.compensation.currencyCode` | ISO currency code (e.g. `EUR`, `USD`, `GBP`) |
| `job.compensation.formattedText` | Human-readable salary string when available |
| `job.compensation.salarySource` | How Indeed obtained the salary figure |
| `job.compensation.estimated.baseSalary` | Indeed's estimated salary when employer did not provide one |
| `job.compensation.estimated.formattedText` | Formatted estimated salary string |
| `job.compensation.key` | Base64-encoded compensation protobuf (full internal salary model) |

#### Location

The location block includes a full administrative hierarchy — useful for regional filtering and geodata pipelines.

| Field | Description |
|---|---|
| `job.location.city` | City name |
| `job.location.postalCode` | Postal / ZIP code |
| `job.location.neighborhood` | Neighborhood when available |
| `job.location.streetAddress` | Street address when available |
| `job.location.countryCode` | ISO country code (e.g. `FR`, `DE`, `US`) |
| `job.location.countryName` | Full country name |
| `job.location.admin1Code` | Level-1 administrative division code (region / state) |
| `job.location.admin1Name` | Level-1 administrative division name |
| `job.location.admin2Code` | Level-2 administrative division code (department / county) |
| `job.location.admin2Name` | Level-2 administrative division name |
| `job.location.admin3Code` | Level-3 subdivision code when available |
| `job.location.admin3Name` | Level-3 subdivision name when available |
| `job.location.admin4Code` | Level-4 subdivision code when available |
| `job.location.admin4Name` | Level-4 subdivision name when available |
| `job.location.latitude` | Latitude coordinate |
| `job.location.longitude` | Longitude coordinate |
| `job.location.formatted.short` | Short formatted location (e.g. `Grenoble (38)`) |
| `job.location.formatted.long` | Long formatted location (e.g. `38100 Grenoble`) |

#### Job description

| Field | Description |
|---|---|
| `job.description.html` | Full job description as HTML |
| `job.description.text` | Full job description as plain text |
| `job.description.hash32` | 32-bit hash of the description (useful for deduplication) |

#### Occupations & attributes

| Field | Description |
|---|---|
| `job.occupations` | Array of `{ key, label }` — Indeed's occupation taxonomy |
| `job.attributes` | Array of `{ key, label }` — tags for job type, benefits, skills, schedules, work arrangements |

##### Occupation categories

Indeed's occupation taxonomy is organized into 23 top-level categories, each subdivided up to 6 tiers. The `occupations` array on each listing may contain one or more entries at any tier level.

| Tier 1 category | SUID |
|---|---|
| Architecture & Engineering | `HY4VD` |
| Business Operations & Management | `MGTWW` |
| Cleaning & Grounds Maintenance | `67D4Z` |
| Community & Human Services | `BCMJX` |
| Construction & Extraction | `SZ69B` |
| Education & Instruction | `AB5HX` |
| Farming, Fishing & Forestry | `5FNC8` |
| Finance & Accounting | `6YCJB` |
| Food & Beverage | `NPKCD` |
| Healthcare | `CFV7X` |
| Legal | `W727U` |
| Manufacturing & Utilities | `6XYW3` |
| Marketing, Advertising & Public Relations | `W83QK` |
| Media, Arts & Design | `SWYS8` |
| Personal Service | `DSCP2` |
| Protective & Security | `HNQ6F` |
| Repair, Maintenance & Installation | `YAQ96` |
| Sales & Retail | `NTGY4` |
| Science & Research | `585N6` |
| Supply Chain & Logistics | `TVT66` |
| Technology | `EHPW9` |
| Transportation | `CKA43` |
| Travel, Attractions & Events | `FYPW9` |

→ Full occupation SUID reference (all tiers): [docs.indeed.com/job-sync-api/reference/occupations](https://docs.indeed.com/job-sync-api/reference/occupations)

##### Attribute categories

The `attributes` array uses 5-character SUIDs drawn from Indeed's search attribute taxonomy. Attributes cover:

- **Technical skills** — programming languages, software tools, certifications (e.g. `GFRKJ` AWS, `RY9MK` Linux, `HT6WW` Machine learning)
- **Benefits & perks** — remote work, company housing, transport allowance, restaurant d'entreprise
- **Work arrangements** — flextime, part-time, side-job friendly
- **Requirements** — licenses, education level, experience thresholds
- **Schedule options** — shift patterns, on-call, overtime (see Shifts & schedules below)
- **Job characteristics** — entry-level, management experience required, bilingual

→ Full attribute SUID reference (58 categories): [docs.indeed.com/job-sync-api/reference/search-attributes](https://docs.indeed.com/job-sync-api/reference/search-attributes)

##### Shifts & schedules

Schedule-related attributes that commonly appear in the `attributes` array:

| Concept | SUID | Applies in |
|---|---|---|
| **Weekly schedule** | | |
| Monday to Friday | `SAP7A` | AT, AU, BE, BR, CA, CH, DE, DK, ES, FR, GB, HK, IE, IN, IT, MX, MY, NL, NO, NZ, PH, PL, PT, SE, SG, US |
| Weekend availability | `7SRRR` | AT, AU, BE, BR, CA, CH, DE, DK, ES, FR, GB, HK, IE, IN, IT, JP, MX, MY, NL, NO, NZ, PH, PL, PT, SE, SG, US |
| Weekends only | `5HX7D` | AT, AU, BE, BR, CA, CH, DE, DK, ES, FR, GB, HK, IE, IN, IT, MX, NL, NZ, PL, PT, SE, US |
| No weekends | `FM8WH` | AT, AU, CA, CH, DE, FR, GB, IE, IT, NZ, PL, US |
| Flextime | `HY5VT` | BE, CA, DE, DK, ES, FR, GB, IE, IT, JP, NL, NO, PH, PL, PT, US |
| Shift system | `SUDVY` | AU, BE, BR, DE, ES, FI, HK, HU, IN, IT, JP, MX, NL, NO, NZ, PH, PL, PT, SE, SG, UA |
| **Shift length** | | |
| 8 hour shift | `5GUGE` | AT, AU, BR, CA, CH, DE, ES, FR, GB, IE, MX, NZ, PH, PL, PT, US |
| 10 hour shift | `EQHS8` | AT, AU, CA, CH, DE, ES, FR, GB, IE, MX, NZ, PH, PL, US |
| 12 hour shift | `4XK2Y` | AT, AU, BR, CA, CH, DE, ES, FR, GB, IE, MX, NZ, PH, PL, PT, US |
| **Shift time** | | |
| Morning shift | `FDF8V` | AU, CA, CH, DE, FR, HK, IN, JP, MX, MY, NZ, PH, PL, SG, US |
| Day shift | `PMS5Q` | AT, AU, BE, BR, CA, CH, DE, ES, FR, GB, HK, IE, IN, IT, JP, MX, MY, NL, NZ, PH, PL, PT, SE, SG, US |
| Evening shift | `K8AKP` | AT, AU, BE, CA, CH, DE, FR, IE, IN, JP, MY, NL, NZ, PH, SE, US |
| Night shift | `H3N5U` | AT, AU, BE, BR, CA, CH, DE, DK, ES, FR, GB, HK, IE, IN, IT, JP, MX, MY, NL, NO, NZ, PH, PL, PT, SE, SG, US |
| Rotating shift | `JCVZE` | AU, CA, FR, GB, IN, MX, MY, NZ, PH, RU, UA, US |
| **Supplemental** | | |
| On call | `VZD9Q` | AT, AU, BE, CA, CH, DE, ES, HK, IE, MX, MY, NL, NZ, PH, SE, SG, US |
| Overtime | `5WFZM` | AT, AU, BE, CA, CH, DE, ES, FR, GB, IE, IT, JP, MX, NL, NZ, PH, PL, SE, US |
| Holiday work possible | `VDB9U` | AT, AU, BE, BR, CA, CH, DE, ES, FR, GB, HK, IE, IT, JP, MX, MY, NL, NZ, PH, PL, PT, SG, US |

→ Full shifts & schedules reference: [docs.indeed.com/job-sync-api/reference/shifts-and-schedules](https://docs.indeed.com/job-sync-api/reference/shifts-and-schedules)

##### Work systems (Japan)

When scraping Japanese listings, the `attributes` array may include work system SUIDs defined under Japanese labor law:

| Work system | SUID | Description |
|---|---|---|
| Fixed working hours | `A4MXD` | Standard set schedule with consistent start and end times |
| Flextime | `HY5VT` | Employees choose their hours within core hours |
| Shift system | `SUDVY` | Rotating morning / afternoon / night shifts |
| Variable working hours | `3VJ3F` | Hours vary by period while averaging within legal limits |
| Deemed working hours (outside workplace) | `VK3PA` | For field work where tracking hours is difficult |
| Discretionary system (professional) | `BDNYH` | Specialized professional work with employee discretion |
| Discretionary system (planning) | `KU3VM` | Strategic planning work with employee discretion |
| Highly Professional System | `3943V` | High-income professionals exempt from certain labor regulations |

→ Full work systems reference: [docs.indeed.com/job-sync-api/reference/work-systems](https://docs.indeed.com/job-sync-api/reference/work-systems)

#### Application

| Field | Description |
|---|---|
| `job.indeedApply.key` | Base64 Indeed Apply configuration object |
| `job.indeedApply.scopes` | Availability: `DESKTOP`, `MOBILE` |
| `job.tracking.applyStartClick.url` | Full tracking URL with `jk`, `jobsearchTk`, `indpubnum` parameters |

#### Feed & source

| Field | Description |
|---|---|
| `job.feed.feedSourceType` | Source type: `EMPLOYER` (direct) or `JOB_BOARD` (aggregated) |
| `job.feed.isDradis` | Internal Dradis feed flag |
| `job.feed.key` | Opaque feed identifier |
| `job.source.key` | Opaque source identifier (distinct from feed key) |

#### Grouping & auction

| Field | Description |
|---|---|
| `group.count` | Number of listings grouped under this result |
| `group.key` | Group identifier for deduplication |
| `auction` | Sponsored listing auction data when present |
| `encodedAdData` | Encoded advertisement metadata when present |

#### Search metadata

| Field | Description |
|---|---|
| `metadata.what` | The search term that matched this result |
| `metadata.keywords` | Array of keywords Indeed matched against |

***

### Sample output

```json
{
  "group": {
    "count": 1,
    "key": "kAP-2YoHmAPh4MKRA6ADAfIHA3RjbA=="
  },
  "job": {
    "key": "a00d8c161c55cdcd",
    "title": "EMPLOYÉ(E) POLYVALENT(E) DE CUISINE EN RESTAURATION RAPIDE",
    "displayTitle": "Cuisinier (H/F)",
    "normalizedTitle": "cuisinier",
    "normalizedCategory": "food",
    "language": "fr",
    "expired": false,
    "datePublished": 1570165200000,
    "dateOnIndeed": 1732308703791,
    "dateLastAnnotated": 1773062111718,
    "url": "https://www.originel.com/offre-emploi/employe-de-cuisine-en-restauration-rapide/",
    "attributes": [
      { "key": "CF3CP", "label": "Temps plein" },
      { "key": "T9BXE", "label": "CDD" },
      { "key": "NA9HP", "label": "Primes" },
      { "key": "YXGDY", "label": "Cuisine" }
    ],
    "employer": {
      "name": "Originel",
      "key": "e465e7d7603c9368"
    },
    "sourceEmployerName": "originel",
    "recruit": {
      "title": "EMPLOYÉ(E) POLYVALENT(E) DE CUISINE EN RESTAURATION RAPIDE",
      "employerName": "originel",
      "viewJobUrl": "https://www.originel.com/offre-emploi/employe-de-cuisine-en-restauration-rapide/",
      "experience": "",
      "expirationDate": null,
      "workSchedule": null,
      "detailedSalary": null,
      "commuteInformation": null,
      "photoUrl": []
    },
    "compensation": {
      "baseSalary": null,
      "currencyCode": null,
      "formattedText": null,
      "salarySource": null,
      "estimated": null,
      "key": "CMrYnfMWHQB4tEYgmpXUGy..."
    },
    "location": {
      "city": "Grenoble",
      "postalCode": "38100",
      "countryCode": "FR",
      "countryName": "France",
      "admin1Code": "ARA",
      "admin1Name": "Auvergne-Rhône-Alpes",
      "admin2Code": "38",
      "admin2Name": "Isère",
      "admin3Code": null,
      "admin3Name": null,
      "latitude": 45.157455,
      "longitude": 5.73303,
      "formatted": {
        "short": "Grenoble (38)",
        "long": "38100 Grenoble"
      }
    },
    "description": {
      "hash32": -958556346,
      "text": "À propos d'Originel\n\nORIGINEL vous invite à découvrir...",
      "html": "<div><h2>À propos d'Originel</h2>..."
    },
    "occupations": [
      { "key": "6AEZW", "label": "Employés/es polyvalents/es en restauration rapide" },
      { "key": "NPKCD", "label": "Métiers de la restauration" }
    ],
    "feed": {
      "feedSourceType": "EMPLOYER",
      "isDradis": false,
      "key": "AAAAAYCT999rKsxxcmMVIY..."
    },
    "indeedApply": {
      "key": null,
      "scopes": []
    },
    "tracking": {
      "applyStartClick": {
        "url": "http://fr.indeed.com/applystart?jk=a00d8c161c55cdcd&jobsearchTk=..."
      }
    }
  },
  "metadata": {
    "what": "serveur",
    "keywords": ["serveuse", "serveur", "serveuses", "serveurs"]
  }
}
```

***

### How to scrape Indeed jobs — step by step

1. Click **Try for free** at the top of this page
2. Create a free Apify account if you don't have one
3. Set `country` and optionally a `query`, `location`, and date filters
4. Click **Start**
5. When the run finishes, download your dataset as JSON

No proxy setup. No browser configuration. No technical knowledge required.

***

### Input options

#### Option A — search by query

```json
{
  "query": "data analyst",
  "country": "us",
  "location": "New York, NY",
  "sort": "date",
  "startDate": 1700000000000,
  "maxResults": 500
}
```

#### Option B — full country enumeration (no query)

```json
{
  "country": "pl",
  "maxResults": 50000
}
```

Leave `query` empty or omit it entirely to retrieve the full job stock for the selected country.

#### Supported input parameters

| Parameter | Required | Description |
|---|---|---|
| `country` | Yes | Indeed country market (see full list below) |
| `query` | No | Job title or keyword. Omit for full country enumeration |
| `location` | No | City, region, or address |
| `startDate` | No | Filter by `dateOnIndeed` range start — Unix timestamp in milliseconds |
| `endDate` | No | Filter by `dateOnIndeed` range end — Unix timestamp in milliseconds |
| `sort` | No | `DATE` or `RELEVANCE` |
| `maxResults` | No | Result cap |

***

### All 63 supported countries

Sourced directly from [indeed.com/worldwide](https://www.indeed.com/worldwide).

| Country | Code | Country | Code | Country | Code |
|---|---|---|---|---|---|
| Argentina | `ar` | Hungary | `hu` | Saudi Arabia | `sa` |
| Australia | `au` | India | `in` | Singapore | `sg` |
| Austria | `at` | Indonesia | `id` | South Africa | `za` |
| Bahrain | `bh` | Ireland | `ie` | South Korea | `kr` |
| Belgium | `be` | Israel | `il` | Spain | `es` |
| Brazil | `br` | Italy | `it` | Sweden | `se` |
| Canada | `ca` | Japan | `jp` | Switzerland | `ch` |
| Chile | `cl` | Kuwait | `kw` | Taiwan | `tw` |
| China | `cn` | Luxembourg | `lu` | Thailand | `th` |
| Colombia | `co` | Malaysia | `malaysia` | Turkey | `tr` |
| Costa Rica | `cr` | Mexico | `mx` | Ukraine | `ua` |
| Czech Republic | `cz` | Morocco | `ma` | United Arab Emirates | `ae` |
| Denmark | `dk` | Netherlands | `nl` | United Kingdom | `uk` |
| Ecuador | `ec` | New Zealand | `nz` | United States | `us` |
| Egypt | `eg` | Nigeria | `ng` | Uruguay | `uy` |
| Finland | `fi` | Norway | `no` | Venezuela | `ve` |
| France | `fr` | Oman | `om` | Vietnam | `vn` |
| Germany | `de` | Pakistan | `pk` | — | — |
| Greece | `gr` | Panama | `pa` | — | — |
| Hong Kong | `hk` | Peru | `pe` | — | — |
| — | — | Philippines | `ph` | — | — |
| — | — | Poland | `pl` | — | — |
| — | — | Portugal | `pt` | — | — |
| — | — | Qatar | `qa` | — | — |
| — | — | Romania | `ro` | — | — |

***

### How much does it cost to scrape Indeed?

This Actor uses **pay-per-event (PPE)** pricing. Compute is free. You are charged only for results written to the dataset, plus a negligible one-time start fee per run.

| Event | Cost |
|---|---|
| Per result (dataset item) | $0.0049 |
| Per run start | $0.00005 |

Volume discounts apply automatically based on your Apify subscription tier:

| Tier | Per result |
|---|---|
| No discount | $0.0049 |
| Bronze | $0.0044 |
| Silver | $0.0039 |
| Gold | $0.0034 |

**Example:** 100,000 results at the standard rate = **$490**, plus $0.00005 for the run start.

No proxy fees. No compute charges. No surprises.

An Apify account is required to run this Actor. See [apify.com/pricing](https://apify.com/pricing) for platform subscription tiers.

#### Enterprise & bulk pricing

For high-volume or enterprise use cases, fixed pricing with unlimited results is available. Reach out at <etr@metaretica.com>.

***

### Use cases

**Labor market research** — build compensation benchmarks, skills demand analyses, or hiring trend reports across countries and industries. The structured compensation union types and occupation taxonomy are directly usable without post-processing.

**Job market datasets by country** — the full enumeration mode (empty query) produces country-wide job stock snapshots. With date range filtering on `dateOnIndeed`, you can retrieve only listings added within a specific window, enabling incremental dataset updates.

**Recruitment intelligence** — monitor company hiring activity by filtering on `employer.key` or `sourceEmployerName`. The `feed.feedSourceType` field distinguishes direct employer postings (`EMPLOYER`) from aggregated listings (`JOB_BOARD`).

**HR tech and ATS enrichment** — pipe fresh job market data into your product to give clients real-time market context for their open roles and salary ranges.

**Job aggregation** — maintain a continuously refreshed index of Indeed listings. The `description.hash32` field makes deduplication straightforward, and date range filtering on `dateOnIndeed` enables incremental indexing.

**Salary benchmarking** — the `compensation.baseSalary.range` union types and `compensation.estimated` block provide structured salary data at a level of detail not available from rendered HTML scraping.

**Lead generation** — `job.url`, `job.recruit.viewJobUrl`, `tracking.applyStartClick.url`, and `employer.key` provide multiple contact and identification vectors for companies actively hiring.

***

### Integrations

The Actor integrates with the full Apify platform stack:

- **Apify API** — trigger runs and fetch results programmatically in any language
- **Make / Zapier** — pipe job data into Google Sheets, Airtable, Slack, or any SaaS tool
- **Webhooks** — get notified when a run completes
- **Scheduling** — run on any cron-based cadence for continuous dataset freshness

#### API example (Python)

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("YOUR_ACTOR_ID").call(run_input={
    "query": "software engineer",
    "country": "de",
    "location": "Berlin",
    "maxResults": 1000,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

#### API example (JavaScript)

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

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

const run = await client.actor('YOUR_ACTOR_ID').call({
    query: 'product manager',
    country: 'fr',
    maxResults: 500,
});

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

***

### FAQ

**Is it legal to scrape Indeed?**
This Actor only extracts publicly available job listing data accessible via Indeed's API. It does not extract private user data, bypass authentication, or access anything that is not already public. We recommend using extracted data responsibly and in compliance with applicable laws in your jurisdiction, including GDPR in the EU. See Apify's blog post on [the legality of web scraping](https://blog.apify.com/is-web-scraping-legal/) for further context.

**Why is JSON the recommended output format?**
The raw API schema is deeply nested — compensation is a union type with four possible shapes, location includes up to four administrative levels, and occupations and attributes are arrays of objects. Flattening this to CSV or Excel without losing information requires post-processing decisions that vary by use case. Export as JSON and transform downstream to suit your needs. CSV is available on the Apify platform if you only need top-level scalar fields.

**Why doesn't this Actor need proxies?**
This Actor operates at the API level rather than rendering web pages, which means it does not trigger the IP-based rate limiting that browser-based scrapers encounter. This is also why throughput reaches 100 jobs/sec and platform credit costs remain minimal regardless of result volume.

**Does the empty-query mode really return all jobs in a country?**
Yes. When the `what` parameter is omitted, Indeed's API returns the full job stock for the specified country market. The Actor handles traversal automatically up to your `maxResults` cap.

**What is `dateOnIndeed` vs `datePublished` vs `dateLastAnnotated`?**
Three distinct timestamps. `datePublished` is when the employer originally published the role — it may be years old for evergreen listings. `dateOnIndeed` is when Indeed ingested the listing into its index, and is the most useful field for freshness filtering. `dateLastAnnotated` is when Indeed last updated its internal annotation of the listing (taxonomy, compensation estimates, etc.).

**What is `feed.feedSourceType`?**
It distinguishes `EMPLOYER` listings (posted directly by the company) from `JOB_BOARD` listings (aggregated from third-party job boards). Useful when you want to filter for direct employer postings only.

**What is the `compensation.key` field?**
A base64-encoded protobuf containing Indeed's full internal compensation model, including inferred pay ranges, salary type, currency, and schema version. It is included in the output as-is. The decoded compensation data is also surfaced in the structured `baseSalary` and `estimated` fields.

**What happens if Indeed changes its API?**
We monitor the Actor continuously. If an API change causes failures, we push a fix and announce it in the changelog.

***

### Issues and feedback

Found a bug or want to request a feature? Open a ticket in the **Issues** tab. We respond within 24 hours for active subscribers.

# Actor input Schema

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

Indeed country market code (e.g. us, fr, de, uk). See README for all 63 supported codes.

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

Job title, keyword, or company name. Leave empty to retrieve the full job stock for the country.

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

City, region, or address to restrict results to.

## `sort` (type: `string`):

Sort results by date or relevance.

## `startDate` (type: `integer`):

Filter by dateOnIndeed range start — Unix timestamp in milliseconds.

## `endDate` (type: `integer`):

Filter by dateOnIndeed range end — Unix timestamp in milliseconds.

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

Cap on the number of results to return. Omit for unlimited.

## Actor input object example

```json
{
  "country": "us",
  "query": "software engineer",
  "location": "New York",
  "sort": "DATE"
}
```

# Actor output Schema

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

All scraped job listings. Use the overview view for a flat table of key fields, or fetch raw items for the full nested payload.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("metaretica-owner/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 = {}

# Run the Actor and wait for it to finish
run = client.actor("metaretica-owner/indeed-jobs-scraper").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 '{}' |
apify call metaretica-owner/indeed-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/ww7nOA7CceZkd6jS0/builds/feJ01yjnQFZZgshT6/openapi.json
