# Indeed Jobs Scraper: Descriptions, Salaries, Benefits, No Login (`charitable_trousseau/indeed-jobs-scraper`) Actor

Indeed job listings by keyword, location and country on 12 Indeed country sites, with no login or cookies: title, company, salary, job type, benefits, employer rating, posting date and optional full job descriptions. Goes past the one page Indeed shows visitors and reports each run's coverage.

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

## Pricing

from $2.80 / 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 Jobs Scraper: Descriptions, Salaries, Benefits, No Login

Get Indeed job listings for any keyword and location, or for any filtered Indeed job search, on 12 Indeed country sites. No login, no cookies. Full job descriptions are optional.

Every run reports how many of the jobs Indeed counts for your search it saved, so you can see the coverage you got.

### What you can do with it

- Follow the job market for a title in a city: schedule a run with **Date posted** set to the last day and collect the new jobs.
- Pay and benefits analysis: `salaryMin`, `salaryMax`, `salaryPeriod` and `benefits` per job.
- Skills analysis on full job descriptions (`description`, optional).
- Fill a job board, spreadsheet or alert with jobs from any of 12 Indeed country sites.

### What you get

One record per job, never the same job twice in a search:

- **Job:** `jobId`, `title`, `url`, `location`, `workModel` (Remote, Hybrid work), `jobTypes` (Full-time, Contract...), `snippet` (short excerpt of the description)
- **Company:** `companyName`, `companyRating` (1 to 5), `companyReviewCount`
- **Pay, when Indeed shows it:** `salaryText` (for example `$93,500 - $145,400 a year`), `salaryMin`, `salaryMax`, `salaryPeriod` (year, month, week, day, hour), `salaryCurrency`
- **Benefits:** `benefits` (health insurance, 401(k), paid time off...)
- **Posting:** `postedText` ("2 days ago"), `postedDate`, `easyApply`, `isSponsored`, `isNew`, `urgentlyHiring`
- **Description, if you ask for it:** `description` (full text, plain), `descriptionFetched`
- **Other:** `search` (which keyword or URL produced it), `scrapedAt`

#### Sample output

One record from a run on 2026-10-08, as saved (long text and lists shortened):

```json
{
    "jobId": "360b742521200392",
    "title": "Electrician Trainee",
    "companyName": "Kiewit Craft",
    "companyRating": 3.7,
    "companyReviewCount": 2361,
    "location": "Aurora, CO",
    "workModel": null,
    "jobTypes": [],
    "salaryText": "$24 - $30 an hour",
    "salaryMin": 24,
    "salaryMax": 30,
    "salaryPeriod": "hour",
    "salaryCurrency": "USD",
    "benefits": [
        "Paid training"
    ],
    "postedText": "30+ days ago",
    "postedDate": "2026-07-10",
    "easyApply": false,
    "isSponsored": false,
    "isNew": false,
    "urgentlyHiring": false,
    "snippet": "Develop conduit bending, conduit installation and layout skills. As an Electrician Trainee, you'll complete a paid, two-week training program at a Kiewit…",
    "url": "https://www.indeed.com/viewjob?jk=360b742521200392",
    "description": "Requisition ID: 185387\nPosition Summary\nIf you're ready to work hard, learn a trade and build a long-term career, Kiewit's Electrical Training Program is a great place to start. As an Electrician Trainee, you'll complete a paid, two-week training program at a…",
    "descriptionFetched": true,
    "search": "electrician in Denver, CO",
    "scrapedAt": "2026-10-08T02:33:58.028Z"
}
```

### Input

