# Indeed Jobs Scraper – Salary, Description & Apply URL, No Login (`inovaflow/indeed-jobs-scraper`) Actor

Scrape Indeed job postings by keyword, location and country (60+ Indeed sites) without an account. Typed JSON per job: salary, job type, remote flag, posted date, full description, employer profile and apply link — plus a companies-hiring summary.

- **URL**: https://apify.com/inovaflow/indeed-jobs-scraper.md
- **Developed by:** [inovaflow](https://apify.com/inovaflow) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 jobs

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

If you need Indeed job postings as data — for a job board, a recruiting pipeline, a salary study, a lead list of companies that are hiring, or an AI agent that watches the market for you — **Indeed Jobs Scraper** turns any Indeed search into clean, typed JSON. No Indeed account, no cookies, no browser to babysit. It searches **60+ national Indeed sites** (United States, United Kingdom, Canada, Australia, Germany, France, India, Brazil, Japan …) and returns each job with the **full description, salary, job type, remote flag, employer profile and the apply link**.

- **Recruiters & sourcers** — fresh postings by title, city and radius; see which companies are hiring and which are urgent hires.
- **Job boards & aggregators** — a scheduled feed of new roles with full descriptions and salary where disclosed.
- **Sales & B2B teams** — hiring is a buying signal: the run's companies-hiring summary ranks employers by open roles, with company size, industry and website.
- **Analysts, researchers & job seekers** — salary transparency by role and region, remote share, demand by skill.

### What does Indeed Jobs Scraper do?

Give it job titles or keywords and locations (or paste an Indeed search URL from your browser) and it returns the matching **Indeed job postings** — each with title, company, location, posted date, **salary (employer-stated or Indeed's estimate, flagged as such)**, **job type, remote / hybrid / in-person, seniority, benefits**, Indeed's skill tags, occupation categories, urgent-hire signals, the **full job description as text and HTML**, the employer's profile (industry, size, revenue, website, logo) and both the Indeed job URL and the **employer's own apply link** when the job is hosted off Indeed. Duplicates across searches are removed, and a **companies-hiring summary** is written next to the dataset. It works as an **Indeed jobs API**: call it from the Apify API, schedule it, or use it from an AI agent through MCP.

### Why use this Indeed jobs scraper?

- **No login, no cookies, no browser.** Nothing of yours is at risk, and runs are fast: 100 jobs typically take a few seconds.
- **Any country.** Pick the Indeed site — `us`, `gb`, `ca`, `au`, `de`, `fr`, `in`, `br`, `jp` and 50 more — and search in that market's language.
- **Typed fields, not blobs.** Salary is parsed into `salaryMin` / `salaryMax` / `salaryCurrency` / `salaryPeriod` with a `salaryEstimated` flag; job types, workplace, seniority and benefits are separate fields; the posted date is ISO.
- **Real apply links.** For jobs hosted on the employer's site you get the employer's application URL, not just the Indeed page; Indeed-hosted applications are marked `indeed_apply`.
- **Indeed's own filters.** Posted within 24h / 3 / 7 / 14 / 30 days, remote / hybrid / in-person, job type, radius, sort by date — plus your own title / company include-exclude lists.
- **Companies hiring.** Besides the jobs, you get `COMPANIES` — employers ranked by open roles with titles, locations, job types, newest posting and urgent hires — a ready-made hiring-intent signal.
- **Pay per job, no minimums.** 5 jobs cost 5 jobs. Duplicates and filtered-out jobs are free.
- **Built for pipelines.** Deduplicated across searches, CSV exports, webhooks, and 20+ export formats via Apify.

### What data does it extract?

| Field | Description |
| --- | --- |
| `id`, `url` | Indeed job key and the job page on the chosen Indeed site |
| `title`, `normalizedTitle` | Title as posted and Indeed's normalised title |
| `company`, `companyUrl`, `companyIndustry`, `companySize`, `companyRevenue`, `companyWebsite`, `companyDescription`, `companyLogoUrl` | Employer profile |
| `location`, `city`, `region`, `postalCode`, `countryCode` | Location as posted, split into parts |
| `isRemote`, `workplace` | Remote flag; `remote` / `hybrid` / `onsite` when Indeed tags it |
| `jobTypes`, `seniorityLevel`, `benefits` | e.g. `["full-time"]`, `senior`, `["Health insurance", "401(k) matching"]` |
| `postedAt`, `postedTimestamp` | ISO date and epoch milliseconds |
| `salaryText`, `salaryMin`, `salaryMax`, `salaryCurrency`, `salaryPeriod`, `salaryEstimated` | Salary as shown and parsed; `salaryEstimated` is `true` when Indeed estimated it |
| `applyType`, `applyUrl`, `externalUrl` | `indeed_apply` (apply on Indeed) or `external` (employer site); the best link to apply |
| `attributes`, `occupations` | Indeed's skill / requirement / schedule tags and occupation categories |
| `isUrgentHire`, `isHighVolumeHiring` | Indeed's hiring-demand signals |
| `description`, `descriptionHtml` | Full job description as readable text and as HTML |
| `language`, `sourceName` | Posting language; the feed the job came from (employer or partner board) |
| `searchKeywords`, `searchLocation`, `searchCountry`, `scrapedAt` | Provenance |

### How to scrape Indeed jobs

1. Open the Actor and click **Try for free**.
2. Enter **Job titles / keywords** (one per line) and **Locations** (one per line). Every keyword is searched in every location. Pick the **Country** if it is not the United States.
3. Optionally narrow with **Posted within**, **Workplace**, **Job type**, **Search radius**, or paste an Indeed search URL from your browser.
4. Set **Max jobs per search** and click **Start**. 100 jobs with full descriptions take a few seconds.
5. Read the **Output** tab, download **JSON / CSV / Excel**, or open `COMPANIES` to see who is hiring most.

#### How to track new Indeed jobs every day

Set **Posted within** to *Last 24 hours*, **Sort by** to *Most recent*, and schedule the Actor daily in Apify. Add a webhook or an integration (Slack, Google Sheets, Make, Zapier, n8n) to push new rows where your team works.

#### How to find companies that are hiring

Run a broad search — e.g. keyword `sales development representative`, location `Texas`, posted within *Last 7 days*, 500 jobs — and open `COMPANIES`: employers sorted by open roles with company size, industry, titles, locations and newest posting date.

#### How to scrape Indeed in another country

Set **Country** to the Indeed site you want (`gb` for uk.indeed.com, `de` for de.indeed.com, …) and type locations the way locals do (`London`, `Berlin`, `Bengaluru`). Job links point to that country's Indeed site.

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

Pay-per-event: **$0.0005 per job delivered** plus a small run-start fee — **1,000 jobs for about $0.50**. Duplicates, filtered-out jobs and failed searches are never charged. Datacenter proxies (the default) are included in Apify plans.

### Input

Example — two roles in two cities, remote, posted this week, newest first:

```json
{
    "keywords": ["python developer", "data engineer"],
    "locations": ["New York, NY", "Austin, TX"],
    "country": "us",
    "postedWithin": "week",
    "workplace": ["remote"],
    "sortBy": "date",
    "maxJobsPerSearch": 100
}
```

Or paste a search URL from your browser:

```json
{ "startUrls": [{ "url": "https://uk.indeed.com/jobs?q=accountant&l=London&fromage=7" }] }
```

All fields are optional except one of `keywords` / `locations` / `startUrls`. Aliases such as `query`, `title`, `location`, `remote: true`, `limit` and `datePosted` are accepted, so inputs written for other job scrapers usually work unchanged.

### Output

One dataset row per job:

```json
{
    "id": "84079cc285958263",
    "title": "Senior Developer Relations Engineer, GKE and AI Infrastructure",
    "company": "Google",
    "companyUrl": "https://www.indeed.com/cmp/Google",
    "companySize": "10,000+",
    "companyRevenue": "more than $10B (USD)",
    "companyWebsite": "http://goo.gle/3ygdkgv",
    "location": "New York, NY",
    "city": "New York",
    "region": "NY",
    "countryCode": "US",
    "isRemote": false,
    "workplace": null,
    "jobTypes": ["full-time"],
    "seniorityLevel": "senior",
    "benefits": ["Paid holidays", "Disability insurance", "Health insurance", "Dental insurance", "Paid time off", "Parental leave", "Vision insurance", "401(k) matching"],
    "postedAt": "2026-09-09",
    "url": "https://www.indeed.com/viewjob?jk=84079cc285958263",
    "applyUrl": "https://careers.google.com/jobs/results/135563382647333574-senior-developer-relations-engineer/",
    "applyType": "external",
    "salaryText": "$163,000 - $236,000 a year",
    "salaryMin": 163000,
    "salaryMax": 236000,
    "salaryCurrency": "USD",
    "salaryPeriod": "year",
    "salaryEstimated": false,
    "attributes": ["Kubernetes", "Generative AI", "Technical writing", "Bachelor's degree", "Full-time", "Senior level"],
    "occupations": ["Technical Marketers & Marketing Engineers"],
    "isUrgentHire": false,
    "description": "In accordance with Washington state law, we are highlighting our comprehensive benefits package…",
    "searchKeywords": "python developer",
    "searchLocation": "New York, NY",
    "searchCountry": "us"
}
```

Also in the key-value store: `COMPANIES` (+ `COMPANIES.csv`) — employers ranked by open roles — `JOBS.csv`, and `OUTPUT` with run counts (jobs delivered, with salary, remote, companies, filtered, duplicates).

### Using it from AI agents and code

Through the Apify MCP server an agent can call this Actor with plain-language inputs (`keywords`, `locations`, `country`, `postedWithin`). Rows are flat and typed, and the `OUTPUT` summary says exactly how many jobs were delivered, skipped as duplicates or filtered out, so an agent never has to guess. From code, use the Apify API or clients:

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

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('inovaflow/indeed-jobs-scraper').call({
    keywords: ['registered nurse'],
    locations: ['Texas'],
    postedWithin: 'day',
    maxJobsPerSearch: 200,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

### Tips

- **Salary coverage** varies by market — in the United States roughly two thirds of postings carry a stated or estimated salary; `salaryEstimated` tells them apart.
- **Radius 0** searches the exact location only; the default 25 km matches Indeed's own default.
- **Combining a posted-within window with a workplace or job-type filter** makes the run take jobs newest-first and stop as soon as it passes the window, so it stays cheap.
- **Large runs**: each search fetches up to 100 jobs per page, so 1,000 jobs are ~10 requests. Duplicate jobs that appear under several searches are delivered once and charged once.

### FAQ

**Do I need an Indeed account?** No. The Actor never logs in and never uses cookies.

**Is it legal to scrape Indeed?** Job postings are public information published to be found. You are responsible for how you use the data — respect the employers' and Indeed's terms, and personal-data laws where you operate.

**Why does a job have `applyType: "unknown"`?** Indeed did not expose an application route for it; use `url` to open the job on Indeed.

**Can I get jobs from a specific company?** Add the company name to `keywords` (Indeed's `company:` operator works too) or filter the results with `companyExclude` / `titleInclude`.

**Does it work for other countries' Indeed sites?** Yes — 60+ sites via the `country` field, or paste a URL from that site into `startUrls`.

**What happens when Indeed throttles?** The Actor rotates proxies and retries; throttled requests are counted in `OUTPUT.blockedRequests`. Switching the proxy group to residential helps on very large runs.

### Support

Found a field you need or a search that misbehaves? Open an issue on the Actor's **Issues** tab — feedback shapes the roadmap.

# Actor input Schema

## `keywords` (type: `array`):

One search per line, as you would type it into Indeed's *What* box — e.g. `python developer`, `registered nurse`, `account executive`. Indeed's search operators work too: `"data engineer" -senior`, `title:(product manager)`.

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

Cities, regions, postcodes or `Remote` — every keyword is searched in every location (Indeed's *Where* box). E.g. `New York, NY`, `London`, `Berlin`, `Texas`, `Remote`. Leave empty to search the whole country.

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

Which national Indeed site to search — it decides the job pool and the language of the results. Job links point to that site.

## `maxJobsPerSearch` (type: `integer`):

Cap per keyword × location combination. Duplicates across searches are removed automatically.

## `postedWithin` (type: `string`):

Only jobs posted in this window. Filtered-out jobs are never charged.

## `workplace` (type: `array`):

Remote, hybrid and/or in-person. Leave empty for all.

## `jobTypes` (type: `array`):

Leave empty for all types.

## `radiusKm` (type: `integer`):

Distance around each location. `0` = exact location only.

## `titleInclude` (type: `array`):

Keep only jobs whose title contains at least one of these words (case-insensitive). Applied after Indeed's own matching, which can be loose.

## `titleExclude` (type: `array`):

Drop jobs whose title contains any of these words — e.g. `senior`, `intern`, `manager`.

## `companyExclude` (type: `array`):

Drop jobs from companies whose name contains any of these words — handy for skipping staffing agencies.

## `sortBy` (type: `string`):

Order in which Indeed returns the results (affects which jobs make it under the cap). With a *posted within* window plus a workplace/job-type filter, results are always taken newest-first.

## `includeDescriptionHtml` (type: `boolean`):

Adds `descriptionHtml` next to the plain-text `description`. Turn off for smaller rows.

## `skipExpired` (type: `boolean`):

Drop jobs Indeed already marks as expired.

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

Paste `indeed.com/jobs?q=…&l=…` URLs from your browser (any country site) — their keywords, location, radius, date and remote/job-type filters are used as additional searches.

## `maxConcurrency` (type: `integer`):

How many search pages are fetched in parallel. Each page holds up to 100 jobs, so 5 is plenty for most runs.

## `proxyConfiguration` (type: `object`):

Indeed's job feed works well through Apify's datacenter proxies (default). Switch to residential only if you see throttling in the log.

## Actor input object example

```json
{
  "keywords": [
    "python developer"
  ],
  "locations": [
    "New York, NY"
  ],
  "country": "us",
  "maxJobsPerSearch": 50,
  "postedWithin": "any",
  "workplace": [],
  "jobTypes": [],
  "radiusKm": 25,
  "sortBy": "relevance",
  "includeDescriptionHtml": true,
  "skipExpired": true,
  "maxConcurrency": 5,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `jobs` (type: `string`):

One row per job posting with typed fields.

## `companies` (type: `string`):

Employers ranked by open roles found in this run — titles, locations, job types, newest posting, urgent hires (hiring-intent signal).

## `jobsCsv` (type: `string`):

Spreadsheet-ready jobs export (first 5,000 rows).

## `summary` (type: `string`):

Counts: jobs delivered, with salary, remote, companies hiring, filtered, duplicates, throttled requests.

# 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 = {
    "keywords": [
        "python developer"
    ],
    "locations": [
        "New York, NY"
    ],
    "maxJobsPerSearch": 50,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("inovaflow/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 = {
    "keywords": ["python developer"],
    "locations": ["New York, NY"],
    "maxJobsPerSearch": 50,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("inovaflow/indeed-jobs-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "keywords": [
    "python developer"
  ],
  "locations": [
    "New York, NY"
  ],
  "maxJobsPerSearch": 50,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call inovaflow/indeed-jobs-scraper --silent --output-dataset

```

## MCP server setup

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

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

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