# Glassdoor Scraper — Reviews, Salaries, Culture & Jobs (`brilliant_gum/glassdoor-scraper`) Actor

Scrape Glassdoor without login: reviews with sub-ratings and employer replies, salary percentiles by role, interviews, benefits, jobs, offices and culture ratings by demographic group.

- **URL**: https://apify.com/brilliant\_gum/glassdoor-scraper.md
- **Developed by:** [Yuliia Kulakova](https://apify.com/brilliant_gum) (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.009 / review

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.

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 Scraper — Reviews, Salaries, Culture & Jobs

Pull structured Glassdoor data across **eight modes** in one run — reviews, salaries, jobs, company overview, benefits, culture & diversity, interviews and office locations — with **no built-in 200-review cap**, per-review sentiment and theme tagging, salary percentiles and confidence, full company firmographics, and cross-run deduplication for scheduled monitoring. Keyless: no Glassdoor account or cookie required.

![Glassdoor Scraper — Reviews, Salaries, Culture & Jobs](https://api.apify.com/v2/key-value-stores/IuFu0Cw6PpOkNkDV7/records/glassdoor-scraper-banner)

***

### What it does

This Actor turns any Glassdoor company page into clean, analysis-ready rows. Point it at company names, a search query, or direct Glassdoor URLs (any tab, any country domain), pick the modes you want, and it returns one flat record per review, salary, job, office, benefit set, demographic breakdown, interview, or company profile — plus optional analytics computed locally.

It is HTTP-first — no headless browser, no login, no API key. It reads public Glassdoor data and returns it as flat rows, ready for a spreadsheet or a database.

**Who it's for**

- **HR & talent / recruiting** — employer-branding monitoring, competitor review tracking, interview-process intel.
- **Compensation teams** — salary benchmarking with percentiles, confidence and bonus breakdowns.
- **Market & competitive research** — firmographics, ratings trends, culture and diversity signals.
- **Investors & analysts** — employee-sentiment and workforce signals as an alternative data source.

***

### Key features

- **8 modes, mix-and-match** — `reviews`, `salaries`, `jobs`, `company-overview`, `benefits`, `culture` (diversity), `interviews`, `locations`. Every selected mode runs for every resolved company/URL.
- **No 200-review cap.** Most Glassdoor scrapers stop at a couple of hundred reviews, or at the handful the logged-out page shows. This one keeps paginating in bulk, deduped by review id, limited only by your `maxResults` (0 = everything). Salaries and jobs are uncapped too.
- **Per-review sentiment + theme extraction** — a local lexicon scorer adds `sentiment {score, label}`, and `themes[]` tags each review by aspect (compensation, management, workLifeBalance, culture, career, jobSecurity) with polarity. No external AI dependency.
- **Salary depth** — base-pay and total-comp **P10–P90 percentiles**, `confidence {level, salaryCount}`, sample counts, plus (with `salaryDetail`) **additional-pay breakdowns** (cash bonus / stock / commission / profit-sharing / tips / total additional pay) and **recent salary reports** (job title, years of experience, city/state/metro and date — Glassdoor does not publish the amount of an individual report).
- **Company firmographics** — size, revenue, type, stock symbol, industry + sector, HQ, website, year founded, description, mission, logo, competitors, **Best-Places-to-Work awards**, certifications, office addresses, and CEO approval — a full company profile in one row.
- **Employer scorecard roll-up** — one cross-mode summary row per company: overall rating, average review sentiment, review volume, median base salary, recommend/CEO/outlook %, and a recent-review **churn signal**.
- **Cross-run dedup + monitoring on ALL modes** — `dedupKey` on every record; persist seen keys in a named key-value store to avoid re-billing/duplication across scheduled runs; `monitoringMode` emits only records unseen since the last run (new-review / new-job alerts).
- **Company contact emails** — optionally collect the company's role-based addresses (`info@`, `hr@`, `careers@` …) from its own website and check the domain accepts mail (`enrichEmails`). Personal mailboxes are never collected. Note that large corporations usually publish a contact form instead of an address, so this field is most useful for small and mid-sized employers.
- **Keyless & resilient** — no account or API key needed; blocked requests are retried automatically on a fresh connection.

***

### Input

Set `mode` (required) and at least one target (`companyNames`, `companySearchQuery`, or `startUrls`). All other fields are optional filters/toggles.

#### Parameters

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | array (multiselect) | `["reviews"]` | Any of `reviews`, `salaries`, `company-overview`, `interviews`, `jobs`, `benefits`, `culture`, `locations`. |
| **Targeting** | | | |
| `companyNames` | array | — | Company names resolved to Glassdoor employers via search (e.g. `["Google","Netflix"]`). |
| `startUrls` | array | — | Direct Glassdoor URLs (any tab / country domain); employer id `E12345` auto-extracted. |
| `companySearchQuery` | string | — | Free-text company search; resolves the top matching employer(s). |
| `searchDomain` | string | `www.glassdoor.com` | Glassdoor domain/TLD (e.g. `www.glassdoor.co.uk`, `www.glassdoor.ca`). |
| `minCompanyRating` | integer | `0` | Skip companies below this overall rating (1–5). 0 = no filter. |
| `companySize` | string | — | Optional company-size filter label (informational / jobs search). |
| `industryId` | integer | — | Glassdoor industry id filter (jobs / search). |
| `sectorId` | integer | — | Glassdoor sector id filter (jobs / search). |
| **Jobs filters** | | | |
| `searchKeyword` | string | — | Jobs keyword to search. |
| `searchLocation` | string | — | Jobs location text. |
| `radius` | integer | — | Jobs search radius (miles). |
| `matchKeywordInTitle` | boolean | `false` | Only keep jobs whose title contains the keyword. |
| `jobType` | enum | `""` | `fulltime` / `parttime` / `contract` / `internship` / `temporary`. |
| `maxDaysOld` | integer | `0` | Only jobs posted within N days. 0 = any. |
| `remoteWorkType` | enum | `""` | `onsite` / `remote` / `hybrid`. |
| `easyApplyOnly` | boolean | `false` | Only Easy Apply jobs. |
| `minSalary` / `maxSalary` | integer | — | Jobs salary bounds. |
| `sortBy` | enum | `date` | `relevance` / `date`. |
| `resumeKeywords` | array | — | Skills to compute a per-job `matchScore` + `matchedSkills`. |
| **Reviews filters** | | | |
| `minRating` | integer | `0` | Keep reviews with overall rating ≥ this (1–5). 0 = no filter. |
| `reviewJobTitle` | string | — | Filter reviews by job title. |
| `reviewLocation` | string | — | Filter reviews by location. |
| `reviewsStartDate` | string | — | Keep reviews on/after `YYYY-MM-DD` or relative (`30 days`). |
| `employmentStatus` | enum | `any` | `current` / `former` / `any`. |
| `languageId` | string | `eng` | ISO language code or `all`. |
| `includeAllReviews` | boolean | `false` | Pull reviews in every language (overrides `languageId`). |
| `includeCompanyReviewStats` | boolean | `false` | Attach `reviewStats` (rating histogram, aggregate ratings, numberOfPages) to company-overview. |
| `includeCompanyInterviewStats` | boolean | `false` | Emit one interview-stats record per company (difficulty mean, experience & channel distributions). |
| `sortReviewsBy` | enum | `DATE` | `DATE` (most recent) / `RELEVANCE`. |
| `keywordFilter` | string | — | Keep reviews whose pros/cons/summary contain this keyword. |
| **Salary filters** | | | |
| `salaryJobTitle` | string | — | Restrict salaries to a job title. |
| `salaryLocation` | string | — | Salary location scope. |
| `seniority` | string | — | Seniority scope. |
| `currency` | string | — | Preferred currency. |
| `salaryDetail` | boolean | `true` | Fetch per-title detail page for bonus breakdown + individual submissions (1 request/row). |
| `maxSalaryDetail` | integer | `50` | Cap on how many salary rows get detail enrichment. |
| **Company-overview enrichment** | | | |
| `enrichEmails` | boolean | `false` | Harvest + MX-verify business contact emails from the company website. |
| **Volume, dedup & proxy** | | | |
| `maxResults` | integer | `100` | Records per company per mode. **0 = all (no cap).** |
| `startPage` | integer | `1` | First results page (1-based); window large pulls with `maxResults`. |
| `deduplicate` | boolean | `true` | Drop records whose `dedupKey` was already produced. |
| `deduplicateKeyStore` | string | — | Named key-value store to persist seen keys across runs. |
| `monitoringMode` | boolean | `false` | Output only records unseen since the previous run (requires `deduplicateKeyStore`). |
| `maxChallengeRetries` | integer | `3` | How many times to retry a blocked request before giving up on it. |
| `proxy` | object | — | Proxy configuration. Leave the default. |
| **Analytics** | | | |
| `reviewSentiment` | boolean | `true` | Add `sentiment {score, label}` to each review. |
| `themeExtraction` | boolean | `true` | Add aspect `themes[]` with polarity to each review. |
| `salaryPercentiles` | boolean | `true` | Add `derivedPercentiles` (p10/p25/p50/p75/p90/mean) to salary rows. |
| `employerScorecard` | boolean | `false` | Emit one cross-mode roll-up row per company. |

#### Input examples

**Reviews in bulk (uncapped, English, most recent) with analytics**

```json
{
  "mode": ["reviews"],
  "companyNames": ["Google"],
  "sortReviewsBy": "DATE",
  "languageId": "eng",
  "maxResults": 0,
  "reviewSentiment": true,
  "themeExtraction": true
}
```

**Salary benchmarking for a role, with bonus breakdown + individual submissions**

```json
{
  "mode": ["salaries"],
  "companyNames": ["Google"],
  "salaryJobTitle": "Software Engineer",
  "salaryLocation": "United States",
  "salaryDetail": true,
  "maxSalaryDetail": 50,
  "salaryPercentiles": true
}
```

**Company overview + locations + benefits, with review stats and email enrichment**

```json
{
  "mode": ["company-overview", "locations", "benefits"],
  "companyNames": ["Netflix"],
  "includeCompanyReviewStats": true,
  "enrichEmails": true
}
```

**Scheduled monitoring — only new reviews since last run**

```json
{
  "mode": ["reviews"],
  "startUrls": [{ "url": "https://www.glassdoor.com/Reviews/Google-Reviews-E9079.htm" }],
  "deduplicate": true,
  "deduplicateKeyStore": "glassdoor-google-seen",
  "monitoringMode": true
}
```

***

### Output

One flat row per record. Every record carries a `recordType` (`review` / `salary` / `company-overview` / `job` / `benefits` / `culture` / `location` / `interview` / `interview-stats` / `employer-scorecard`), a natural `dedupKey`, and a `scrapedAt` timestamp. A `RUN_SUMMARY` (counts by mode, blocked targets) is written to the run's key-value store.

The samples below are trimmed for readability; field names are exactly as emitted.

#### `review`

```json
{
  "recordType": "review",
  "reviewId": 78412034,
  "employerId": 9079,
  "companyName": "Google",
  "company": { "id": 9079, "name": "Google", "logo": "https://media.glassdoor.com/sql/9079/google-squareLogo.png" },
  "ratingOverall": 5,
  "subratings": {
    "workLifeBalance": 4,
    "cultureAndValues": 5,
    "seniorManagement": 4,
    "compensationAndBenefits": 5,
    "careerOpportunities": 5,
    "diversityAndInclusion": 5,
    "ceoApproval": 1,
    "businessOutlook": 1,
    "recommendToFriend": 1
  },
  "summary": "Great place to grow",
  "pros": "Smart people, strong benefits and real work-life balance.",
  "cons": "Can be bureaucratic; promotions are slow.",
  "adviceToMgmt": "Keep investing in career growth.",
  "jobTitle": "Software Engineer",
  "location": { "name": "Mountain View, CA", "type": "CITY" },
  "employmentStatus": "current",
  "rawEmploymentStatus": "REGULAR",
  "isCurrentJob": true,
  "tenureYears": 3,
  "reviewDate": "2026-08-14T00:00:00.000",
  "language": "eng",
  "countHelpful": 12,
  "countNotHelpful": 0,
  "employerResponses": [],
  "employerResponse": null,
  "originalLanguageId": "eng",
  "demographicRatings": null,
  "featured": false,
  "companyReviewsUrl": "https://www.glassdoor.com/Reviews/Employer-Reviews-E9079.htm",
  "sentiment": { "score": 0.72, "label": "positive" },
  "themes": [
    { "theme": "compensation", "polarity": "positive", "mentions": 2 },
    { "theme": "career", "polarity": "mixed", "mentions": 2 }
  ],
  "dedupKey": "review:78412034",
  "scrapedAt": "2026-09-02T12:00:00.000Z"
}
```

`employerResponses[]` is the full array of employer replies (`text`, `responseDateTime`, `responderName`, `responderTitle`); `employerResponse` is the first reply for back-compat.

#### `salary`

```json
{
  "recordType": "salary",
  "employerId": 9079,
  "companyName": "Google",
  "jobTitle": "Software Engineer",
  "jobTitleId": 1072,
  "basePay": {
    "p10": 145000, "p25": 165000, "p50": 190000, "p75": 220000, "p90": 255000,
    "derivedPercentiles": { "p10": 145000, "p25": 165000, "p50": 190000, "p75": 220000, "p90": 255000, "mean": 195000, "count": 5 }
  },
  "totalComp": { "p10": 180000, "p25": 210000, "p50": 260000, "p75": 320000, "p90": 400000 },
  "currency": "USD",
  "payPeriod": "ANNUAL",
  "location": "United States",
  "seniority": "All years of experience",
  "sampleCount": 4213,
  "confidence": { "level": "HIGH", "salaryCount": 4213 },
  "mostRecent": "2026-08-01",
  "cashBonusStatistics": { "p25": 12000, "median": 22000, "p75": 38000 },
  "stockBonusStatistics": { "p25": 30000, "median": 65000, "p75": 120000 },
  "profitSharingStatistics": null,
  "salesCommissionStatistics": null,
  "tipsStatistics": null,
  "totalAdditionalPayStatistics": { "p25": 42000, "median": 87000, "p75": 158000 },
  "individualSalariesForGoc": [
    {
      "jobTitle": "Senior Software Engineer", "yearsOfExperience": "7-9 years",
      "city": "Los Angeles, CA", "state": "California", "metro": "Los Angeles, CA",
      "country": "United States", "reportedOn": "2026-08-20"
    }
  ],
  "relatedJobTitles": [
    { "jobTitle": "Senior Software Engineer", "url": "https://www.glassdoor.com/Salary/Google-Senior-Software-Engineer-Salaries-E9079.htm" }
  ],
  "source": "GLASSDOOR_ESTIMATE",
  "dedupKey": "salary:9079:1072",
  "scrapedAt": "2026-09-02T12:00:00.000Z"
}
```

The additional-pay blocks (`cashBonusStatistics`, `stockBonusStatistics`, …), the salary reports, `relatedJobTitles[]` and `availableCountries[]` populate only when `salaryDetail` is on and within `maxSalaryDetail`; they are `null`/`[]` otherwise. A bonus block is `null` when Glassdoor publishes no figure for it — never a misleading zero.

`individualSalariesForGoc[]` lists the recent salary reports behind the estimate: job title, years of experience, location and date. Glassdoor does not publish the amount of an individual report, so those rows carry no pay figures — the money is in the percentiles above.

#### `company-overview`

```json
{
  "recordType": "company-overview",
  "employerId": 9079,
  "name": "Google",
  "shortName": "Google",
  "overallRating": 4.4,
  "subratings": {
    "careerOpportunities": 4.3,
    "compensationAndBenefits": 4.5,
    "cultureAndValues": 4.4,
    "diversityAndInclusion": 4.4,
    "seniorManagement": 3.9,
    "workLifeBalance": 4.2
  },
  "ceoApprovalPercent": 86.0,
  "recommendToFriendPercent": 89.0,
  "businessOutlookPercent": 71.0,
  "ratedCeo": { "name": "Sundar Pichai", "title": "CEO", "photo": "https://media.glassdoor.com/people/sundar-pichai.png" },
  "reviewCount": 54832,
  "size": "10000+ Employees",
  "revenue": "$10+ billion (USD)",
  "type": "Company - Public",
  "stockSymbol": "GOOGL",
  "primaryIndustry": { "industryId": 200063, "industryName": "Internet & Web Services", "sectorId": 10013, "sectorName": "Information Technology" },
  "headquarters": "Mountain View, CA",
  "website": "www.google.com",
  "yearFounded": 1998,
  "description": "Google's mission is to organize the world's information...",
  "mission": "To organize the world's information and make it universally accessible and useful.",
  "squareLogoUrl": "https://media.glassdoor.com/sql/9079/google-squareLogo.png",
  "coverPhoto": null,
  "competitors": ["Meta", "Amazon", "Microsoft"],
  "awards": [ { "name": "Best Places to Work", "rank": 8, "year": "2026", "listType": "BPTW_EMPLOYEES_CHOICE" } ],
  "certifications": [],
  "officeAddresses": [
    { "name": "Googleplex", "addressLine": "1600 Amphitheatre Parkway", "city": "Mountain View", "state": "California", "country": "United States", "postalCode": "94043", "isHeadquarters": true, "latitude": 37.422, "longitude": -122.084 }
  ],
  "parent": null,
  "subsidiaries": [],
  "siblings": [],
  "counts": { "reviews": 54832, "salaries": 68210, "jobs": 4123, "interviews": 13290, "benefits": 1876, "photos": 4501 },
  "url": "https://www.glassdoor.com/Overview/Working-at-E9079.htm",
  "scrapedAt": "2026-09-02T12:00:00.000Z"
}
```

With `includeCompanyReviewStats`, a `reviewStats` object (`ratingCountDistribution`, `ratings`, `allReviewsCount`, `filteredReviewsCount`, `numberOfPages`) is attached; with `enrichEmails`, a `contactEmails[]` array is added.

#### Other record types (field lists)

- **`job`** — `jobId`, `title`, `company {id,name,logo}`, `location {name,type,country}`, `salaryEst {min,max,currency,period,source}`, `easyApply`, `ageInDays`, `postedDate`, `jobUrl`, and (with `resumeKeywords`) `matchScore` + `matchedSkills`, `dedupKey`.
- **`benefits`** — one record per company: `overallBenefitRating`, `benefitCount`, `categories[]` → `{categoryId, categoryName, benefits[] {id, name, rating (0–5), reviewCount, totalComments, verified}}`, `dedupKey`.
- **`culture`** — one record per company: `demographicRatings` keyed by `raceEthnicity`, `gender`, `sexualOrientation`, `disability`, `parentOrCaregiver`, `veteranStatus`; each segment carries `overallRating`, `reviewCount`, the six sub-ratings and CEO/recommend/outlook %, `dedupKey`.
- **`location`** — one record per office: `name`, `addressLine`, `city`, `state`, `country`, `postalCode`, `locationId`, `overallRating`, `latitude`, `longitude`, `dedupKey`.
- **`interview`** — `interviewId`, `difficulty`, `difficultyLabel`, `experience`, `outcome`, `processDescription`, `userQuestions[]`, `jobTitle`, `location`, `source`, `date`, `countHelpful`, `dedupKey`. With `includeCompanyInterviewStats`, an `interview-stats` record adds difficulty mean, experience distribution and the "getting an interview" channel breakdown.
- **`employer-scorecard`** (`employerScorecard`) — one roll-up per company: `overallRating`, `recommendToFriendPercent`, `ceoApprovalPercent`, `businessOutlookPercent`, `reviewsAnalyzed`, `avgReviewSentiment`, `churnSignal`, `salaryMedianBase`, `counts`, `url`.

***

### Pricing

This Actor is billed **pay per event**: every record has its own price, because they are not
the same size. One `culture` record holds every demographic breakdown for a company; one `job`
record is a single posting.

Bulk records, price per 1,000:

| Record | Per 1,000 |
|--------|-----------|
| Salary report | **$15** |
| Review | **$9** |
| Interview report | **$9** |
| Job posting | **$4** |
| Office location | **$2** |

One record per company:

| Record | Each |
|--------|------|
| Company profile | **$0.05** |
| Culture & diversity | **$0.05** |
| Benefits | **$0.04** |
| Employer scorecard | **$0.02** |
| Interview statistics | **$0.01** |

Plus **$0.01** per run when the Actor starts.

What that means in practice:

- 1,000 reviews for one employer — **$9**
- 500 job postings — **$2**
- 100 salary reports with percentiles — **$1.50**
- A company's full profile (overview + culture + benefits + scorecard) — **$0.16**

**Duplicates and empty records are not charged.** A record is billed only once it actually
reaches the dataset, so scheduled runs with `deduplicate` + `deduplicateKeyStore` (and
`monitoringMode`) pay only for genuinely new data. If you set a maximum cost per run, the
Actor stops as soon as it is reached and tells you so in the run status.

Glassdoor pages are slow to fetch, so expect a few seconds per request — plan large jobs
accordingly. (The authoritative prices are the ones on the Actor's Apify Store page.)

***

### Use cases

- **Employer branding** — track your own and competitors' review volume, ratings, sentiment and CEO approval over time; alert on new reviews with `monitoringMode`.
- **Compensation benchmarking** — pull role-level base + total-comp percentiles, confidence and bonus/stock breakdowns across peer companies to calibrate offers and pay bands.
- **Competitive intelligence** — firmographics, interview processes, benefits and culture/diversity ratings for a target set of employers in a single scheduled run.
- **Investment / alternative-data research** — employee sentiment, churn signal, review trends and workforce ratings as inputs to workforce and company-health models.

***

### Honest limitations

Everything documented above is returned. Two Glassdoor-side gaps are worth calling out explicitly:

- **There is no permanent link to a single review.** Glassdoor gives individual reviews no URL of their own, so each row carries `companyReviewsUrl` — the company's reviews page — rather than a deep link that would not resolve.
- **Individual benefit comments are not available.** Glassdoor does not publish the free-text comment behind each benefit to logged-out visitors. The `benefits` mode returns per-benefit aggregates instead: `rating` (0–5), `reviewCount`, `totalComments` (the count) and a `verified` flag — not the comment text.
- **Salary breakdowns by gender or race are not published.** Glassdoor keeps those behind its own gate, so `demographics` is `null` rather than guessed. Everything else about pay comes through: percentiles, confidence, bonus and stock breakdowns, and individual submissions with years of experience and city.

Glassdoor blocks aggressively, so leave the proxy setting at its default — it is the configuration this Actor is tuned for.

***

### FAQ

**Do I need a Glassdoor account or an API key?**
No. Reviews, salaries and jobs are all collected without any login.

**How does it get past the 200-review cap other scrapers hit?**
It pages through reviews in bulk rather than reading the handful shown on the public page, deduping by review id. The only limit is your `maxResults` (0 = everything).

**Can I scrape multiple companies at once?**
Yes — list several in `companyNames`, pass multiple `startUrls`, or use `companySearchQuery`. Each selected mode runs for every resolved company.

**Which countries / domains are supported?**
Set `searchDomain` to any Glassdoor TLD (e.g. `www.glassdoor.co.uk`, `www.glassdoor.ca`). Direct `startUrls` on any country domain work too — the employer id is extracted automatically.

**How do I run incremental/monitoring jobs?**
Set `deduplicate: true` with a named `deduplicateKeyStore`, then enable `monitoringMode` to emit only records unseen since the previous run — ideal for new-review or new-job alerts.

**Is the sentiment/theme analysis AI-based?**
No external AI. Sentiment is a local lexicon scorer blended with the numeric rating; themes are aspect keyword buckets with polarity. This keeps runs fast and deterministic.

***

### Legal / ToS

Scrapes **public** Glassdoor data only. The Actor does not log in and does not bypass authentication. Scraping may violate Glassdoor's Terms of Service; you are responsible for your use and for handling any personal data in line with GDPR/CCPA (provide opt-out on request). Defensible as public-data access (cf. *hiQ v. LinkedIn*), but this is not legal advice.

# Actor input Schema

## `mode` (type: `array`):

What to scrape. Each selected mode runs for every resolved company/URL. company-overview & locations read the Overview page (firmographics + offices); reviews & culture read the reviews page (reviews / demographic ratings); salaries, interviews, jobs and benefits use their own pages.

## `companyNames` (type: `array`):

Company names to resolve to Glassdoor employers via search (e.g. "Google", "Netflix"). The best-matching employer is used.

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

Direct Glassdoor URLs (any tab / country domain). Reviews, Salary, Interview, Jobs or Overview URLs are all accepted; the employer id (E12345) is extracted automatically.

## `companySearchQuery` (type: `string`):

Free-text company search. Resolves the top matching employer(s).

## `searchDomain` (type: `string`):

Glassdoor domain to use, e.g. www.glassdoor.com, www.glassdoor.co.uk, www.glassdoor.ca.

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

Skip companies whose overall rating is below this (1-5). 0 = no filter.

## `companySize` (type: `string`):

Optional company-size filter label (informational / jobs search).

## `industryId` (type: `integer`):

Glassdoor industry id filter (jobs / search).

## `sectorId` (type: `integer`):

Glassdoor sector id filter (jobs / search).

## `searchKeyword` (type: `string`):

Jobs mode: keyword to search.

## `searchLocation` (type: `string`):

Jobs mode: location text.

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

Jobs mode: search radius in miles.

## `matchKeywordInTitle` (type: `boolean`):

Only keep jobs whose title contains the keyword.

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

fulltime | parttime | contract | internship | temporary.

## `maxDaysOld` (type: `integer`):

Only keep jobs posted within this many days. 0 = any.

## `remoteWorkType` (type: `string`):

onsite | remote | hybrid.

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

Return only jobs that support Easy Apply.

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

Minimum salary filter for job search.

## `maxSalary` (type: `integer`):

Maximum salary filter for job search.

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

date | relevance.

## `resumeKeywords` (type: `array`):

Skills/keywords to compute a match score against each job description.

## `minRating` (type: `integer`):

Keep reviews with overall rating >= this (1-5). 0 = no filter.

## `reviewJobTitle` (type: `string`):

Filter reviews by the reviewer's job title.

## `reviewLocation` (type: `string`):

Filter reviews by location.

## `reviewsStartDate` (type: `string`):

Keep reviews on/after this date (YYYY-MM-DD) or relative like '30 days'.

## `employmentStatus` (type: `string`):

current | former | any.

## `languageId` (type: `string`):

ISO language code (e.g. eng) or 'all'.

## `includeAllReviews` (type: `boolean`):

Pull reviews in every language (overrides the language filter above). Off = only the language set in 'Reviews: language' (default English).

## `includeCompanyReviewStats` (type: `boolean`):

For company-overview: attach reviewStats — the per-subrating 1-5 rating histogram (ratingCountDistribution), aggregate ratings and numberOfPages.

## `includeCompanyInterviewStats` (type: `boolean`):

For interviews mode: emit one interview-stats record per company — overall interview difficulty (mean), the experience distribution (positive/neutral/negative) and the 'getting an interview' channel breakdown (applied online / recruiter / employee referral / campus / staffing agency).

## `sortReviewsBy` (type: `string`):

DATE (most recent) or RELEVANCE.

## `keywordFilter` (type: `string`):

Only keep reviews whose pros/cons/summary contain this keyword.

## `salaryJobTitle` (type: `string`):

Filter salaries by job title.

## `salaryLocation` (type: `string`):

Filter salaries by location.

## `seniority` (type: `string`):

Filter salaries by seniority level.

## `currency` (type: `string`):

Currency code for salary values (e.g. USD).

## `salaryDetail` (type: `boolean`):

For each salary row, fetch the job-title detail page to add the additional-pay breakdown (cash bonus, stock, commission, profit-sharing, tips, total additional pay) and recent individual salary submissions (with years-of-experience + city). Adds one request per row — bounded by 'Salaries: max detail rows'.

## `maxSalaryDetail` (type: `integer`):

Cap on how many salary rows get the per-title detail enrichment (protects run time / cost on uncapped pulls).

## `enrichEmails` (type: `boolean`):

For company-overview: collect the company's role-based contact addresses (info@, hr@, careers@ …) from its own website and verify the domain accepts mail. Personal mailboxes are never collected.

## `maxResults` (type: `integer`):

Maximum records per company per mode. 0 = everything available. Reviews are collected in bulk well past the first page.

## `startPage` (type: `integer`):

First results page to fetch (1-based). Use with maxResults to window large pulls.

## `deduplicate` (type: `boolean`):

Drop records whose dedupKey was already produced (within run, and across runs if a key store is set).

## `deduplicateKeyStore` (type: `string`):

Named store that remembers records seen in previous runs, so scheduled runs return only what is new. Leave as is unless you run several independent monitors on one account — then give each its own name.

## `monitoringMode` (type: `boolean`):

Return only records not seen in previous runs of this Actor. Pairs with the store name below.

## `maxChallengeRetries` (type: `integer`):

How many times to retry a blocked request before giving up on it.

## `proxy` (type: `object`):

Optional. Proxies are configured automatically — leave this empty.

## `reviewSentiment` (type: `boolean`):

Add sentiment {score,label} to each review (lexicon-based, no external AI).

## `themeExtraction` (type: `boolean`):

Tag each review with aspect themes (comp, management, WLB, culture, career, DEI...) and polarity.

## `salaryPercentiles` (type: `boolean`):

Compute p10/p25/p50/p75/p90 for salary results.

## `employerScorecard` (type: `boolean`):

Emit one cross-mode roll-up row per company (rating + sentiment + salary median + churn signal).

## Actor input object example

```json
{
  "mode": [
    "reviews"
  ],
  "companyNames": [
    "Google"
  ],
  "searchDomain": "www.glassdoor.com",
  "minCompanyRating": 0,
  "matchKeywordInTitle": false,
  "jobType": "",
  "maxDaysOld": 0,
  "remoteWorkType": "",
  "easyApplyOnly": false,
  "sortBy": "date",
  "minRating": 0,
  "employmentStatus": "any",
  "languageId": "eng",
  "includeAllReviews": false,
  "includeCompanyReviewStats": false,
  "includeCompanyInterviewStats": false,
  "sortReviewsBy": "DATE",
  "salaryDetail": true,
  "maxSalaryDetail": 50,
  "enrichEmails": false,
  "maxResults": 20,
  "startPage": 1,
  "deduplicate": true,
  "deduplicateKeyStore": "glassdoor-seen",
  "monitoringMode": false,
  "maxChallengeRetries": 3,
  "reviewSentiment": true,
  "themeExtraction": true,
  "salaryPercentiles": true,
  "employerScorecard": false
}
```

# Actor output Schema

## `results` (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 = {
    "mode": [
        "reviews"
    ],
    "companyNames": [
        "Google"
    ],
    "searchDomain": "www.glassdoor.com",
    "sortReviewsBy": "DATE",
    "maxResults": 20,
    "deduplicateKeyStore": "glassdoor-seen"
};

// Run the Actor and wait for it to finish
const run = await client.actor("brilliant_gum/glassdoor-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 = {
    "mode": ["reviews"],
    "companyNames": ["Google"],
    "searchDomain": "www.glassdoor.com",
    "sortReviewsBy": "DATE",
    "maxResults": 20,
    "deduplicateKeyStore": "glassdoor-seen",
}

# Run the Actor and wait for it to finish
run = client.actor("brilliant_gum/glassdoor-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 '{
  "mode": [
    "reviews"
  ],
  "companyNames": [
    "Google"
  ],
  "searchDomain": "www.glassdoor.com",
  "sortReviewsBy": "DATE",
  "maxResults": 20,
  "deduplicateKeyStore": "glassdoor-seen"
}' |
apify call brilliant_gum/glassdoor-scraper --silent --output-dataset

```

## MCP server setup

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