- **Keywords** — job titles, skills or companies, one per line. Each line is its own search. If you give no keyword, location or search URL (for example an API call with an empty input), the example search `data analyst` in `Austin, TX` runs.
- **Location** — city, state, ZIP or postcode, or `Remote`. Applies to all keywords. Leave empty for the whole country.
- **Country** — United States, United Kingdom, Canada, Australia, Ireland, New Zealand, India, Singapore, South Africa, Germany, France or the Netherlands. Results come only from that country's Indeed site.
- **Date posted, job type, remote or hybrid, distance** — applied by Indeed itself, so every job returned is inside the filter.
- **Indeed job search URLs** — for anything more specific. Set your filters on any Indeed country site and paste the address of the results page.
- **Maximum jobs per keyword or URL** — default 100. You are never charged for more.
- **Maximum pages read per keyword or URL** — default 150. Limits how much work one search may take; see the numbers below.
- **Include full job descriptions** — off by default.
- **Leave out sponsored placements** — on by default, see below.

```json
{
    "keywords": ["data analyst", "registered nurse"],
    "location": "Austin, TX",
    "datePosted": "7",
    "maxJobsPerSearch": 500,
    "includeDescriptions": true
}
```

### FAQ

#### Is there an Indeed jobs API that works without logging in?

Yes, in the sense that you can call it like one. Start a run through the Apify API or one of Apify's clients with the input described here, then read the results as JSON, CSV or Excel. It uses no login and no cookies.

#### How many Indeed jobs can I get for one search?

Most of a small or medium search and a good part of a large one, not every job. In our October 2026 measurements, searches with a place gave 78% to 95% of Indeed's count up to about 3,000 jobs and a third of it at 11,000; remote searches gave about a fifth. The table under "How many jobs you can get" has the runs behind these numbers, and every run reports its own coverage.

#### Can it get full Indeed job descriptions?

Yes, with **Include full job descriptions** on. In tests 1,492 of the 1,507 descriptions asked for were fetched (99%). A job whose description cannot be fetched is still returned, with `descriptionFetched: false`.

#### Can I run an Indeed scraper from n8n, Make or a schedule?

Yes. Like any Apify actor it can be started on a schedule in Apify, from Apify's n8n and Make integrations, or over the Apify API, and the results can be read as JSON, CSV or Excel.

#### Which countries does it cover?

The United States, United Kingdom, Canada, Australia, Ireland, New Zealand, India, Singapore, South Africa, Germany, France and the Netherlands. Results come only from the chosen country's Indeed site.

#### How much does it cost?

$4.00 per 1,000 jobs on Apify's Free plan, plus $1.00 per 1,000 descriptions when you ask for them and a start fee of $0.00005 per run. Paid Apify plans pay less: Bronze 10%, Silver 20% and Gold 30% less. Runs that fail or return nothing cost nothing.

### How many jobs you can get: read this first

Indeed shows visitors who are not signed in **only the first page** of a search: 15 matching jobs plus up to 30 sponsored ones. Page 2 leads to a sign-in screen. This scraper does not log in, so it cannot page through a search.

Instead it divides your search with Indeed's own filters (job attributes, job type, pay, education, date posted, city, postcode, employer, excluded words), reads the first page of each part, divides again the parts that are still too big, and merges everything without duplicates. Each part is a narrower version of your search, so every job returned still matches your keyword, location, country and filters. Remote and date filters are also checked on each job.

This reaches most of a small or medium search and a good part of a large one, **not every job**. Measured in October 2026, with the job maximum out of the way:

| Search | Indeed's count | After Indeed merges repeats | Jobs saved | Share of count | Share after merging | Pages read | Run time |
|---|---|---|---|---|---|---|---|
| actuary, Columbus, OH | 19 | 18 | 18 | 95% | 100% | 7 | 1 to 3 min |
| data analyst, Austin, TX | 539 | 504 | 421 | 78% | 84% | 184 | 5 min |
| registered nurse, Chicago, IL | 2,850 | 2,262 | 2,230 | 78% | 99% | 600 (the limit set) | 10 min |
| python developer, whole US | 11,182 | 4,299 | 3,677 | 33% | 86% | 600 (the limit set) | 13 min |
| software engineer, London (UK site) | 1,222 | 410 | 433 | 35% | over 100% | 96 | 4 min |
| customer service, Remote | 4,122 | 2,765 | 867 | 21% | 31% | 552 | 13 min |

