# Indeed Jobs Scraper — Salaries, Company Ratings, 62 Countries (`yugenox/indeed-jobs-scraper`) Actor

Scrape Indeed jobs in 62 countries: title, company, rating and reviews, salary with a yearly equivalent, job type, remote/hybrid, Easy Apply, urgent-hire flags, GPS and full description. Goes past Indeed's 1,000-result limit and can return only new jobs for daily alerts.

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

## Pricing

from $0.10 / 1,000 job or company rows

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?

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 Jobs Scraper

Scrape job listings from **Indeed in 62 countries**: job title, company, company rating and review count, salary (with a yearly equivalent), job type, remote/hybrid/on-site, Easy Apply, urgent-hire flags, GPS coordinates, the full job description and the employer's profile (industry, size, revenue, website, logo).

No Indeed account, no cookies, nothing to set up. Type a job title and a location, press **Start**, download the results as JSON, CSV or Excel.

### Why this Indeed scraper

- **Goes past Indeed's 1,000-result limit.** Indeed shows at most about 1,000 jobs per search, and often fewer. When your search hits that ceiling and you asked for more, the scraper splits it automatically: by state or province for nationwide searches, then by posting date. Duplicates are removed. In our tests "software engineer" in New York went from 996 jobs to **3,796**, and "customer service" across the US in the last 24 hours went from about 880 to **4,512**.
- **Only new jobs (monitoring mode).** Run the same search every day and get just the jobs you haven't received yet, and only pay for those. It works as a job-alert feed, an ATS import or a "who started hiring" signal.
- **Salaries you can compare.** Hourly, daily, weekly and monthly pay is also given as a yearly amount (`salaryAnnualMin` / `salaryAnnualMax`), with the currency and whether the employer posted it. "From $X" and "Up to $X" salaries are kept as they are, not guessed.
- **Company data on every row:** rating, review count, industry, employee count, revenue, website, logo, headquarters and the Indeed company page.
- **Hiring signals:** urgently hiring, hiring in high volume and Easy Apply on each job, plus an optional **one-row-per-company summary** (open roles, titles, locations, pay range). This is useful for recruiting and B2B sales prospecting.
- **Filters combine:** date posted, several job types, remote, hybrid or on-site, Easy Apply only and a minimum yearly salary, all at once.
- **Paste any Indeed link.** A search results page (its keyword, location and filters are used) or individual job links, from any Indeed country site.
- **Fast and light:** about 100 jobs per 2-3 seconds.

### How to use

1. Enter one or more **job titles or keywords** (for example `data analyst`, `registered nurse`).
2. Enter one or more **locations** (for example `Toronto, ON`, `Austin, TX`, `London`, `Remote`), or leave it empty to search the whole country.
3. Pick the **country** (the Indeed site to search).
4. Set **Max jobs per search** (0 = everything) and any filters, then press **Start**.

Every keyword is searched in every location. A job that turns up in several of your searches is only returned (and charged) once.

#### Input example

```json
{
  "searchQueries": ["software engineer", "data engineer"],
  "locations": ["New York, NY", "Remote"],
  "country": "US",
  "maxItemsPerSearch": 500,
  "datePosted": "7d",
  "jobTypes": ["fulltime", "contract"],
  "minSalary": 120000,
  "descriptionFormat": "markdown",
  "includeCompanySummary": true
}
```

#### Main input fields

| Field | What it does |
|---|---|
| `searchQueries` | Job titles or keywords, each searched separately. Leave empty (with a location) to get every job in that place. |
| `locations` | City, state/province, postal code or `Remote`. Empty = whole country. |
| `country` | Indeed site: US, CA, GB, AU, IN, DE, FR, and 55 more. |
| `radius`, `radiusUnit` | Distance around each location (default 25 miles). |
| `maxItemsPerSearch` | Cap per keyword + location (default 100; 0 = all). |
| `maxItems` | Optional cap for the whole run. |
| `datePosted` | Any time, 24 hours, 3, 7, 14 or 30 days. |
| `jobTypes` | Full-time, part-time, contract, temporary, internship, permanent (any of them). |
| `workplaceTypes` | Remote, hybrid, on-site. |
| `easyApplyOnly` | Only jobs you can apply to directly on Indeed. |
| `minSalary` | Minimum yearly pay in the local currency. |
| `sort` | Relevance or newest first. |
| `startUrls` | Indeed search pages, job links or job keys. |
| `descriptionFormat` | Plain text, Markdown, HTML, or leave it out for faster, smaller runs. |
| `includeCompanySummary` | Adds one summary row per employer after the jobs. |
| `splitBeyondCap` | Go past the ~1,000-per-search limit (on by default). |
| `monitorMode` | Return only jobs not delivered by earlier runs of the same search. |

