# Indeed Scraper: Jobs, Pay and Company Data

> Indeed scraper: turn a job title and location, an Indeed search URL or job IDs into a table with pay, skills and company data in 62 countries. No login.

URL: https://cliqtomedia.com/actors/indeed-scraper/

Category: Jobs & hiring · Status: coming soon · Apify profile: https://apify.com/cliqtomedia?fpr=cliqto

Search Indeed by keyword and location, by search link or by job ID. You get one row per job with title, company, pay, job type, skills and link. No login, API key or cookies.

## How to use it: 3 steps

1. **Follow us on Apify.** The tool is built and waits in the queue for the Apify Store. Apify is the cloud platform where our tools run.
2. **Paste your input and press Start.** No code needed: you fill in a form (the input). It already has a working example. For example: `[]` in Skills to match. Each start is one run.
3. **Download the results.** When the run ends, the results are in a table (the dataset). Open Output, press Export and pick Excel or CSV. JSON and the API are there too.

## What it does

Indeed Jobs Scraper turns a job title and location, an Indeed search URL or a list of job IDs into a table of Indeed jobs with pay, skills and company data, in 62 countries. You need no login, API key or cookies.

- Search jobs: by keyword and location, by Indeed search URLs, or by a list of searches.
- Look up job IDs: read up to 100 known jobs.
- Monitor changes: compare each run with the last one and mark jobs as new, still open or closed.

### Good for

- You want pay data by job title and city, with hourly pay also shown as a yearly number.
- You want a list of companies that are hiring, with their website, size and rating.
- You want to see new and closed jobs for one search every day.
- You want to rank jobs by your own skill list.

## Price

Prices will be shown after release.

## Questions

### Do I need an Indeed account, API key or cookies?

No. The tool reads public job data only. You need an Apify account.

### Are the salaries exact?

The pay comes from Indeed. Check salaryEstimated to see if Indeed marks it as an estimate. Jobs without pay have null.

### Do I get every job on Indeed?

No. You get what Indeed returns for your search, up to your limit. Treat it as a sample of the market.

### Why does a small run cost more per job than a large one?

Each source page has its own charge. A page holds many jobs, so a run with 20 jobs pays for a full page, and a run with 1,000 jobs shares its pages across more rows.

### How fresh is the data?

Each row is read at the time of the run, shown in `fetchedAt`. To follow changes, use monitor mode on a schedule.

## Data fields

- `searchQuery` (string): Search terms for this row; null for direct lookups.
- `searchLocation` (string): Location used in this search; null for direct lookups.
- `jobKey` (string): Indeed job identifier.
- `title` (string): Job title.
- `company` (string): Employer name.
- `location` (string): City, region and country.
- `city` (string): Job city.
- `region` (string): State or region code.
- `country` (string): Two-letter country code.
- `postalCode` (string): Postal code.
- `latitude` (number): Job latitude.
- `longitude` (number): Job longitude.
- `salary` (string): Pay range in the original currency and period.
- `salaryMin` (number): Minimum pay in the original period.
- `salaryMax` (number): Maximum pay in the original period.
- `salaryCurrency` (string): Original salary currency code.
- `salaryPeriod` (string): Pay period: hour, day, week, month or year.
- `salaryEstimated` (boolean): True when Indeed labels this salary as estimated.
- `salaryYearlyMin` (number): Annualized minimum pay. Hourly pay assumes 2,080 hours; daily pay assumes 260 days.
- `salaryYearlyMax` (number): Annualized maximum pay using the same assumptions.
- `jobType` (string): Employment type labels.
- `employmentType` (array/string): Employment types; text in flat output.
- `remote` (boolean): True for remote or hybrid; null when unknown.
- `remoteType` (string): remote, hybrid, onsite, or null when not labeled.
- `experienceLevel` (string): Indeed experience level from explicit job attributes; null when not returned.
- `seniority` (string): Seniority inferred from title; null when unclear.
- `isEasyApply` (boolean): True when Indeed Apply scopes include DESKTOP; null when scopes are unavailable.
- `isUrgentHire` (boolean): Indeed urgent hiring flag.
- `isHighVolumeHiring` (boolean): Indeed high-volume hiring flag.
- `isPlacement` (boolean): Indeed placement or recruitment agency flag.
- `postedAt` (string): Posting date on Indeed in UTC.
- `publishedAt` (string): Original publication date in UTC.
- `expiresAt` (string): Expiry date in UTC.
- `expired` (boolean): Explicit expiry status from Indeed.
- `isRepost` (boolean): Indeed repost flag.
- `isLatestPost` (boolean): Indeed latest post flag.
- `language` (string): Job language code.
- `reference` (string): Employer reference.
- `description` (string): Job description as plain text.
- `companyId` (string): Indeed employer identifier.