These six runs used a page maximum of 600. With the default of 150 pages the Chicago search gave 1,084 jobs in under four minutes. Run times are from these runs; small searches now finish in about a minute.

In short: **searches with a place typically gave 78% to 95% of Indeed's count up to about 3,000 jobs, and a third of it at 11,000. Remote searches are the weak case, at about a fifth**, because Indeed offers few filters to divide them with and a remote job has no city to search by.

How to read this:

- Indeed gives two counts. The first is the one behind the number on its results page. The second is what remains after Indeed merges repeated postings, which is what paging through the search would reach. Coverage against the second is the fairer measure; both are shown.
- Indeed's own count for the same search changes from one request to the next (we saw 2,850 and 4,250 for one search within two hours), so percentages are approximate.
- The London run saved more jobs than Indeed's merged count: narrower searches also surface postings Indeed would fold into another one.
- The scraper stops a search when further pages stop bringing new jobs (fewer than one new job per two pages over 40 pages), when it reaches your job maximum, or when it reaches the page maximum. The run's status message and log say which, with the count saved against Indeed's count.
- For the widest coverage of a big search, split it yourself as well: one run per city, or per job type, each with its own maximum.

Other limits:

- Indeed's remote filter combined with a city often returns no result list at all on Indeed itself (0 of 14 in our test). To search remote jobs, put `Remote` in Location.
- Pay is missing where Indeed shows none.
- Counts and coverage are per search; the same job can appear under two keywords.

### Sponsored jobs

Indeed shows paid placements in two ways.

- **In separate blocks around the result list**, up to 30 per page. Its ad system picks them, they are not part of the count Indeed reports, and they often match the search only loosely (a search for actuaries with 19 results came with 59 different placements, among them payroll and cybersecurity analysts). By default these are left out, so your results and your bill consist of jobs that match your search. Turn **Leave out sponsored placements** off to get them too: they are added at the end of each search, only if there is room under your maximum.
- **Inside the result list**, in place of an unpaid result. These match the search and are always kept. On some country sites (Canada in our tests) the whole first page consists of them.

Both kinds are marked `isSponsored: true`.

### Job descriptions

With **Include full job descriptions** on, each job gets its full description as plain text in `description`. In tests 1,492 of the 1,507 descriptions asked for were fetched (99%); the 15 missing ones were a single refused request in one run. A job whose description cannot be fetched is still returned, with `description: null` and `descriptionFetched: false`.

### Pricing

You pay per job saved, and per description when you ask for descriptions. Duplicates are never saved, so never charged. Runs that fail or return nothing cost nothing.

### Reliability

Indeed blocks automated traffic, so the scraper uses a real browser and residential proxies, and replaces its browser session with a fresh one on a new address every 26 pages, before Indeed's limit of about 30 searches per visitor. In our last test batch of 16 runs, 21% of first page loads and 4% of the further requests were refused and repeated from a new address; no search was lost to blocking. If a search cannot be opened at all, the run says so in its status message and still returns the jobs of the other searches.

### Notes

This scraper collects job listing data only. It does not collect recruiter or other personal contact details, and it does not log in.

Each run stores a `COVERAGE` record in its key-value store: per search, Indeed's two counts, jobs saved, pages read, why it stopped, and how many new jobs each kind of filter brought.

### Related scrapers