### Output

One row per job. Example (description shortened):

```json
{
  "rowType": "job",
  "jobKey": "6cf23698942d5448",
  "title": "Registered Nurse (RN) | PACU - Contract - Nights",
  "normalizedTitle": "registered nurse - pacu",
  "companyName": "HealthTrust Workforce Solutions",
  "companyRating": 3.6,
  "companyReviewCount": 977,
  "location": "Round Rock, TX 78681",
  "city": "Round Rock",
  "state": "TX",
  "postalCode": "78681",
  "streetAddress": "2400 Round Rock Avenue",
  "countryCode": "US",
  "latitude": 30.510717,
  "longitude": -97.71349,
  "salaryText": "$40.30 – $47.45 per hour",
  "salaryMin": 40.3,
  "salaryMax": 47.45,
  "salaryCurrency": "USD",
  "salaryPeriod": "hour",
  "salarySource": "employer",
  "salaryAnnualMin": 83824,
  "salaryAnnualMax": 98696,
  "jobTypes": ["Contract"],
  "workplace": null,
  "isRemote": false,
  "isEasyApply": true,
  "isUrgentHire": false,
  "isHighVolumeHiring": false,
  "isExpired": false,
  "postedAt": "2026-09-23T21:55:55.646Z",
  "originalPublishedAt": "2026-09-23T05:00:00.000Z",
  "postedDaysAgo": 0,
  "jobUrl": "https://www.indeed.com/viewjob?jk=6cf23698942d5448",
  "applyUrl": "https://tnl2.jometer.com/v2/job?jz=5ymcw...",
  "applyType": "indeed",
  "attributes": ["PACU experience", "Nursing", "Direct deposit", "RN License", "Mid-level", "Acute care facility experience"],
  "occupations": ["Healthcare Occupations", "Registered Nurses"],
  "language": "en",
  "sourceName": "HealthTrust Workforce Solutions",
  "description": "**Entrust Your Career to HealthTrust!** At HealthTrust, we believe that healthcare is ...",
  "company": {
    "key": "4ea1df1175d41167",
    "name": "HealthTrust Workforce Solutions",
    "indeedUrl": "https://www.indeed.com/cmp/Healthtrust-Workforce-Solutions",
    "rating": 3.6,
    "reviewCount": 977,
    "logo": "https://d2q79iu7y748jz.cloudfront.net/s/_squarelogo/256x256/4d9bef465720699b12aabece56e07eb8",
    "website": "http://healthtrustjobs.com",
    "industry": "Health Care",
    "employeeCount": "1,001 to 5,000",
    "revenue": "$25M to $100M (USD)",
    "ceo": "Brendan Courtney",
    "addresses": ["1000 Sawgrass Corporate Parkway, Sunrise, FL 33323 United States"]
  },
  "searchQuery": "registered nurse",
  "searchLocation": "Austin, TX",
  "country": "US",
  "scrapedAt": "2026-09-24T06:38:52.504Z"
}
```

**Field notes**