## Input settings

- `mode` (string): Search finds jobs by filters, lookup reads known job IDs, monitor compares jobs across runs and needs a state name. Default: search.
- `country` (string): Indeed country site. Search URLs and entries in Multiple searches can set their own country. Default: United States.
- `query` (string): Job title, company, skill or other search terms, up to 300 characters. Example: data analyst. Leave empty to search all jobs in the location.
- `location` (string): City, region or postal code, up to 200 characters. Example: New York. Leave empty to search the whole selected country.
- `maxItems` (integer): Upper limit of saved job rows across this run, from 1 to 20,000. Default: 20. Extra source pages can be needed when filters remove jobs. Set a longer run timeout for large runs.
- `radius` (integer): Distance around the location, from 0 to 200. Default: 25. Indeed can return nearby jobs when few jobs match.
- `radiusUnit` (string): Unit for the search radius. Default: miles.
- `postedWithinDays` (integer): Only jobs posted within this many days, from 0 to 365. Example: 7. Default: 0, which means any date.
- `jobType` (string): Keep one employment type. Default: all types.
- `remote` (string): Filter by Indeed remote or hybrid labels. Jobs without a label can be missing from a filtered search. Default: all.
- `sort` (string): Sort by relevance or by posting date. Default: relevance.
- `easyApply` (boolean): Only jobs labeled by Indeed as supporting Indeed Apply. Default: off.
- `salaryMin` (number): Keep jobs whose maximum annual pay is at least this amount. Example: 80000. Uses each job’s original currency; does not convert currencies. Jobs without comparable pay are excluded.
- `salaryMax` (number): Keep jobs whose minimum annual pay is no more than this amount. Example: 150000. Uses each job’s original currency.
- `includeNoSalaryJob` (boolean): Keep jobs when Indeed has no salary information. Default: on.
- `experienceLevel` (string): Keep one level. Uses the Indeed experience label, or the job title when Indeed returns no label. Jobs with an unknown level do not match. Default: all levels.
- `onlyExternalJobs` (boolean): Save only jobs with an external application URL returned by Indeed. Links are not followed. Default: off.
- `uniqueCompanies` (boolean): Save at most one matching job per company in this run. Default: off.
- `resumeKeywords` (array): Up to 50 terms of up to 80 characters, matched in public job descriptions. Example: SQL. No resume upload or personal details are needed.
- `strictMatch` (boolean): Save jobs only when all skill terms match the description. Default: off.
- `deduplicate` (boolean): Remove exact repeated job IDs and jobs with the same company, title and description prefix. When off, reposts have duplicateOf; repeated IDs are always removed. Default: on.
- `maxItemsPerSearch` (integer): Upper limit of saved job rows for each search, from 1 to 20,000. Default: 20,000.
- `startUrls` (array): Up to 20 HTTPS Indeed search URLs. Example: https://www.indeed.com/jobs?q=nurse&l=Boston. They replace Multiple searches and the main search terms. Supported filters: q, l, radius, fromage, jt, sort, start, remotejob and sc with attr or jt. Without q or l, the search has no keyword or city filter. Any other filter stops the run.
- `searches` (array): Up to 20 searches, each with country, query and optional location. Example: [{"country":"US","query":"nurse","location":"Boston"}]. Used when search URLs are empty.
- `deepSearch` (boolean): Add built-in major-city searches when location is empty. New York, London and Berlin also support metro-area searches. Up to 100 searches; results overlap and duplicates are removed. This is a city sample, not complete country coverage. Default: off.

## Step by step on Apify

1. Open the Input tab and keep or change Country (box 1 in the picture).
2. Keep or change Job search and Location (box 2). The form starts with `data analyst` and `New York`.
3. Keep Maximum jobs at 20 for the first run (box 3).
4. Click Start.
5. Open the Output tab and check the Jobs view. Box 5 shows the title, company, location and salary columns. Yearly pay, skills, skill matches and monitor status are in the All job fields view.

## Use cases