- [Coles Australia Grocery Price Scraper](https://apify.com/charitable_trousseau/coles-au-product-scraper): products, prices and specials from coles.com.au
- [AliExpress Product Search Scraper](https://apify.com/charitable_trousseau/aliexpress-search-scraper): search results by keyword with prices, discounts and units sold
- [eBay Active Listings & Auctions Search Scraper](https://apify.com/charitable_trousseau/ebay-search-scraper): active listings and auctions on five eBay sites
- [Apple App Store Scraper](https://apify.com/charitable_trousseau/app-store-scraper): iOS top charts, search results and app details
- [Zillow ZIP Code Search Scraper](https://apify.com/charitable_trousseau/zillow-search-scraper): homes for sale, rentals and recently sold homes
- [Tripadvisor Places Scraper](https://apify.com/charitable_trousseau/tripadvisor-listings-scraper): hotels, restaurants and things to do for any place
- [Google Maps Places Scraper](https://apify.com/charitable_trousseau/google-maps-places-scraper): business listings across a whole city, postcode or radius
- [Glassdoor Jobs Scraper](https://apify.com/charitable_trousseau/glassdoor-jobs-scraper): job listings with salary ranges and employer ratings
- [LinkedIn Jobs Scraper](https://apify.com/charitable_trousseau/linkedin-jobs-scraper): job postings past LinkedIn's 1,000-per-search limit, no login
- [Google Trends Scraper](https://apify.com/charitable_trousseau/google-trends-scraper): interest over time, interest by region, rising queries and trending searches

# Actor input Schema

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

Job titles, skills or companies, one per line. Each line is a separate search. If the keywords, location and search URLs are all empty, the example search data analyst in Austin, TX runs.

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

City, state, ZIP or postcode, or "Remote", e.g. Austin, TX. Applies to the keywords above. Leave empty to search the whole country.

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

Indeed country site to search. Results come only from that site.

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

Only jobs posted within this time. Applied by Indeed itself, so every job returned is inside the window.

## `jobType` (type: `string`):

Only jobs of this type.

## `workModel` (type: `string`):

Only jobs Indeed marks as remote, or as hybrid. Note: on Indeed itself the remote filter combined with a city often returns few or no jobs; to search remote jobs, put "Remote" in Location instead.

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

In miles (kilometres on sites that use them). 0 means the exact location only. Leave empty for Indeed's default of 25. Needs a location.

## `searchUrls` (type: `array`):

For anything more specific: set your filters on any Indeed country site and paste the address of the results page. The filters above do not apply to these.

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

The scraper stops a search when it has saved this many jobs. You are never charged for more.

## `maxPagesPerSearch` (type: `integer`):

Upper limit on how much work one search may take. Indeed shows 15 matching jobs per page, and pages overlap more as a search nears its end. In tests 150 pages gave about 1,100 jobs for a large city search; small searches need far fewer pages. Raise it for large searches; see the README for measured numbers.

## `expandWithFilters` (type: `boolean`):

Indeed shows visitors who are not signed in only the first page of a search (15 matching jobs). With this on, the scraper divides your search with Indeed's own filters (job type, pay, date posted, city, employer and others), reads each part and merges the results without duplicates. Every job still matches your search. Turn off to get only the first page.

## `includeDescriptions` (type: `boolean`):

Adds the full description of each job as plain text in `description`. Jobs whose description cannot be fetched are still returned, with `descriptionFetched: false`.

## `excludeSponsored` (type: `boolean`):

Indeed adds up to 30 paid placements in separate blocks on each page. Its ad system picks them, they are not part of the job count it reports, and they often match the search only loosely. On by default. When turned off, they are added at the end of each search, only if there is room under your maximum. Paid results that Indeed puts inside the result list itself match the search and are always kept. Both kinds are marked `isSponsored: true`.

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

US residential proxies are used by default and are needed for reliable runs.

## Actor input object example

```json
{
  "keywords": [
    "data analyst"
  ],
  "location": "Austin, TX",
  "country": "us",
  "datePosted": "",
  "jobType": "",
  "workModel": "",
  "maxJobsPerSearch": 100,
  "maxPagesPerSearch": 150,
  "expandWithFilters": true,
  "includeDescriptions": false,
  "excludeSponsored": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

All jobs saved by the run.

# 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": [
        "data analyst"
    ],
    "location": "Austin, TX",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("charitable_trousseau/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": ["data analyst"],
    "location": "Austin, TX",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("charitable_trousseau/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": [
    "data analyst"
  ],
  "location": "Austin, TX",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call charitable_trousseau/indeed-jobs-scraper --silent --output-dataset

```

## MCP server setup

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