# Glassdoor Jobs Scraper: Salaries, Ratings & Job Listings (`themineworks/glassdoor-jobs-salary-scraper`) Actor

Scrape Glassdoor job listings by keyword and location: title, company, company rating, salary range with median, location, posted date, Easy Apply, skills and benefits. US, UK, Canada, Australia, Germany, France and India. Filters for date, remote, Easy Apply and rating. No login. Pay per job.

- **URL**: https://apify.com/themineworks/glassdoor-jobs-salary-scraper.md
- **Developed by:** [The Mine Works](https://apify.com/themineworks) (community)
- **Categories:** Jobs, Lead generation
- **Stats:** 2 total users, 1 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.
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

## Glassdoor Jobs Scraper: Salaries, Ratings & Job Listings

### What does Glassdoor Jobs Scraper do?

Give it job titles or keywords and a location. Get back every matching Glassdoor job as a clean row: title, company, the company's Glassdoor star rating, the pay range with its median, pay period and currency, whether the employer posted the pay or Glassdoor estimated it, location, days since posting, Easy Apply, job type, a short description extract, and the skills, benefits, schedule and education tags Glassdoor pulls out of each listing.

It searches seven Glassdoor country sites (United States, United Kingdom, Canada, Australia, Germany, France and India), matches your location against Glassdoor's own city, state and country list, and follows the result pages the way the site's own "load more" button does, up to 30 pages per search.

✅ Salary range and median on every row that has one | ✅ Company rating and logo | ✅ 7 countries | ✅ Filters for date, remote, Easy Apply and rating | ✅ No login or cookies | ✅ Pay only for jobs delivered | ✅ MCP-ready for AI agents

### Who is it for?

Recruiters and staffing agencies building lead lists of companies that are hiring right now, and what they pay. HR and compensation teams benchmarking salaries for a role in a city. Job seekers and career coaches tracking new openings with pay and company ratings side by side. Analysts and researchers who need flat, dated job data in a spreadsheet or pipeline.

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

You pay per job delivered to your dataset, plus $0.005 per run at the default memory.

| Apify plan | Per job |
| --- | --- |
| Free | $0.0015 |
| Starter (Bronze) | $0.00135 |
| Scale (Silver) | $0.0012 |
| Business (Gold) and above | $0.001 |

The filters, the location lookup, salary data, company ratings and job attributes are all included. Compute and proxies are included.

| Job | Free | Starter | Scale | Business |
| --- | --- | --- | --- | --- |
| 1 keyword in 1 city, 30 jobs | $0.050 | $0.046 | $0.041 | $0.035 |
| 10 keywords, 100 jobs each (1,000 jobs) | $1.51 | $1.36 | $1.21 | $1.01 |
| 50 keywords, 300 jobs each (15,000 jobs) | $22.51 | $20.26 | $18.01 | $15.01 |

Each row above is one run and includes the $0.005 run fee.

**Never charged:** location lookups, pages Glassdoor refused or that failed, searches with no results, locations Glassdoor does not know, the same job found again by a second keyword, jobs your rating or Easy Apply filter removed, expired listings, and the run summary. The Pricing tab always shows the rate for your own plan; if this table and the Pricing tab ever disagree, the Pricing tab is right.

### How does it get Glassdoor jobs without logging in?

It reads what Glassdoor shows a visitor who is not logged in, in three steps.

First, your location. Glassdoor ignores a typed place name in a search link and quietly searches the whole country instead, so the actor looks your location up in Glassdoor's own location list for the site you chose and uses the id it gets back. "Austin, TX" becomes Austin, Texas; "London" on glassdoor.co.uk becomes the London region. The lookup is done once per location per run and is free.

Second, the first page of results, 30 jobs, straight from the search page Glassdoor builds for that keyword and place. Your filters (posted within N days, remote only, Easy Apply only, minimum rating) are Glassdoor's own filters, applied on its side.

Third, further pages, 30 jobs each, fetched the same way the site's "load more" button fetches them, up to 3 at a time. The actor stops when it has the number of jobs you asked for, when Glassdoor offers no further page, when a page brings nothing new, or at page 30, which is as far as Glassdoor goes.

Glassdoor sits behind Cloudflare, so every request goes through Apify's unblocking proxy, and a refused request is retried on a fresh connection up to 3 times. Refused pages are listed in the run summary and never charged.

### What input does it take?

```json
{
  "keywords": ["data analyst", "business analyst"],
  "location": "Austin, TX",
  "site": "glassdoor.com",
  "maxResultsPerSearch": 100,
  "postedWithinDays": 7,
  "remoteOnly": false,
  "easyApplyOnly": false,
  "minCompanyRating": 3
}
```

| Input | Default | What it does |
| --- | --- | --- |
| `keywords` | none | Job titles or keywords, one per line. Each is its own search. Up to 50 per run. A single `keyword` string is accepted too |
| `location` | empty | A city, state or country, for example `Austin, TX`, `California` or `London`. Empty searches the whole country of the site |
| `site` | `glassdoor.com` | `glassdoor.com` (US), `glassdoor.co.uk`, `glassdoor.ca`, `glassdoor.com.au`, `glassdoor.de`, `glassdoor.fr` or `glassdoor.co.in` |
| `maxResultsPerSearch` | 30 | Most jobs per keyword, 1 to 1,000. Glassdoor stops at 30 pages (900 jobs) per search |
| `postedWithinDays` | empty | Only jobs posted in the last N days, 1 to 30 |
| `remoteOnly` | false | Only jobs marked remote or work from home |
| `easyApplyOnly` | false | Only jobs you can apply to on Glassdoor directly |
| `minCompanyRating` | empty | Only companies rated at least 1, 2, 3 or 4 stars. Jobs at companies with no rating are left out |
| `startUrls` | empty | Glassdoor search result URLs instead of keywords. Filters in the URL are kept |

### What data do you get back?

One row per job. This is a real row from a test run on 27 Sep 2026, with `job_attributes` shortened:

```json
{
  "listing_id": "1010270320133",
  "url": "https://www.glassdoor.com/job-listing/j?jl=1010270320133",
  "title": "Analyst, Data Maintenance",
  "normalized_title": "data analyst",
  "occupation": "data analyst",
  "employer_name": "Visa U.S.A. Inc.",
  "employer_profile_name": "Visa Inc.",
  "employer_id": 3035,
  "company_rating": 3.7,
  "employer_logo_url": "https://media.glassdoor.com/sql/3035/visa-inc-squareLogo-1627484054817.png",
  "location": "Austin, TX",
  "location_type": "city",
  "country_id": 1,
  "remote": false,
  "salary_min": 89200,
  "salary_median": 113900,
  "salary_max": 138600,
  "salary_currency": "USD",
  "salary_period": "ANNUAL",
  "salary_source": "EMPLOYER_PROVIDED",
  "age_in_days": 5,
  "posted_date_estimate": "2026-09-22",
  "easy_apply": true,
  "sponsored": false,
  "job_types": ["Full-time"],
  "description_snippet": "The position will require the incumbent to sit and stand at a desk, communicate in person and by telephone, frequently operate standard office equipment, such…",
  "job_attributes": ["Project reporting", "Data integrity assurance", "Internal controls", "Oracle", "SAP Ariba", "Health insurance", "401(k)", "Paid time off", "Hybrid work", "Bachelor's degree"],
  "search_keyword": "data analyst",
  "search_location": "Austin, TX",
  "site": "glassdoor.com",
  "scraped_at": "2026-09-27T15:22:31.485Z"
}
```

| Field | Description |
| --- | --- |
| `listing_id`, `url` | Glassdoor's job id and a link to the job |
| `title`, `normalized_title`, `occupation` | The title as posted, Glassdoor's standard title, and the occupation it files the job under |
| `employer_name`, `employer_profile_name`, `employer_id` | The company named on the job, the Glassdoor company profile it is linked to (when the name differs) and that profile's id |
| `company_rating`, `employer_logo_url` | The company's overall Glassdoor rating (1 to 5) and logo |
| `location`, `location_type`, `country_id`, `remote` | Where the job is, whether that is a city, state or country, Glassdoor's country id, and a remote flag |
| `salary_min`, `salary_median`, `salary_max` | The pay range Glassdoor shows: low end (10th percentile), median, high end (90th percentile) |
| `salary_currency`, `salary_period`, `salary_source` | Currency, `ANNUAL`, `HOURLY`, `MONTHLY` and so on, and `EMPLOYER_PROVIDED` or `ESTIMATED` |
| `age_in_days`, `posted_date_estimate` | Days since posting, and the posting date worked out from it |
| `easy_apply`, `sponsored`, `job_types` | Easy Apply, paid listing, and job types such as Full-time or Contract |
| `description_snippet` | The short description extract Glassdoor shows in search results |
| `job_attributes` | Skills, tools, benefits, schedule, education and seniority tags Glassdoor extracted from the listing |
| `search_keyword`, `search_location`, `site`, `scraped_at` | Which search found the row, and when |

In the test runs of 27 Sep 2026, 85% and 97% of rows in the two city searches had a salary range, 95% and 93% had a company rating, and every row had job attributes and a description extract.

Empty fields are dropped rather than sent as `null`. Each run also writes a summary to the key-value store record `OUTPUT`: a status for every search (`ok`, `no_results`, `location_not_found`, `blocked`, `skipped`), the location Glassdoor matched, pages read and failed, duplicates skipped, and what was charged. A final `_type: "info"` row in the dataset is informational and never billed.

### What are the limitations?

**900 jobs per search.** Glassdoor's own pages stop at page 30, whatever total it reports. To collect more, split a big search into narrower ones: several keywords, cities instead of a whole country, or a date window.

**Description extract, not the full description.** You get the short extract Glassdoor shows in search results, plus the extracted skills and benefits. The full job text is on the job page (`url`).

**Salary is what Glassdoor shows.** When the employer did not post pay, Glassdoor often shows its own estimate, marked `salary_source: "ESTIMATED"`. Some jobs have no pay at all. Currency is as Glassdoor labels it.

**Country wide searches in the US.** A glassdoor.com search with no location returned sponsored listings only in our tests. For the full list, give a city or state.

**Ratings.** The rating filter is Glassdoor's own; the actor also drops any job whose company rating is below your minimum or missing, because Glassdoor let a few through in testing.

**Dates.** Glassdoor gives the age of a listing in whole days, so `posted_date_estimate` is exact to the day, not the hour.

**Limits.** Up to 50 searches per run and 1,000 jobs per search. Glassdoor changes its site from time to time; if it refuses a search, the run summary says so and nothing is charged for it.

### What can you use it for?

**Salary benchmarking.** Pull every data analyst job in a city and compare the pay ranges employers post with Glassdoor's estimates.

**Hiring lead lists.** Find companies hiring for a role in your territory, with their rating and logo, and track them week by week with the date filter.

**Job market research.** Count openings by title, city, company and job type, and see which skills and benefits come up most often.

**Job boards and alerts.** Feed fresh listings posted in the last day or week into your own site, newsletter or Slack channel.

### How do I get started?

1. Type one or more job titles into **Keywords**.
2. Add a **Location** and pick the **Glassdoor site** for that country, or leave the location empty for the whole country.
3. Set **Jobs per search**, and any filters you want.
4. Click Start, then download the dataset as JSON, CSV or Excel, or read it through the API or MCP.

### Can I run it on a schedule?

Yes. Run it once with the input you want, click **Save as a task**, then in Apify Console go to **Schedules**, create a schedule, pick how often (for example every morning) and add the task. With **Posted within the last N days** set to 1, each daily run returns that day's new jobs. Each scheduled run is billed the same way as a manual one; the schedule itself costs nothing.

### FAQ

#### How much does it cost to scrape 1,000 Glassdoor jobs?

1,000 x $0.0015 on Apify's Free plan, 1,000 x $0.00135 on Starter, 1,000 x $0.0012 on Scale and 1,000 x $0.001 on Business and above, plus $0.005 per run. Salary ranges, ratings, job attributes and filters are included, and duplicates, blocked pages and filtered jobs are not charged.

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

No. The actor reads public job listings the way Glassdoor shows them to a visitor who is not logged in. There is nothing of yours to connect, and no account of yours can be blocked.

#### Does it return salaries?

Yes, whenever Glassdoor shows pay on the job: `salary_min`, `salary_median` and `salary_max` with the period (`ANNUAL`, `HOURLY` and so on) and currency. `salary_source` tells you whether the employer posted it (`EMPLOYER_PROVIDED`) or it is Glassdoor's estimate (`ESTIMATED`).

#### Can I search a whole state or country?

Yes. Type a state (`California`) or a country (`United Kingdom`) as the location, or leave the location empty to search the whole country of the Glassdoor site you picked.

#### How many jobs can one search return?

Up to 900, because Glassdoor stops at 30 pages of 30 jobs. The run summary shows how many jobs Glassdoor reported for each search next to how many were read. For more, use narrower searches: more specific keywords, several cities, or a date window.

#### Can I get only jobs posted in the last day or week?

Yes. Set **Posted within the last N days** to anything from 1 to 30. It uses Glassdoor's own date filter, so older jobs are never fetched or charged.

#### Which countries does it support?

The United States (glassdoor.com), United Kingdom (glassdoor.co.uk), Canada (glassdoor.ca), Australia (glassdoor.com.au), Germany (glassdoor.de), France (glassdoor.fr) and India (glassdoor.co.in). Pick the site, then give a location in that country.

#### What happens if my location is not found?

The search is reported as `location_not_found` in the run summary, returns nothing and costs nothing. Try the spelling Glassdoor uses, such as `New York, NY` or `London`.

#### Am I charged for duplicates or blocked pages?

No. The same job found by two keywords is returned and charged once. Pages Glassdoor refuses are retried on a fresh connection; if they still fail they are listed in the run summary and nothing is charged for them.

#### Can I paste a Glassdoor search URL instead of keywords?

Yes. Put Glassdoor job search result URLs in **Glassdoor search URLs**. The filters in the URL are kept, and each URL is read up to **Jobs per search** jobs.

#### Is it legal to scrape Glassdoor job listings?

The actor collects only publicly visible job listings and never logs in. In *hiQ Labs v. LinkedIn* a US federal appeals court found that accessing publicly available data is unlikely to breach the Computer Fraud and Abuse Act, but platform terms and privacy laws such as GDPR still apply to how you store and use the data. This is general information, not legal advice.

### Use in Claude, ChatGPT and any MCP agent

Add it to Claude Code in one line:

```bash
claude mcp add --transport http apify "https://mcp.apify.com/?tools=themineworks/glassdoor-jobs-salary-scraper"
```

Or point any MCP client at:

```
https://mcp.apify.com/?tools=themineworks/glassdoor-jobs-salary-scraper
```

Things an agent can ask once connected:

- "What do data analyst jobs in Austin pay on Glassdoor right now? Give me the median by company."
- "List remote product manager jobs posted in the last 3 days at companies rated 4 stars or more."
- "Which companies are hiring nurses in London this week, and what hourly rates do they post?"

Or call it from code with the Apify client:

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });

