# Glassdoor Jobs Scraper ⭐ (employer rating on every job) (`tagadanar/glassdoor-jobs-scraper`) Actor

Glassdoor job listings as JSON, with the hiring company's own Glassdoor star rating on every row, so you can ask for jobs at companies rated 4.0 and up in one pass. Title, company, rating, location, pay range, Easy Apply, posted date, skills and the apply link. No login, no API key.

- **URL**: https://apify.com/tagadanar/glassdoor-jobs-scraper.md
- **Developed by:** [Tagada Data](https://apify.com/tagadanar) (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 $0.28 / 1,000 job scrapeds

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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Glassdoor Jobs Scraper (with the employer's rating on every job)

Live Glassdoor job listings as clean JSON, and every row already carries the hiring company's own Glassdoor star rating. That one field is the reason this actor exists: you can ask for "software engineer jobs in Austin at companies rated 4.0 and up" and get exactly that back, in one pass, instead of scraping the jobs first and then scraping company profiles to find out who is worth applying to.

No login. No cookies to paste. No API key. One flat price per job, platform usage included, so the number you see is the number you pay.

### What it costs

| Event | Price, all-in |
| --- | --- |
| Each job returned | $0.40 per 1,000 |
| Run start | $0.001 |

Platform usage (compute, proxies) is included in those prices. Glassdoor's own job-search endpoint answers without a proxy, and that saving is already in the number. A search that matches nothing is never billed beyond the start fee, and a listing your filters drop is never billed at all.

### The rating filter, and why it is not a checkbox anyone else can add

Glassdoor puts the employer's rating inside the job payload. Every other job scraper in this category throws it away, so filtering by company quality means a second scrape and a join. Here it is one input.

Two details that matter if you rely on it:

- Glassdoor's own rating filter is approximate. Ask its website for 4.0 and it hands back companies rated 3.9, and promoted listings sail past the filter entirely. On a measured run of "software engineer in Austin, TX" with Glassdoor's 4.0 filter on, 38 of 275 listings (14%) came back below 4.0.
- So the bar is applied again on every row here, before you are charged for it. Set 4.0 and you get 4.0, and the run's status message tells you how many listings were dropped and why.

About one job in six is posted by a company Glassdoor has no rating for, usually a small employer or a recruiter. Those rows are dropped when you set a minimum rating, unless you switch on **Keep companies Glassdoor has not rated**.

### Glassdoor job data without the subscription

| | This actor | Glassdoor's own site | A job-data subscription |
| --- | --- | --- | --- |
| Get the data as JSON/CSV | yes, every run | copy and paste | yes |
| Employer star rating on the job row | yes, on every row | one company page at a time | rarely |
| Filter jobs by employer rating | yes, exact | approximate, and promoted ads ignore it | no |
| Pay range on the row | yes, with the estimate flag | yes, on screen | varies |
| Skills and keywords pulled from the ad | yes | no | varies |
| Cost | pennies per thousand jobs | free but manual | hundreds per month |
| Login or API key | none | none | account required |

### What you get

One record per job listing:

| Field | Description |
| --- | --- |
| `jobId` | Glassdoor's listing ID |
| `title` | Job title as advertised |
| `companyName` | Hiring company or recruiter |
| `companyRating` | The company's Glassdoor star rating, e.g. `4.1`. Empty when Glassdoor has no rating for it |
| `companyId` | Glassdoor's employer ID, stable across that company's listings |
| `companyUrl` | The company's Glassdoor page |
| `companyLogoUrl` | Company logo, when the listing has branding |
| `location` | City and state as Glassdoor shows it, e.g. `Austin, TX` |
| `locationId` | Glassdoor's location ID |
| `locationType` | `C` city, `S` state, `N` country, `M` metro |
| `salaryMin`, `salaryMedian`, `salaryMax` | Pay range for the role, 10th, 50th and 90th percentile |
| `salaryCurrency` | e.g. `USD` |
| `salaryPeriod` | `ANNUAL` or `HOURLY` |
| `salaryIsEstimate` | `false` when the employer stated the pay, `true` when Glassdoor estimated it |
| `salaryText` | The same range as one readable line, e.g. `USD 106,425 - 163,174/yr` |
| `easyApply` | Whether you can apply on Glassdoor itself |
| `isSponsored` | Whether the listing is promoted |
| `isExpired` | Whether Glassdoor has already closed it |
| `ageInDays` | Days since it was posted |
| `postedDate` | The posting date as `YYYY-MM-DD` |
| `occupation` | Glassdoor's normalised occupation, e.g. `machine learning engineer` |
| `normalizedTitle` | The title in Glassdoor's normalised form |
| `skills` | Skills named on the listing, e.g. `["Python", "SQL", "C++"]` |
| `jobAttributes` | Every keyword Glassdoor extracted from the ad, seniority and requirements included |
| `teaser` | The summary line from the search card |
| `jobUrl` | Direct link to the listing |
| `applyUrl` | The apply link |
| `searchKeyword` | Which of your keywords found this row |
| `searchLocation` | The location you searched, as Glassdoor resolved it |
| `source` | `glassdoor.com` |
| `scrapedAt` | When the row was collected |

### Who uses it

**Recruiters and staffing agencies.** Pull every open role in a city, keep the ones at companies rated 4.0 and up, and you have a call list of employers whose candidates will actually accept an offer. `companyId` groups every listing by employer, so a company hiring twelve roles at once stands out immediately.

**Job seekers and career coaches.** "Show me remote data roles posted this week at companies rated 4.0+, paying at least $140k." One run, one spreadsheet, no clicking through company profiles to find out who is a bad place to work.

**Market and salary researchers.** `salaryMin`/`salaryMedian`/`salaryMax` with the estimate flag, plus `occupation` and `skills`, gives you a pay-and-skills picture per city that you can rebuild every week and diff.

**Sales teams selling to hiring companies.** A company posting fifteen engineering roles is buying tooling. Filter by location, group by `companyId`, and sort by how many listings each company has open.

### How to use it

Type a job title and a place, the way you would on the site:

```json
{
  "keywords": ["software engineer"],
  "location": "Austin, TX",
  "minEmployerRating": "4.0",
  "maxItems": 200
}
```

Several searches in one run, merged and de-duplicated on the listing ID:

```json
{
  "keywords": ["data engineer", "machine learning engineer", "data scientist"],
  "location": "Texas",
  "minEmployerRating": "4.0",
  "maxAgeDays": "7",
  "sortBy": "date",
  "maxItems": 500
}
```

A daily feed of brand-new remote roles at well-rated companies:

```json
{
  "keywords": ["product manager"],
  "location": "United States",
  "remoteOnly": true,
  "maxAgeDays": "1",
  "minEmployerRating": "4.0",
  "sortBy": "date",
  "maxItems": 200
}
```

Or paste a Glassdoor search link straight from your address bar and let the filters do the rest:

```json
{
  "searchUrls": ["https://www.glassdoor.com/Job/austin-tx-software-engineer-jobs-SRCH_IL.0,9_IC1139761_KO10,27.htm"],
  "minEmployerRating": "3.5",
  "easyApplyOnly": true,
  "maxItems": 100
}
```

### FAQ

**Does it need a Glassdoor login or an API key?**
No. It reads the same public job-search data Glassdoor's own website loads, and it never touches a signed-in page.

**How many jobs can one search return?**
Glassdoor serves at most 900 results for a single search, in 30 pages of 30. Past that the site simply stops answering, so the run says so by name instead of pretending the results ran out. To go deeper, split the search: several keywords, or one city at a time instead of a whole state.

**Why did I ask for 300 jobs and get 237?**
Because your filters dropped the rest, and you were not charged for them. The status message at the end of every run breaks it down, for example "38 listing(s) were dropped by your filters (38 below your rating bar)".

**Is the salary real or estimated?**
Both appear, and `salaryIsEstimate` tells you which. Most listings carry Glassdoor's own estimate for the role; some carry the range the employer published.

**Can I filter by company rating with decimals like 4.2?**
The dropdown offers half steps up to 4.5. If you need a finer bar, set the nearest step and filter `companyRating` yourself in the output; the exact number is on every row.

**Why do some rows have no rating?**
Glassdoor has not collected enough reviews for that employer yet. The field is left empty rather than filled with a guess, and those rows are dropped when you set a minimum rating unless you ask to keep them.

**Does it collect anything about people?**
No. Job listings and company-level data only. No reviewer profiles, no reviews, no applicants, no personal data of any kind.

**What happens if Glassdoor blocks the run?**
The actor tries a second browser fingerprint, and if the block holds it stops rather than paying to hammer a wall. Whatever it already collected stays in the dataset, and the run's status message names the block and the HTTP status.

### Related actors

- [SEEK Jobs Scraper](https://apify.com/tagadanar/seek-jobs-scraper) for Australia
- [LinkedIn Company Jobs](https://apify.com/tagadanar/linkedin-company-jobs) for every open role at a named company
- [LinkedIn Remote Jobs](https://apify.com/tagadanar/linkedin-remote-jobs) for remote-only listings
- [Verified Hiring Employers](https://apify.com/tagadanar/verified-hiring-employers) to check which companies are genuinely hiring
- [ATS Jobs Aggregator](https://apify.com/tagadanar/ats-jobs-aggregator) for listings straight off company career sites

***

Keywords: glassdoor scraper, glassdoor jobs api, glassdoor job listings, scrape glassdoor, glassdoor company ratings, jobs at highly rated companies, employer rating filter, job board scraper, recruiting data, hiring signals, salary data by city, remote jobs scraper, easy apply jobs, job feed json, glassdoor alternative api.

# Actor input Schema

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

One entry per search, exactly what you would type in Glassdoor's job box: a job title, a skill, or a company name. Each entry runs as its own search and the results are merged and de-duplicated. Leave empty to browse a whole location.

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

A city (<code>Austin, TX</code>), a state (<code>Texas</code>) or a country (<code>United States</code>). The name is resolved against Glassdoor's own location list, and a name it does not know is reported by name instead of quietly returning zero jobs.

## `minEmployerRating` (type: `string`):

The headline filter. Every Glassdoor job carries the hiring company's own star rating, so you can ask for jobs at companies people actually rate well without a second scrape. Glassdoor's own filter is approximate (asking for 4.0 returns 3.9s and lets promoted listings through), so the exact bar is applied again on every row before you are charged for it.

## `includeUnratedEmployers` (type: `boolean`):

About one job in six is posted by a company with no Glassdoor rating yet, often a small employer or a recruiter. Off, a minimum rating drops those rows. On, they are kept with an empty rating. Ignored when no minimum rating is set.

## `maxAgeDays` (type: `string`):

Only listings posted recently. Set it to Today and schedule this actor daily to get a feed of brand-new postings and nothing else.

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

Keep only jobs you can apply to on Glassdoor itself, without being sent to the company's own application form.

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

Keep only jobs Glassdoor labels as remote or work-from-home.

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

Lower end of the yearly pay in the location's currency, for example 120000. Glassdoor matches it against its own pay figure for the listing, which is an estimate on most ads.

## `radiusMiles` (type: `string`):

How far around the location to look. Glassdoor's own default is 25 miles.

## `sortBy` (type: `string`):

Relevance is Glassdoor's default. Choose Newest first when you cap the results and want the most recent listings rather than the best-matching ones.

## `includeExpired` (type: `boolean`):

Glassdoor occasionally still returns a listing it has flagged as expired. Off, those rows are dropped and never billed. On, they are kept with an expiry flag.

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

Instead of a keyword and a location, paste the address bar from a Glassdoor search results page, for example <code>https://www.glassdoor.com/Job/austin-tx-software-engineer-jobs-SRCH\_IL.0,9\_IC1139761\_KO10,27.htm</code>. The keyword and the location are read out of the link; the filters above still apply on top.

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

Stop after this many jobs across all searches. You are only charged for jobs actually delivered. Glassdoor itself serves at most 900 results per search, so ask for more than that by splitting the search across several keywords or cities.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "location": "Austin, TX",
  "minEmployerRating": "4.0",
  "includeUnratedEmployers": false,
  "maxAgeDays": "any",
  "easyApplyOnly": false,
  "remoteOnly": false,
  "radiusMiles": "25",
  "sortBy": "relevance",
  "includeExpired": false,
  "maxItems": 30
}
```

# Actor output Schema

## `jobs` (type: `string`):

One item per job in the default dataset.

# 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": [
        "software engineer"
    ],
    "location": "Austin, TX",
    "minEmployerRating": "4.0",
    "maxItems": 30
};

// Run the Actor and wait for it to finish
const run = await client.actor("tagadanar/glassdoor-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": ["software engineer"],
    "location": "Austin, TX",
    "minEmployerRating": "4.0",
    "maxItems": 30,
}

# Run the Actor and wait for it to finish
run = client.actor("tagadanar/glassdoor-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": [
    "software engineer"
  ],
  "location": "Austin, TX",
  "minEmployerRating": "4.0",
  "maxItems": 30
}' |
apify call tagadanar/glassdoor-jobs-scraper --silent --output-dataset

```

## MCP server setup

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