# Glassdoor Jobs Scraper — Salaries, Skills & Company Ratings (`yugenox/glassdoor-jobs-scraper`) Actor

Scrape Glassdoor job listings by keyword and location — US, Canada, UK and more. Salary range with source, skills, benefits, job type, seniority, company rating, and optional full description plus company profile. No login.

- **URL**: https://apify.com/yugenox/glassdoor-jobs-scraper.md
- **Developed by:** [Yugenox Corp](https://apify.com/yugenox) (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.40 / 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.

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, Skills & Company Ratings

Scrape job listings from **Glassdoor** by job title and location — in the **United States, Canada, the UK, Ireland, India, Australia** and every other country Glassdoor covers. Each job comes with its **salary range and where that number came from**, the **skills, benefits, job type, work setting and seniority** Glassdoor extracts from the posting, the **company rating**, and — optionally — the **full job description plus a complete company profile** (size, revenue, headquarters, founded year, industry, CEO, competitors and every Glassdoor sub-rating).

No Glassdoor account, no cookies, no browser. Fast: 100 jobs per request, thousands of jobs per search.

### What you get

| Field | Example |
|---|---|
| `title`, `companyName`, `companyRating` | Analyst - People Analytics (Hybrid) · United Airlines · 3.8 |
| `location`, `locationType`, `countryId` | Chicago, IL · CITY · 1 |
| `salaryMin` / `salaryMedian` / `salaryMax` | 66500 / 76558 / 86616 |
| `salaryPeriod`, `salaryCurrency`, `salarySource` | ANNUAL · USD · EMPLOYER\_PROVIDED (or ESTIMATED) |
| `salaryText` | $66,500 – $86,616 per year (employer provided) |
| `postedDate`, `ageInDays` | 2026-09-19 · 5 |
| `easyApply`, `isSponsored` | false · true |
| `skills` | SQL, Python, Workday, Forecasting… |
| `benefits` | Health insurance, Dental insurance, 401(k), Paid time off… |
| `jobTypes`, `workSetting`, `seniority`, `schedule` | Full-time · Hybrid work · Mid-level · Monday to Friday |
| `education`, `experience`, `licenses`, `requirements` | Bachelor's degree · 3 years · RN License · Background check |
| `url`, `applyUrl`, `companyUrl`, `companyLogo` | links to the job, Glassdoor's apply link, the company page |

With **Full description + company profile** turned on, each job also gets `descriptionHtml`, `descriptionText`, `discoveredAt`, `jobSource`, `latitude` / `longitude`, and `companyDetails`: size, revenue, headquarters, website, founded, type, industry, sector, stock ticker, CEO, competitors and ratings (overall, CEO approval, recommend to a friend, business outlook, career opportunities, compensation & benefits, culture & values, diversity & inclusion, senior management, work-life balance).

#### Sample row

```json
{
  "jobId": 1010267244215,
  "title": "Analyst - People Analytics (Hybrid)",
  "companyName": "United Airlines",
  "companyRating": 3.8,
  "location": "Chicago, IL",
  "salaryMin": 66500,
  "salaryMedian": 76558,
  "salaryMax": 86616,
  "salaryPeriod": "ANNUAL",
  "salaryCurrency": "USD",
  "salarySource": "EMPLOYER_PROVIDED",
  "salaryText": "$66,500 – $86,616 per year (employer provided)",
  "postedDate": "2026-09-19",
  "ageInDays": 5,
  "easyApply": false,
  "url": "https://www.glassdoor.com/job-listing/analyst-people-analytics-hybrid-united-airlines-JV_IC1128808_KO0,31_KE32,47.htm?jl=1010267244215",
  "normalizedTitle": "hr analyst",
  "companyId": 683,
  "companyLegalName": "UAL Corporation",
  "companyUrl": "https://www.glassdoor.com/Overview/W-EI_IE683.htm",
  "skills": ["Process improvement", "SQL", "Analysis skills", "Requirements analysis", "Forecasting", "Business requirements", "Python", "Workday"],
  "jobTypes": ["Full-time"],
  "workSetting": [],
  "seniority": ["Mid-level"],
  "benefits": ["Paid holidays", "Disability insurance", "Health insurance", "Dental insurance", "401(k)", "Paid time off", "Parental leave", "Employee assistance program", "Vision insurance", "Bonus opportunities"],
  "searchKeyword": "data analyst",
  "searchLocation": "Chicago",
  "scrapedAt": "2026-09-24T12:00:00.000Z"
}
```

### How to use it

1. Type a **job title** (e.g. `data analyst`) and a **location** (e.g. `Toronto`, `Chicago, IL`, `Ontario`, `London, England`, `Canada`, `Remote`).
2. Set **Max jobs per search**.
3. Optionally add filters and more job titles / locations — every job title is searched in every location.
4. Run. Download as JSON, CSV, Excel, or use the API.

You can also paste **Glassdoor URLs**: a search results page (its filters are kept) or individual job links (`…?jl=1010267244215`).

#### Input example

```json
{
  "keywords": "software engineer",
  "location": "Toronto",
  "additionalLocations": ["Vancouver", "Montreal"],
  "limit": 500,
  "daysOld": 7,
  "remoteWorkType": false,
  "minRating": 3.5,
  "includeDetails": true
}
```

#### Filters

| Input | What it does |
|---|---|
| `daysOld` | Posted within N days (1 = last 24 hours) |
| `easyApply` | Only Easy Apply jobs |
| `remoteWorkType` | Only remote jobs |
| `minRating` | Minimum company rating — decimals like 3.8 work |
| `radius` | Distance around a city |
| `employerSizes` | Company size bracket (1 = 1–200 … 5 = 5,001+) |
| `jobType` | Full-time, part-time, contract, temporary, internship, permanent… |
| `seniority` | Internship, entry level, mid-senior, director, executive |
| `minSalary` / `maxSalary` | Yearly pay range |
| `industry`, `jobCategory` | Glassdoor industry / job function |
| `sortBy` | Most relevant, or most recent first |
| `excludeJobIds` | Skip jobs you already have (incremental runs) |
| `urlParam` | Any other Glassdoor search filter as key/value |

**Switching from another Glassdoor jobs actor?** The inputs `keywords`, `location`, `daysOld`, `easyApply`, `remoteWorkType`, `minRating`, `radius`, `employerSizes`, `sortBy`, `limit`, `urlParam` and `excludeJobIds` work the same way, so your existing input keeps working.

### Use cases

- **Salary benchmarking** — employer-provided vs. estimated pay bands by title, city and company.
- **Skills demand** — which tools and certifications employers ask for, per role and market.
- **Job boards & alerts** — fresh listings with `daysOld: 1` and `excludeJobIds` for daily incremental runs.
- **Recruiting & sales leads** — who is hiring, how big they are, their rating and headquarters.
- **Labour-market research** — Canada, UK and US side by side, with local currency preserved.
- **AI / LLM pipelines** — clean `descriptionText` plus structured attributes.

### FAQ

**What happens when Glassdoor is slow, down or blocks the request?**
The run still finishes successfully with every job it managed to collect, and the status message
says exactly what happened ("Partial — stopped at the run time limit: 1,240 jobs saved", "Glassdoor
blocked every request this run — 0 jobs, no charge", …). Blocked requests rotate to a fresh IP,
escalate to residential proxies and finally fall back to Glassdoor's own search page; a job is
only ever charged once it has been written to your dataset. A `RUN_REPORT` record in the run's
key-value store has the per-search breakdown.

**Do I have to use your input names?**
No — `query` / `keyword` / `jobTitle`, `city`, `maxResults` / `resultsLimit`, `urls`, `fetchDetails`
and other common names from similar scrapers are accepted as aliases.

**How many jobs can I get per search?**
Thousands. The scraper keeps asking Glassdoor for jobs it hasn't seen yet instead of stopping at the page limit you hit on the website, and very large searches are split automatically. Glassdoor's "total matches" count is an estimate — the number you can actually collect can be lower for narrow searches.

**My location matched the wrong place.**
The run log shows exactly which Glassdoor location each name matched (📍 lines). A bare name follows Glassdoor's own suggestions — "Toronto" is Toronto, ON; a state or province wins over a same-named city ("Ontario" is the province). Add the region to be specific ("London, ON", "Ontario, CA", "Portland, ME"), or set the exact `locationId` + `locationType` from a Glassdoor URL.

**Which countries work?**
Any country Glassdoor lists jobs for. Salaries keep their local currency (USD, CAD, GBP, EUR, INR…).

**Is the salary real?**
`salarySource` tells you: `EMPLOYER_PROVIDED` means the employer published it; `ESTIMATED` is Glassdoor's estimate for that role. Hourly jobs have `salaryPeriod: HOURLY`.

**What is `applyUrl`?**
Glassdoor's apply link for the job. Opened in a browser it takes you to the employer's application (or Glassdoor's Easy Apply).

**"Most recent first" isn't strictly sorted — why?**
Newest jobs are collected first in posting-age groups (last 24 hours, 3 days, week, 2 weeks, month, older). Within a group, jobs are in Glassdoor's relevance order. Use `postedDate` / `ageInDays` to sort exactly.

**Do I need a proxy?**
Apify Proxy is used automatically (datacenter by default, residential only if needed). You don't need to configure anything.

**How is it priced?**
Per job saved. The full description + company profile is an optional add-on charged per job that actually received a description. Duplicates across your searches are removed before saving, so you never pay twice for the same job.

**Is it legal to scrape Glassdoor?**
This actor only collects publicly available data: the job listings, salary ranges, company ratings and company profiles that Glassdoor shows to anyone without an account. It doesn't log in and doesn't touch anything behind a login. Collecting publicly available data is generally legal, but you're responsible for how you use it. Job listings describe roles, not people, but some fields can still be personal data: the company profile includes the CEO's name, and a job description written by the employer can occasionally mention a recruiter or hiring manager by name or email. If you store or reuse that kind of data, follow the data protection laws that apply to you (such as GDPR, PIPEDA or CCPA) and Glassdoor's terms. If you're unsure whether your use case is legitimate, check with a lawyer. You can read more in Apify's article [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

**Does it access any private data?**
No. Everything comes from what Glassdoor shows to any visitor without logging in. It never uses a login or anyone's account, never collects individual employee reviews or reviewer profiles (only the company's overall ratings that appear with its jobs), and never reaches password-protected areas.

# Actor input Schema

## `keywords` (type: `string`):

Job title, skill or company to search for, e.g. "data analyst" or "registered nurse". Leave empty to get every job in the location.

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

City, state/province or country — e.g. "Toronto", "Chicago, IL", "Ontario", "London, England", "Canada", "Remote". Leave empty for the whole United States.

## `limit` (type: `integer`):

How many jobs to collect for each keyword + location combination. Large numbers work (thousands per search).

## `additionalKeywords` (type: `array`):

Extra job titles / keywords. Every keyword is searched in every location.

## `additionalLocations` (type: `array`):

Extra locations. Every keyword is searched in every location.

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

Paste Glassdoor job-search URLs (filters in the URL are kept) and/or individual job URLs (…?jl=1010267244215). Works with glassdoor.com, .ca, .co.uk and other country sites.

## `includeDetails` (type: `boolean`):

Also fetch each job's full description (HTML and plain text), the date Glassdoor indexed it, map coordinates, and the company profile: size, revenue, headquarters, website, founded year, industry, sector, CEO, stock ticker, competitors and all Glassdoor sub-ratings (culture, work-life balance, compensation…).

## `includeAttributes` (type: `boolean`):

Include the skills, benefits, job types, work setting (remote/hybrid/in-person), seniority, schedule, education, experience, licenses and requirements Glassdoor extracts from each posting. Turn off for smaller rows.

## `daysOld` (type: `integer`):

Only jobs posted within this many days, e.g. 1 = last 24 hours, 7 = last week.

## `easyApply` (type: `boolean`):

Only jobs you can apply to directly on Glassdoor.

## `remoteWorkType` (type: `boolean`):

Only remote / work-from-home jobs.

## `minRating` (type: `number`):

Only companies rated at least this high on Glassdoor (0–5, decimals like 3.8 work).

## `radius` (type: `string`):

Search radius around a city (miles on US sites, kilometres on most others).

## `employerSizes` (type: `string`):

Filter by number of employees.

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

Filter by employment type.

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

Filter by seniority level.

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

Only jobs paying at least this much per year (in the local currency).

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

Only jobs paying at most this much per year (in the local currency).

## `industry` (type: `string`):

Only jobs at companies in this industry.

## `jobCategory` (type: `string`):

Only jobs in this function / department.

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

Most relevant (Glassdoor's ranking) or most recent first (newest jobs are collected first, grouped by posting age: last 24h, 3 days, week, 2 weeks, month, older).

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

Stop the whole run after this many jobs (across all searches). Leave empty for no overall cap.

## `excludeJobIds` (type: `array`):

Job IDs to skip — handy for incremental runs (feed in the jobId values you already have).

## `urlParam` (type: `array`):

Any other Glassdoor search filter as key/value, e.g. industryNId = 10013, cityId = 1128825, jobTypeIndeed = CF3CP.

## `locationId` (type: `integer`):

Optional: use an exact Glassdoor location ID instead of looking up the location name (the number after IC/IS/IN in a Glassdoor URL, e.g. 2281069 for Toronto).

## `locationType` (type: `string`):

Type of the location ID above.

## `splitLargeSearches` (type: `boolean`):

When a single search asks for more than ~5,000 jobs, automatically split it by company size, seniority and job function to keep finding new jobs.

## `maxConcurrency` (type: `integer`):

How many requests run at once. The default is fast and safe.

## `proxyConfiguration` (type: `object`):

Apify Proxy is required. The default (datacenter) is fast and cheap; the actor switches to residential proxies automatically if it gets blocked.

## Actor input object example

```json
{
  "keywords": "data analyst",
  "location": "Toronto",
  "limit": 30,
  "includeDetails": false,
  "includeAttributes": true,
  "sortBy": "relevant_desc",
  "splitLargeSearches": true,
  "maxConcurrency": 8,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

All scraped job listings.

## `run` (type: `string`):

Status and statistics for this run.

# 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": "Toronto",
    "limit": 30,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("yugenox/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": "data analyst",
    "location": "Toronto",
    "limit": 30,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("yugenox/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": "data analyst",
  "location": "Toronto",
  "limit": 30,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call yugenox/glassdoor-jobs-scraper --silent --output-dataset

```

## MCP server setup

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