const run = await client.actor('themineworks/glassdoor-jobs-salary-scraper').call({
  keywords: ['data analyst'],
  location: 'Austin, TX',
  site: 'glassdoor.com',
  maxResultsPerSearch: 100,
  postedWithinDays: 7,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((j) => j.salary_source === 'EMPLOYER_PROVIDED' && j.salary_median >= 100000));
```

### More from The Mine Works

Browse every tool at [themineworks.com](https://themineworks.com/). Related actors for jobs data:

- **[LinkedIn Jobs Scraper](https://apify.com/themineworks/linkedin-jobs-scraper)**: LinkedIn job listings by keyword and location, no login.
- **[ATS Jobs Scraper](https://apify.com/themineworks/ats-jobs)**: live jobs straight from company boards on Greenhouse, Lever, Workday and Ashby.
- **[SEEK Jobs Scraper](https://apify.com/themineworks/seek-jobs-scraper)**: SEEK Australia job listings with salary labels and work types.

Found this useful? A quick Store review helps other buyers find it. Found a bug or want a field added? Open an issue on the actor's Apify Console page.

***

**Disclaimer:** This actor is an independent tool and is not affiliated with, endorsed by, or sponsored by Glassdoor, Inc. Glassdoor is a trademark of Glassdoor, Inc. Use scraped public data in line with GDPR, CCPA and your local laws.

# Actor input Schema

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

Job titles or keywords to search, one per line, for example data analyst or registered nurse. Each keyword is its own search. Up to 50 per run. The same job found by two keywords is returned once.

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

A city, state or country, for example Austin, TX or London or California. It is matched against Glassdoor's own location list for the chosen site. Leave empty to search the whole country of the site.

## `site` (type: `string`):

Which Glassdoor country site to search. The location must be in that country.

## `maxResultsPerSearch` (type: `integer`):

The most jobs to return for each keyword. Glassdoor shows 30 jobs per page and at most 30 pages (900 jobs) for one search, so to collect more, split the search into narrower keywords or locations.

## `postedWithinDays` (type: `integer`):

Only jobs posted in the last N days (1 to 30), using Glassdoor's own date filter. Leave empty for any date.

## `remoteOnly` (type: `boolean`):

Only jobs Glassdoor marks as remote or work from home.

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

Only jobs you can apply to directly on Glassdoor.

## `minCompanyRating` (type: `integer`):

Only jobs at companies rated at least this many stars on Glassdoor (1 to 4). Jobs whose company has no rating are left out. Leave empty for any rating.

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

Instead of keywords, paste Glassdoor job search result URLs, for example https://www.glassdoor.com/Job/austin-tx-data-analyst-jobs-SRCH\_IL.0,9\_IC1139761\_KO10,22.htm. Any filters in the URL are kept. Each URL is one search and uses Jobs per search.

## Actor input object example

```json
{
  "keywords": [
    "data analyst"
  ],
  "location": "Austin, TX",
  "site": "glassdoor.com",
  "maxResultsPerSearch": 30,
  "remoteOnly": false,
  "easyApplyOnly": false
}
```

# Actor output Schema

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

No description

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

No description

# 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"
};

// Run the Actor and wait for it to finish
const run = await client.actor("themineworks/glassdoor-jobs-salary-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",
}

# Run the Actor and wait for it to finish
run = client.actor("themineworks/glassdoor-jobs-salary-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"
}' |
apify call themineworks/glassdoor-jobs-salary-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,themineworks/glassdoor-jobs-salary-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/AJbC4uUd5VQf1WWjZ/builds/wEDY7BhOOVTlI1auk/openapi.json