- `postedAt` is when the job appeared on Indeed, and `originalPublishedAt` is the employer's own publishing date when Indeed has it.
- `jobUrl` is the Indeed job page and `applyUrl` is where the Apply button leads (the employer's site, or Indeed for Easy Apply jobs).
- `attributes` holds everything Indeed tags a job with: skills, licences, benefits, schedules, education.
- `jobTypes` and `workplace` are normalized to English whatever the country site's language.
- `salary*` fields are empty when neither the employer nor Indeed provides pay.

#### Company summary rows (optional)

With **Add a hiring summary per company** switched on, one extra row per employer follows the jobs (`rowType: "company"`). It includes `openJobs` (in your results), `jobTitles`, `locations`, `urgentHireJobs`, `highVolumeJobs`, `easyApplyJobs`, `remoteJobs`, `salaryAnnualMin`/`salaryAnnualMax`, `latestPostedAt`, rating, review count and the full `company` profile. Filter the dataset on `rowType` to separate the two. Company rows count as results.

### Use cases

- **Job boards and aggregators:** fresh listings with salaries and company info, deduplicated.
- **Recruiting and staffing:** find employers hiring urgently or in volume, by city and role.
- **B2B sales prospecting:** companies that are growing a team, with their website, size and industry.
- **Salary benchmarking:** yearly-normalized pay by title, city and country.
- **Labor-market research:** demand for skills, remote share and posting volume over time.
- **Job alerts:** a daily scheduled run with "Only new jobs" switched on.

### Monitoring: only new jobs

Switch on **Only new jobs (monitoring)**, set **Date posted** to *Last 24 hours* or *Last 3 days*, and schedule the run (for example daily). The first run returns everything that matches. Later runs return only jobs not delivered before for that same search, and you are only charged for those. Each distinct search keeps its own memory. Use **Monitoring memory name** to keep separate feeds.

### FAQ

**Do I need an Indeed account, cookies or a login?** No. No login is needed: the scraper reads the same public job listings any visitor sees, and needs nothing from you except a search.

**Which proxy should I use?** Keep the default (Apify Proxy, datacenter). It comes with every Apify plan, including the free one, and Indeed answers it. If datacenter IPs are refused for a while, the run switches to residential proxies when your account has them, and carries on without them when it doesn't. If the proxy you picked isn't available on your account, the run uses datacenter instead and says so in its status message.

**How many jobs can I get?** Indeed returns about 1,000 jobs per search at most, and sometimes 850-1,000 because it collapses near-identical postings. With **Go beyond Indeed's 1,000-result limit** switched on (the default), bigger searches are split automatically. Nationwide searches in the US, Canada, the UK, Australia, India and Germany are split by state or province, and every country is split by posting date. Very broad searches (for example every job in a whole country) can still leave some one-hour slices capped, and the run's status message tells you when that happens.

**Why doesn't every job have a salary?** Many employers don't publish pay. Coverage varies by country and role: in our tests about 80% of Canadian and 70% of UK jobs had pay, but far fewer in India or Germany. With **Minimum yearly salary**, Indeed also counts its own pay estimate, so a few matching jobs show no salary.

**Which countries are supported?** 62 Indeed country sites, including the US, Canada, UK, Ireland, Australia, New Zealand, India, Singapore, UAE, Germany, France, Netherlands, Spain, Italy, Switzerland, Austria, Belgium, the Nordics, Poland, Japan, Korea, Hong Kong, Malaysia, the Philippines, Mexico, Brazil, Argentina, Chile, Colombia, South Africa and more. Job descriptions stay in the language they were posted in.

**The location returned 0 jobs.** Check the spelling. Indeed understands "City, ST" in the US ("Austin, TX"), "City, Province" in Canada ("Toronto, ON"), plain city names elsewhere, state or province names ("Texas", "Ontario") and "Remote".

**Can I get jobs for a list of job links?** Yes. Paste them (or bare 16-character job keys) into **Indeed URLs**.

**Is it fast?** Roughly 100 jobs per 2-3 seconds. Leave the description out for the fastest and smallest runs.

**What happens if a run hits its time limit?** It stops shortly before the timeout (20% of the run time, at most a minute), keeps everything collected so far, and finishes successfully. If the timeout is so short that nothing came back, the status message says so: give the run at least 120 seconds.

**Is it legal to scrape Indeed?** This Actor only collects publicly available data: job listings and the employer profiles Indeed shows to any visitor without an account (title, company, salary, location, description, company rating, size and website). Collecting publicly available data is generally legal, but you're responsible for how you use it. The results are about jobs and companies, not private individuals: no applicant or reviewer data is collected, and recruiter contact fields are not requested. Company profiles can include the CEO's name as Indeed publishes it, and a job description is the employer's own text, which occasionally mentions a recruiter's name or work email. You must follow privacy laws such as GDPR, PIPEDA and CCPA, as well as Indeed's terms. If you're unsure, check with a lawyer. More on this: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?** No. Everything comes from what Indeed shows to any visitor without logging in. It never uses a login, never touches private or restricted accounts, and never reaches password-protected areas.

# Actor input Schema

## `searchQueries` (type: `array`):

Each keyword is searched separately, e.g. "software engineer", "registered nurse", "warehouse". Leave empty and fill Locations to get every job in a place.

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

City, state/province, postal code or "Remote" — e.g. "New York, NY", "Toronto, ON", "Texas", "London". Every keyword is searched in every location. Leave empty to search the whole country.

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

Which Indeed country site to search. Salaries, links and labels follow that country.

## `radius` (type: `integer`):

Distance around each location. 0 = exactly that place.

## `radiusUnit` (type: `string`):

Miles or kilometers for the radius.

## `maxItemsPerSearch` (type: `integer`):

Cap for each keyword + location pair. 0 = everything Indeed has (large searches are split automatically to go past Indeed's ~1,000-result limit).

## `maxItems` (type: `integer`):

Optional cap across the whole run.

## `datePosted` (type: `string`):

Only jobs posted within this period.

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

Pick one or more (a job matching any of them is included).

## `workplaceTypes` (type: `array`):

Remote, hybrid and/or on-site.

## `easyApplyOnly` (type: `boolean`):

Only jobs you can apply to directly on Indeed.

## `minSalary` (type: `integer`):

Only jobs paying at least this much per year, in the country's currency (hourly/monthly pay is converted). Indeed also matches jobs on its own salary estimate, so some results show no salary.

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

Relevance (Indeed's order) or newest jobs first.

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

Paste Indeed search result pages (their keyword, location and filters are used) or job links / job keys to get those exact jobs. Any Indeed country site works.

## `descriptionFormat` (type: `string`):

How to return the job description. Leaving it out makes runs faster and smaller.

## `includeCompanySummary` (type: `boolean`):

After the jobs, adds one row per employer: open roles in your results, job titles, locations, urgent-hire and high-volume flags, pay range, rating, industry, size, website.

## `splitBeyondCap` (type: `boolean`):

Indeed shows at most ~1,000 jobs per search. When a search hits that and you asked for more, it is split by state/province and posting date to collect the rest (duplicates removed).

## `monitorMode` (type: `boolean`):

Remembers the jobs already delivered for this exact search and returns only new ones on later runs. Schedule the run daily with "Date posted: Last 24 hours" for a job alert feed.

## `monitorStoreName` (type: `string`):

Name of the key-value store that remembers delivered jobs. Use different names to keep separate feeds.

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

How many requests run at the same time. The default is fine for almost every run.

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

Datacenter proxy works; residential is switched on automatically if Indeed starts refusing requests.

## `apiKey` (type: `string`):

Leave empty. Only for troubleshooting.

## Actor input object example

```json
{
  "searchQueries": [
    "software engineer"
  ],
  "locations": [
    "New York, NY"
  ],
  "country": "US",
  "radius": 25,
  "radiusUnit": "mi",
  "maxItemsPerSearch": 100,
  "datePosted": "any",
  "easyApplyOnly": false,
  "sort": "relevance",
  "descriptionFormat": "text",
  "includeCompanySummary": false,
  "splitBeyondCap": true,
  "monitorMode": false,
  "monitorStoreName": "indeed-jobs-monitor",
  "maxConcurrency": 10,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All scraped jobs.

## `run` (type: `string`):

Status and statistics for this run.

## `report` (type: `string`):

RUN_REPORT: how the run ended, counts and proxy use.

# 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 = {
    "searchQueries": [
        "software engineer"
    ],
    "locations": [
        "New York, NY"
    ],
    "country": "US",
    "maxItemsPerSearch": 100,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/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 = {
    "searchQueries": ["software engineer"],
    "locations": ["New York, NY"],
    "country": "US",
    "maxItemsPerSearch": 100,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/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 '{
  "searchQueries": [
    "software engineer"
  ],
  "locations": [
    "New York, NY"
  ],
  "country": "US",
  "maxItemsPerSearch": 100,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/indeed-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,yugenox/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/yMVXmhLaim8yUdp0N/builds/MhDOnRJHBYIzFRts6/openapi.json