| Task | Input | You get | Key fields | Next step |
|---|---|---|---|---|
| Compare pay for one job in many cities | `searches` | Job rows and search summary | `salaryYearlyMin`, `salaryYearlyMax`, `salaryCurrency`, `city` | Export to CSV or Excel |
| Build a list of hiring companies | `query`, `location`, `uniqueCompanies` | Job rows and employer summary | `company`, `companyWebsite`, `companyEmployees`, `companyIndustry` | Export to CSV, or send to a CRM with the API |
| Watch one search for new and closed jobs | `mode`: `monitor`, `stateName` | Job rows with a status | `changeStatus`, `jobKey`, `title`, `url` | Summary in Slack or Notion |
| Find jobs that match your skills | `resumeKeywords`, `strictMatch` | Job rows with a match score | `matchedKeywords`, `unmatchedKeywords`, `keywordMatchPercent` | Sort in a spreadsheet |
| Refresh jobs you already know | `mode`: `lookup`, `jobKeys` | Job rows | `jobKey`, `expired`, `salary`, `postedAt` | API, or an AI agent with MCP |

## Tips

- One search usually ends near 250 jobs. Use searches or deepSearch to get more.
- Use monitor mode on a schedule. It marks jobs as new, still open or closed.
- For 1,000 jobs, set the run timeout to 10 minutes.

## Limits



- Rows: `maxItems` is an upper limit of 20,000 per run, not a promised count. Indeed can return fewer jobs for a search. One search usually ends near 250 jobs, because Indeed returns no more: a nationwide search for nurses gave 245. Use `searches` or `deepSearch` for more. The largest run we measured saved 19,000 rows with `deduplicate` off. It found 2,138 repost duplicates, so with the default on, the same run saves fewer rows or reads more pages.
- Time: the default run timeout of 300 seconds fits a normal search of up to about 250 jobs. A run with 1,000 jobs took 175 to 266 seconds, which is close to that limit, so set 10 minutes for it. The largest measured run took 35 minutes, so set 1 hour for runs of that size. A filtered run with slow source pages took 100 seconds for 30 jobs.
- Requests: each request waits up to 45 seconds and is tried up to 3 times. If a page still fails, the run ends as `FAILED` and keeps the rows it saved. Any searches left are listed in `unprocessedSearches`. One run reads up to 500 requests or 300 MB, and one response can be up to 8 MB.
- Deep search: `deepSearch` covers up to 100 city searches. A `complete` status means these searches finished, not that every job in the country was found.
- Search URLs: URLs with other filters, such as company, level, pay or language filters from the Indeed page, stop the run with `INVALID_INPUT`. Use the input filters instead.
- Monitor: a job is closed only when Indeed marks it as expired. A job that Indeed no longer returns stays open as unresolved. Each run checks up to 100 older job IDs. Only saved rows enter the history, which keeps up to 10,000 jobs. Run one monitor per `stateName` at a time.
- Pay: no currency conversion. Yearly pay uses hourly × 2080 and daily × 260.
- Skills and level: `skills` uses a fixed skill list, and `seniority` is a simple check of the title.

## Sample result

```json
{
  "jobKey": "dd40c18d153680c6",
  "title": "Business Data Analyst",
  "company": "Cathay Holdings",
  "location": "Brooklyn, NY, US",
  "salary": "144414 USD/year",
  "salaryYearlyMin": 144414,
  "salaryYearlyMax": null,
  "salaryCurrency": "USD",
  "jobType": "fulltime",
  "remoteType": "hybrid",
  "experienceLevel": "mid",
  "requirements": "Python (required); SQL (required); AI models (required); Master's degree (required); Jira (required)",
  "skills": "Python; SQL; Machine Learning",
  "postedAt": "2026-10-16T18:45:11.857Z",
  "companyRating": 4,
  "companyReviewCount": 1,
  "companyWebsite": null,
  "url": "https://www.indeed.com/viewjob?jk=dd40c18d153680c6",
  "applyUrl": null,
  "changeStatus": null
}
```

## Similar tools

- [Google Jobs Scraper - Salary, Apply Links & Dates, No Login](https://cliqtomedia.com/actors/google-jobs-scraper/)
- [Glassdoor Jobs & Reviews Scraper](https://cliqtomedia.com/actors/glassdoor-scraper/)
- [Remote Jobs Aggregator - RemoteOK, WWR & Himalayas, No login](https://cliqtomedia.com/actors/remote-jobs-aggregator/)
- [Wellfound Jobs Scraper: Startup Jobs to CSV & JSON](https://cliqtomedia.com/actors/wellfound-jobs-scraper/)
- [Ashby Jobs Scraper: Public Job Board Export](https://cliqtomedia.com/actors/ashby-jobs-scraper/)
- [Lever Jobs Scraper: jobs.lever.co Postings Export](https://cliqtomedia.com/actors/lever-jobs-scraper/)
