---
title: "Indeed Web Scraping: Jobs and Salaries (2026) | Scrape.ly"
description: "Indeed web scraping without code or proxies: titles, salaries, employers and apply links, with a real run, its cost and code for curl, Python and Node."
url: https://scrape.ly/blog/scrape-indeed
markdown: https://scrape.ly/blog/scrape-indeed.md
---

[Tutorials](https://scrape.ly/blog/category/tutorials.md)

# How to Scrape Indeed Job Listings: Salaries, Companies and Apply Links

Search Indeed by job title and city, or paste a company's jobs page, and get each listing as a row with salary, job type, company rating, full description and the employer's apply link. A real run, its cost, and code for curl, Python, Node.js and AI agents.

[Openrole Actor publisher on the Scrape.ly Store](https://scrape.ly/blog/author/openrole.md)

- Published

  Oct 23, 2026

- Reading time

  9 min read

![Pixel-art robot with an orange >\_ on its terminal head takes a job card with a briefcase icon off a cork job board topped with the blue Indeed logo and drops it into a crate](https://scrape.ly/media/scrape-indeed.png?w=1080)

Indeed web scraping turns Indeed's public job search into rows you can sort and filter: one row per job with the title, employer, location, salary, job type, workplace setting, company rating, full description and the employer's own apply link. The quickest way to do it is the Indeed Scraper on Scrape.ly: type a job title and a city, press Start, and export the results for $3.50 per 1,000 listings, with no Indeed account, API key or proxy of your own.

This guide covers the no-code steps, the API (curl, Python, Node.js and AI agents over MCP), what a run costs and what to watch out for. Everything comes from a real run on 23 October 2026: data analyst jobs in New York, with the exact input, output, log and charge.

## What data you can get from Indeed

The [Indeed Scraper](https://scrape.ly/store/openrole/indeed-scraper.md) saves one row per job. These are the fields you'll use most:

| Field                                      | What it holds                                                                     |
| ------------------------------------------ | --------------------------------------------------------------------------------- |
| `positionName`, `id`, `url`                | Job title, Indeed job key and the listing link                                    |
| `company`, `companyIndeedUrl`              | Employer name and its Indeed company page                                         |
| `location`                                 | Location as Indeed shows it, e.g. "Manhattan, NY" or a city with its ZIP code     |
| `salary`                                   | Pay exactly as Indeed prints it: "$69,400 - $107,600 a year"                      |
| `jobType`, `jobSetting`, `experienceLevel` | Full-time or part-time, hybrid or remote, entry/mid/senior level                  |
| `rating`, `reviewsCount`                   | The employer's Indeed rating and review count                                     |
| `externalApplyLink`                        | The employer's own application page (Workday, SmartRecruiters, a careers site…)   |
| `postingDateParsed`, `scrapedAt`           | When the job was posted and when you collected it                                 |
| `description`, `descriptionHTML`           | The full job text, plain and HTML                                                 |
| `companyInfo`                              | Website, description, logo and employee range, when you switch on company details |
| `searchInput`, `urlInput`                  | Which search or URL produced the row                                              |

A field Indeed doesn't show is `null` (or `0` for rating and review count), so you can filter on it safely.

## How to scrape Indeed jobs without code

1. Open the [Actor's page](https://scrape.ly/store/openrole/indeed-scraper.md) in the Scrape.ly Store.
2. Pick a ready-made input. We used [Data analyst jobs in New York, 10 jobs](https://scrape.ly/store/openrole/indeed-scraper/presets/company-details.md). "Try this input" opens it in the console.
3. Change the position, city and country to yours. This is the exact input of our run:

```json
{
  "position": "data analyst",
  "location": "New York",
  "country": "US",
  "maxItemsPerSearch": 10,
  "parseCompanyDetails": true
}
```

4. Click **Start**. Ten jobs take a few seconds.
5. Export the jobs as JSON, CSV or Excel.

The fields that matter most:

- `position` and `location`: the same words you'd type into Indeed's two search boxes. Leave `location` empty to search the whole country.
- `country`: which Indeed site to search (`US`, `GB`, `DE`, `IN` and 60 more).
- `startUrls`: Indeed search URLs with filters already set, single job URLs, or a company's jobs page such as `https://www.indeed.com/cmp/Google/jobs`. The preset [Open jobs at Google, 10 jobs](https://scrape.ly/store/openrole/indeed-scraper/presets/company-jobs-url.md) shows that shape. Each URL runs as its own search next to the position search.
- `maxItemsPerSearch`: the cap for the position search and for each URL separately (default 10).
- `parseCompanyDetails`: adds the employer's website, description, logo and size. It reads the same response as the job, so it adds no extra request.
- `saveOnlyUniqueItems`: on by default, so a job found by two of your searches is saved once.

Scrape.ly Store Indeed Scraper Public Indeed jobs by title and city, search URL or company page: salary, job type, rating, full description and apply link. 60+ country sites. $3.50 per 1,000 listings.

[Try it free](https://scrape.ly/store/openrole/indeed-scraper.md) [Browse the Store](https://scrape.ly/store.md)

## How to scrape Indeed with the API

Create an API token under **Settings → API & Integrations** and export it as `SCRAPELY_TOKEN`.

Our run took 6 seconds, so the synchronous endpoint is the simplest option: one request starts the run, waits for it and returns the jobs. Add `?format=csv` to the URL for a CSV instead of JSON.

```shell
curl -X POST "https://api.scrape.ly/v2/actors/openrole~indeed-scraper/run-sync-get-dataset-items"
  -H "Authorization: Bearer $SCRAPELY_TOKEN"
  -H "Content-Type: application/json"
  -d '{"position": "data analyst", "location": "New York", "country": "US", "maxItemsPerSearch": 10, "parseCompanyDetails": true}'
```

The synchronous call waits up to 45 seconds. For bigger jobs (hundreds of listings, many start URLs), start the run with `/runs` instead and read the dataset when it finishes, as the [Actors API docs](https://scrape.ly/docs/api-actors.md) show.

Python (`pip install scrapely-client-python`). `call()` waits however long the run takes; this example prints the salary next to the employer and its size:

```python
import os
from scrapely_client import ScrapelyClient

client = ScrapelyClient(os.environ["SCRAPELY_TOKEN"], api_url="https://api.scrape.ly")

run = client.actor("openrole/indeed-scraper").call(
    run_input={"position": "data analyst", "location": "New York", "country": "US",
               "maxItemsPerSearch": 10, "parseCompanyDetails": True}
)
print(run.status)  # SUCCEEDED, FAILED, ABORTED or TIMED-OUT
for job in client.dataset(run.default_dataset_id).iterate_items():
    size = ((job.get("companyInfo") or {}).get("companySize") or {}).get("min")
    print(f'{job["salary"] or "no salary shown":34} {job["company"][:32]:32} {size or "?":>6}+ staff  {job["positionName"][:40]}')
```

Node.js (`npm install scrapely-client`):

```javascript
import { ScrapelyClient } from 'scrapely-client';

const client = new ScrapelyClient({ token: process.env.SCRAPELY_TOKEN, baseUrl: 'https://api.scrape.ly' });

const run = await client.actor('openrole/indeed-scraper').call({
  position: 'data analyst',
  location: 'New York',
  country: 'US',
  maxItemsPerSearch: 10,
  parseCompanyDetails: true,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map((j) => [j.positionName, j.company, j.salary, j.externalApplyLink]));
```

For AI agents, add the Scrape.ly MCP server. In Cursor, put this in `~/.cursor/mcp.json`:

```json
{
  "mcpServers": {
    "scrapely": {
      "url": "https://api.scrape.ly/mcp",
      "headers": { "Authorization": "Bearer YOUR_TOKEN" }
    }
  }
}
```

In Claude Code, run `claude mcp add --transport http scrapely https://api.scrape.ly/mcp` and sign in with `/mcp`. Then ask: "Use scrapely to run openrole/indeed-scraper for data analyst jobs in New York, 10 jobs, and give me a table of title, company, salary and apply link." A 10-job run finishes inside the 45 seconds `call-actor` waits; for larger runs the agent polls `get-actor-run` and then reads the rows. The [Indeed API](https://scrape.ly/api/indeed-api.md) page shows the same Actor as an API product.

## A real run: data analyst jobs in New York

We ran the "Data analyst jobs in New York, 10 jobs" preset on 23 October 2026. It returned 10 jobs in 6 seconds and was charged $0.0360. The first five rows:

| Position                                                        | Company                                | Salary                         | Type       | Setting     | Level       | Rating |
| --------------------------------------------------------------- | -------------------------------------- | ------------------------------ | ---------- | ----------- | ----------- | ------ |
| Data Analyst I                                                  | Memorial Sloan Kettering Cancer Center | $69,400 - $107,600 a year      | Part-time  | Hybrid work | Entry level | 4.1    |
| Data Analyst                                                    | NYU Langone Health                     | $70,481.60 - $83,475.00 a year | not stated | Hybrid work | Mid-level   | 4.3    |
| Regulatory Data Analyst                                         | Federal Reserve Bank of New York       | $79,300 - $85,000 a year       | Full-time  | not stated  | Mid-level   | 4.1    |
| Business Intelligence Analyst, Product Data Warehouse           | Google                                 | $116,000 - $166,000 a year     | Full-time  | not stated  | Mid-level   | 4.3    |
| Campus Undergraduate Full-Time Analyst - 2027 Data & Analytics… | American Express                       | $78,000 - $124,750 a year      | Full-time  | Hybrid work | Entry level | 4.1    |

All ten jobs were in New York City, so we left the location column out. Every row is an employer, which is business data, so nothing needed masking. What the full ten show:

- **Pay on every row.** All 10 jobs carried an annual salary range, from a $62,000 floor to a $166,000 ceiling. That's a salary benchmark in one six-second run.
- **Direct apply links.** All 10 had `externalApplyLink` pointing at the employer's own system (Workday, SmartRecruiters, a city jobs portal, a careers site), so you can skip Indeed's redirect.
- **Hybrid is the norm here.** Six of ten were marked "Hybrid work". Eight were full-time, one part-time and one didn't say.
- **Fresh and stale side by side.** Posting dates ran from 10 June to 22 October 2026, with three posted in the last three days. Sort by `postingDateParsed` before you act on a list.
- **Company context included.** With company details on, 9 of 10 rows had the employer's website and 6 were listed at 10,000+ employees. Descriptions ran from about 3,300 to 7,600 characters, ready for keyword or skills analysis.

The log, without the platform's start-up lines:

```plaintext
20261023T03:01:19.484Z [Scrapely] Container started (setup 1.9 s)
20261023T03:01:20.909Z [scrapely.actor] INFO  Searches 1, limit 10 per search.
20261023T03:01:21.002Z [scrapely.proxy_configuration] INFO  Platform proxy access check succeeded.
20261023T03:01:23.430Z [scrapely.actor] INFO  [Status message]: Saved 10 jobs from 1 searches.
20261023T03:01:23.935Z [Scrapely] Container state: status=exited exitCode=0 oomKilled=false
```

The search itself took about two and a half seconds on the default datacenter proxy. You don't configure anything for it.

## What it costs

The Actor charges one event: $0.0035 per job listing saved, which is $3.50 per 1,000. Platform usage (compute, storage and proxy) is billed on top and is small for this Actor.

For our run: 10 jobs × $0.0035 = $0.035 in listing fees. The run was charged $0.0360 in total, because it also used $0.0008 of compute, $0.0001 of storage writes and $0.00005 of datacenter proxy traffic. A 1,000-job pull costs $3.50 in listing fees plus a few cents of usage, and the Free plan's $5 of monthly credit covers it. Set a maximum charge per run on [any plan](https://scrape.ly/pricing.md) and the run stops before it goes over.

## What to watch out for when scraping Indeed

- **One search tops out at about 600 to 750 jobs.** Indeed stops paging there even when it reports more. Split big pulls by city, filter or company URL; duplicates across your searches are removed for you.
- **Salary is text.** `salary` is what Indeed prints, including its own estimates when the employer gave none. Parse the numbers and keep the "a year" or "an hour" unit before you compare.
- **Sort on&#x20;**__`postingDateParsed`__ **.** It holds each job's posting time as an ISO timestamp, ready to sort and filter. To keep only recent jobs, set the date filter on Indeed's search page and paste that URL into `startUrls`: filters in a URL are kept.
- **Big runs take minutes.** Each page of results is a separate request, so 1,000 jobs take about two to two and a half minutes. Use the asynchronous API or a schedule rather than the synchronous call.
- **Blocks and site changes.** The datacenter proxy is the default and worked in our run. If Indeed starts refusing a search, switch `proxyConfiguration` to residential. Indeed changes its site over time, and the publisher maintains the Actor, so you read fields like `salary` instead of fixing CSS selectors.
- **People inside descriptions.** Some job texts name a recruiter or give a contact address. Employers are businesses; individual recruiters are people. Keep only the fields you need.

## Is Indeed web scraping legal?

The Actor reads public job listings that any visitor can open, without logging in, and it never touches applications, resumes or private messages. Job titles, employers and posted pay are factual business information.

Indeed sets its own rules for automated access in its [Terms of Service](https://www.indeed.com/legal) and its robots.txt file, so read both and check how they apply to your project before you start.

Responsible practice keeps the footprint small: collect public listings only, set `maxItemsPerSearch` and a maximum charge per run so each job stays at a modest volume, and use the data for analysis rather than republishing listings. Privacy law applies to any person named in a job ad: under the GDPR and the CCPA a recruiter's name or email is personal data, so keep only the fields you need and store them securely. Our guide on [whether web scraping is legal](https://scrape.ly/blog/is-web-scraping-legal.md) covers the general rules. This is not legal advice; before Indeed data goes into a commercial product, get legal advice for your use case.

## Why Scrape.ly for Indeed

- **Indeed's APIs are for posting, not pulling.** Indeed's [developer docs](https://docs.indeed.com/job-postings) offer the Job Sync API for ATS partners and employers to create and expire jobs, and a Publisher JavaScript Plugin that shows Indeed jobs on a partner's site "with front-end integration only". Credentials come through a Partner Console that Indeed provisions. None of that puts search results in your spreadsheet; the Actor does, in seconds.
- **Rows, not selectors.** A hand-written scraper that parses Indeed's HTML needs its own proxies and a fix every time a class name changes. Here you get `salary`, `jobType` and `externalApplyLink` as fields, plus company size and website from the same response.
- **Clear, small cost.** $3.50 per 1,000 jobs, a run charge you can cap, and $5 of free credit every month.
- **Every job board in one place.** The same publisher, openrole, maintains the [Google Jobs Scraper](https://scrape.ly/store/openrole/google-jobs-scraper.md), LinkedIn Jobs, Glassdoor, ZipRecruiter and dozens of national job boards, all with the same API. Our [job scraping guide](https://scrape.ly/blog/job-scraping.md) shows how to combine them, and [How to scrape LinkedIn jobs](https://scrape.ly/blog/scrape-linkedin-jobs.md) covers the LinkedIn side.

## FAQ

### Does Indeed have an API for job listings?

Not for pulling search results. Indeed's current APIs are partner tools for posting jobs, syncing applications and showing Indeed jobs on a publisher's site through a JavaScript plugin. To get listings as data, use a scraper that reads the public search pages, such as the Indeed Scraper.

### Can I scrape Indeed with Python?

Yes. Install `scrapely-client-python`, call `openrole/indeed-scraper` with a position and location, and iterate over the dataset, as in the example above. You don't need requests, BeautifulSoup or a proxy pool.

### How do I scrape all the jobs from one company on Indeed?

Paste the company's jobs page, for example `https://www.indeed.com/cmp/Google/jobs`, into `startUrls` and raise `maxItemsPerSearch`. Schedule the run daily to watch a competitor's hiring.

### How many jobs can I scrape from one Indeed search?

About 600 to 750, because Indeed stops paging there. Run several searches in one go (different cities, filters or company pages) to collect more; duplicates are skipped.

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

$0.0035 per job, so $3.50 per 1,000, plus a little platform usage. Our 10-job run was charged $0.0360 in total.

Scrape.ly Store Scrape Indeed jobs Run the New York data analyst preset as-is, or type your own job title and city, or paste a company's Indeed jobs page. $3.50 per 1,000 listings.

[Try it free](https://scrape.ly/store/openrole/indeed-scraper.md) [Browse the Store](https://scrape.ly/store.md)

About the author

[Openrole](https://scrape.ly/blog/author/openrole.md) Actor publisher on the Scrape.ly Store

Every open role, wherever it is posted: job boards, company ATS pages and freelance markets in dozens of countries. For recruiters, labour-market analysts and job aggregators. A Scrapely studio.

- [Website](https://scrape.ly/users/openrole.md)

Keep reading

## More in Tutorials

- [![Pixel-art robot with an orange >\_ on its terminal head pulls a chart slip with a rising line out of a monitor showing the Google Trends logo and a climbing line chart, and drops it into a crate](https://scrape.ly/media/scrape-google-trends.png?w=750)](https://scrape.ly/blog/scrape-google-trends.md)
  ### [How to Scrape Google Trends: Interest Over Time, Regions and Related Queries](https://scrape.ly/blog/scrape-google-trends.md)
  [Scrape Google Trends for any search term, country and time range, with no code or one API call, then plot the timeline in Python. A real coffee-vs-tea run with its output, log and exact cost, plus where pytrends and Google's own API stand today.](https://scrape.ly/blog/scrape-google-trends.md)
- [![Pixel-art robot with an orange >\_ on its terminal head pulls a comment bubble out of a monitor showing the YouTube logo above a list of comments and drops it into a crate](https://scrape.ly/media/scrape-youtube-comments.png?w=750)](https://scrape.ly/blog/scrape-youtube-comments.md)
  ### [How to Scrape YouTube Comments Without an API Key or Quota](https://scrape.ly/blog/scrape-youtube-comments.md)
  [Scrape YouTube comments from any public video, Short or live link: text, likes, reply counts, creator hearts and publish time, with no API key or daily quota. A real run on a NASA JPL video, its cost, and code for curl, Python and Node.js.](https://scrape.ly/blog/scrape-youtube-comments.md)
- [![Pixel-art robot with an orange >\_ on its terminal head pulls an item card with a photo and a blue price out of a phone showing the blue Facebook logo above a grid of marketplace items, and drops it into a crate](https://scrape.ly/media/scrape-facebook-marketplace.png?w=750)](https://scrape.ly/blog/scrape-facebook-marketplace.md)
  ### [How to Scrape Facebook Marketplace: Listings, Prices and Locations](https://scrape.ly/blog/scrape-facebook-marketplace.md)
  [Scrape Facebook Marketplace by keyword and city, or from search, category and listing URLs, and get title, price, price cuts, location, delivery options and posting time as rows. No Facebook login. A real run, its cost, and code for curl, Python, Node.js and AI agents.](https://scrape.ly/blog/scrape-facebook-marketplace.md)

## The internet is full of data. Start owning yours.

Scrape.ly gives you the infrastructure, the tooling, and the team to extract, process, and operationalize web data at any scale. Setup takes minutes. The advantage lasts forever.

[Get Started Free](https://my.scrape.ly/register) [Chat with Support](mailto:support@scrape.ly?subject=Question%20about%20Scrape.ly\&body=Hi%2C%20I%20have%20a%20question%20about%20Scrape.ly.)

No credit card. No setup calls.
