# Glassdoor Jobs Scraper API - Salaries, Ratings & Locations (`scrapifier/glassdoor-jobs-scraper`) Actor

💼 Scrape Glassdoor job listings by keyword + location or by URL. Get title, company + rating, location, salary estimate, posted date, easy-apply, job type & description snippet — clean structured data. No login and no proxy needed.

- **URL**: https://apify.com/scrapifier/glassdoor-jobs-scraper.md
- **Developed by:** [Scrapifier](https://apify.com/scrapifier) (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 $0.41 / 1,000 results

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 API - Salaries, Ratings & Locations

Scrape job listings from Glassdoor by keyword and location, or from any Glassdoor jobs-search URL, and export them as JSON, CSV or Excel, or pull them straight from the API.

⚡ For every job you get the **title**, the hiring **company and its Glassdoor rating**, the **location**, the **salary estimate** (low, median, high, currency and period), the posted date and age in days, the easy-apply flag, sponsored flag, job category, job attributes (contract type, education level) and a short description with the direct link. Works on **any Glassdoor country site**, with **no login, no cookies and no proxy**. Date, job type, remote and minimum-rating filters are **applied server-side by Glassdoor** before you pay for a single result. You **pay per job**.

[![Apify Actor](https://apify.com/actor-badge?actor=scrapifier/glassdoor-jobs-scraper)](https://apify.com/scrapifier/glassdoor-jobs-scraper)

### 🎯 Why scrape Glassdoor jobs?

- **Job market research**: count openings for a role in a city or country, watch how they evolve week after week and spot which employers are hiring most.
- **Salary benchmarking**: Glassdoor attaches a salary estimate (low, median, high) to most listings, so you can compare pay for the same title across companies, regions or contract types.
- **Lead generation**: a company that posts several data engineer roles is buying tooling, training and consulting. Build lists of hiring companies with their Glassdoor rating attached.
- **Recruiting and sourcing**: monitor competitors' openings, their job types and how long they stay online (`ageInDays`) to gauge how hard a role is to fill.
- **Job boards and aggregators**: feed fresh listings, filtered by date posted or remote work, into your own board or newsletter.

### 📊 What data does Glassdoor Jobs Scraper extract?

| Field | Description |
|---|---|
| `jobId` | Glassdoor job listing id |
| `title` | Job title as displayed |
| `url` | Direct link to the job on Glassdoor |
| `company`, `companyId` | Hiring company and its Glassdoor employer id |
| `companyRating` | Company overall rating (1 to 5) |
| `location` | Job location |
| `salary` | Salary as shown on Glassdoor (for example `45 k€ - 60 k€ (Glassdoor est.)`) |
| `salaryMin`, `salaryMedian`, `salaryMax` | Estimated salary low (P10), median (P50) and high (P90) |
| `salaryCurrency`, `salaryPeriod` | Currency and period (`ANNUAL`, `MONTHLY`, `HOURLY`) |
| `postedAge`, `ageInDays` | Posted age as shown (`15j`, `30j+`) and the number of days since posting |
| `descriptionSnippet` | Short description snippet |
| `easyApply` | `true` when the job accepts Glassdoor easy-apply |
| `isSponsored` | `true` for sponsored or promoted listings |
| `jobCategory` | Normalized job family / occupation |
| `normalizedTitle` | Glassdoor's normalized job title |
| `attributes[]` | Job attributes (contract type, education level, ...) |
| `sourceUrl` | The Glassdoor search this job came from |

With `flatten` enabled, an `attributesText` column joins the attributes into one string so the CSV or Excel export stays flat.

### 🚀 How to scrape Glassdoor jobs

1. Open the Actor and type a **job keyword** in `keyword` (for example `data engineer`) and a **location** in `location` (for example `France`), then pick the Glassdoor domain to search in `country`. Or paste one or more Glassdoor jobs-search URLs (the page you land on after searching on Glassdoor, any country site) in `startUrls`. You can do both in the same run.
2. Set **Max jobs per search** (`maxJobs`). Broad searches return thousands of listings, so keep a cap for a first run.
3. Optionally narrow the search with **Posted within (days)**, **Job type**, **Remote jobs only** and **Minimum company rating**.
4. Click **Start**. The Actor collects the jobs and clicks Glassdoor's own "load more" button until your cap is reached.
5. Open the **Storage** tab to preview the jobs and export them as JSON, CSV, Excel or XML, or read them from the dataset API.

The same run can be started from the Apify API, the Python or JavaScript client, or put on a schedule to collect new listings every day.

### 📥 Input parameters

| Field | Key | Type | Default | Description |
|---|---|---|---|---|
| Job keyword / title | `keyword` | string | `data engineer` | What to search for (`data engineer`, `product manager`, `nurse`). Combine with a location. |
| Location | `location` | string | `France` | City, region or country (`Paris`, `London`, `United States`). Empty = everywhere. |
| Glassdoor jobs URLs | `startUrls` | array of URLs | none | One or more Glassdoor jobs-search URLs, from any Glassdoor country domain. Leave empty to use keyword and location. |
| Glassdoor domain | `country` | select | `www` | Domain searched for keyword and location: `www` (glassdoor.com), `co.uk`, `ca`, `com.au`, `co.in`, `ie`, `de`, `fr`, `es`, `it` or `nl`. Pasted URLs keep their own domain. |
| Login cookies (optional) | `sessionCookies` | array (JSON) | none | Optional browser-exported Glassdoor cookies to run as your signed-in account. Leave empty: you still get the full data. |
| Max jobs per search | `maxJobs` | integer | `100` | Jobs to collect per search. `0` = as many as Glassdoor exposes. |
| Posted within (days) | `datePosted` | integer | none | Only jobs posted within the last N days (`1`, `3`, `7`, `14`, `30`). Empty = any time. |
| Job type | `jobType` | select | ``(Any) | `fulltime`, `parttime`, `contract`, `internship`, `temporary` or `apprenticeship`. |
| Remote jobs only | `remoteOnly` | boolean | `false` | Keep only remote-friendly jobs. |
| Minimum company rating | `minRating` | select |`` (Any) | `3.0`, `3.5` or `4.0`: only jobs at companies rated at least this on Glassdoor. |
| Flat columns (CSV-friendly) | `flatten` | boolean | `false` | Add a flat `attributesText` column for CSV and Excel. |
| Report empty searches | `emitInputStatus` | boolean | `true` | Add an `input_status` report to the run's OUTPUT record. |
| Max 'load more' clicks | `maxLoadMoreClicks` | integer | `60` | Safety cap on how far the Actor pages through results (each click loads about 30 more jobs). |
| Page load retries | `maxChallengeRetries` | integer | `8` | Retries when a page fails to load. Increase only if runs report being blocked. |
| Proxy | `proxyConfiguration` | object | off | Leave off. A proxy usually makes Glassdoor runs fail; only add one if you have your own clean, ISP-grade IPs. |

Example input:

```json
{
  "keyword": "product manager",
  "location": "London",
  "country": "co.uk",
  "jobType": "fulltime",
  "datePosted": 7,
  "minRating": "4.0",
  "maxJobs": 200
}
```

A jobs-search URL looks like `https://www.glassdoor.com/Job/jobs.htm?sc.keyword=data%20engineer&locKeyword=France`: run the search on Glassdoor, apply your filters there, and paste the address bar into `startUrls`. `minRating` and `jobType` are strings, exactly as listed above (`"4.0"`, not `4`), and `maxJobs` applies to each search separately.

### 📤 Output example

Each job is one dataset item, exportable as JSON, CSV, Excel or via the API.

```json
{
  "jobId": "1010191089012",
  "title": "Data Engineer",
  "url": "https://www.glassdoor.com/job-listing/...?jl=1010191089012",
  "company": "Sartorius",
  "companyRating": 3.5,
  "location": "Paris",
  "salary": "45 k€ - 60 k€ (Glassdoor est.)",
  "salaryMin": 45000,
  "salaryMedian": 52000,
  "salaryMax": 60000,
  "salaryCurrency": "EUR",
  "postedAge": "3j",
  "ageInDays": 3,
  "descriptionSnippet": "We are looking for a Data Engineer to…",
  "easyApply": false,
  "isSponsored": false,
  "jobCategory": "development engineer",
  "attributes": ["Full-time", "Master"]
}
```

The run's OUTPUT record also holds the run statistics (searches, unique jobs, duplicates ignored, load-more clicks, errors) and, per search, an `input_status` entry (`ok`, `empty` or `blocked_or_empty`) so you can see at a glance which input produced nothing.

### 💡 Ready-to-run examples

**Full-time product manager jobs in London, posted this week, at companies rated 4.0+**

```json
{ "keyword": "product manager", "location": "London", "country": "co.uk", "jobType": "fulltime", "datePosted": 7, "minRating": "4.0", "maxJobs": 200 }
```

**Data engineer jobs anywhere in France (the default search)**

```json
{ "keyword": "data engineer", "location": "France", "country": "www", "maxJobs": 100 }
```

**Remote data engineer jobs posted in the last 3 days**

```json
{ "keyword": "data engineer", "location": "France", "remoteOnly": true, "datePosted": 3, "maxJobs": 100 }
```

**A Glassdoor search URL, flattened for Excel**

```json
{ "startUrls": [{ "url": "https://www.glassdoor.com/Job/jobs.htm?sc.keyword=data%20engineer&locKeyword=France" }], "maxJobs": 300, "flatten": true }
```

### 💰 Pricing: how much does it cost to scrape Glassdoor jobs?

From **$0.60 per 1,000 jobs** on the free plan, with automatic volume discounts down to **$0.41 per 1,000** on higher Apify plans. You pay only for the results you receive, there is no subscription and no start fee. New Apify accounts get free monthly platform credits to try it.

Cost is driven purely by the number of jobs returned: use `maxJobs` to cap each search, and `datePosted`, `jobType`, `remoteOnly` or `minRating` to let Glassdoor narrow the result set before you pay for it.

### ⚙️ Performance, proxies and limits

- **No proxy needed, and not recommended.** Glassdoor runs work best without a proxy. A proxy usually makes runs fail; add one only if you have your own clean, ISP-grade IPs.
- **Speed**: the Actor paginates with the site's own "load more" button (about 30 jobs per click) and pushes results in batches of 100.
- **Memory**: the run defaults to 4 GB.
- **Volume**: `0` in `maxJobs` collects everything Glassdoor exposes for that search, bounded by `maxLoadMoreClicks` (default `60`). Split very broad searches by location or job type to reach more listings.
- **Filters are server-side**: date posted, job type, remote only and minimum rating are passed to Glassdoor in the search URL, so filtered jobs are never fetched or billed.
- **Salaries**: `salary` is Glassdoor's estimate when the employer does not publish one; the low, median and high values are Glassdoor's P10, P50 and P90.
- **Deduplication**: jobs are deduplicated by `jobId` within each search; the OUTPUT record reports how many duplicates were ignored.
- **Empty or blocked searches**: a search that returns nothing is logged as `empty` or `blocked_or_empty` in `input_status`. Retry later or raise `maxChallengeRetries` if runs report being blocked.
- **Logged-in mode**: pasting `sessionCookies` makes the run match exactly what you see when signed in. Use the same `country` as the cookies' domain, and re-export them when they expire.

### 🔌 Integrations and API

Run Glassdoor Jobs Scraper from the [Apify API](https://docs.apify.com/api/v2), the [Python](https://docs.apify.com/api/client/python) or [JavaScript](https://docs.apify.com/api/client/js) client, or on a [schedule](https://docs.apify.com/platform/schedules). Connect it to Make, Zapier, n8n, Google Sheets, Slack or any webhook through [Apify integrations](https://apify.com/integrations). Every run's dataset is available as JSON, CSV, Excel or XML from the dataset API.

```bash
curl -X POST "https://api.apify.com/v2/acts/scrapifier~glassdoor-jobs-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{ "keyword": "product manager", "location": "London", "country": "co.uk", "jobType": "fulltime", "datePosted": 7, "maxJobs": 200 }'
```

### ❓ FAQ

**Is it legal to scrape Glassdoor jobs?**

The Actor only reads job listings that Glassdoor shows to anyone without logging in. Listings are business data, but treat any personal data you come across in line with GDPR and other privacy laws, respect Glassdoor's terms of use, and stay responsible for how you use the data. This is not legal advice.

**Do I need a Glassdoor account, login or cookies?**

No. The Actor gets the full data anonymously: company names, ratings, salary estimates and descriptions. `sessionCookies` is an optional extra for users who want results as their signed-in account; export them with a browser extension such as Cookie-Editor (Export as JSON) and paste the array.

**Can I export Glassdoor jobs to Excel or Google Sheets?**

Yes. Every run's dataset downloads as CSV, XLSX, JSON or XML from the Storage tab, and the Google Sheets integration can push new jobs to a sheet automatically. Turn on `flatten` for a clean single-row-per-job spreadsheet.

**How many jobs can I scrape per search?**

As many as Glassdoor exposes for that search (set `maxJobs` to `0`), within the `maxLoadMoreClicks` cap. Most users cap each run and add `datePosted` to fetch only new listings on a daily schedule.

**Does it work on Glassdoor country sites other than glassdoor.com?**

Yes. Pick the domain in `country` for keyword searches (glassdoor.com, .co.uk, .ca, .com.au, .co.in, .ie, .de, .fr, .es, .it, .nl), or paste a search URL from any Glassdoor country domain in `startUrls`; pasted URLs keep their own domain.

**Are the salaries real or estimates?**

Both. `salary` reproduces what Glassdoor displays: the employer's figure when published, Glassdoor's estimate otherwise (marked `Glassdoor est.`). `salaryMin`, `salaryMedian` and `salaryMax` are the estimated P10, P50 and P90.

**Can I use my own Glassdoor search with its filters?**

Yes. Run the search on Glassdoor, apply any filter the site offers, and paste the resulting URL into `startUrls`. The Actor keeps the URL as is and records it in `sourceUrl` on every job.

**What if a run reports being blocked or returns 0 jobs?**

Check `input_status` in the OUTPUT record: `empty` means Glassdoor had no jobs for that search, `blocked_or_empty` means the page never rendered job cards. Make sure no proxy is configured, retry later, or raise `maxChallengeRetries`.

### 🔗 Related scrapers

- [Glassdoor Salaries Scraper](https://apify.com/scrapifier/glassdoor-salaries-scraper): salary estimates per job title and company.
- [Glassdoor Company Overview Scraper](https://apify.com/scrapifier/glassdoor-company-scraper): the full company profile (ratings, CEO approval, size, HQ, revenue) by name or URL.
- [Glassdoor Company Search Scraper](https://apify.com/scrapifier/glassdoor-company-search-scraper): find companies by location, industry, minimum rating and size.
- [Glassdoor Reviews Scraper](https://apify.com/scrapifier/glassdoor-reviews-scraper): employee reviews with ratings, pros, cons and company responses.
- [Glassdoor Interviews Scraper](https://apify.com/scrapifier/glassdoor-interviews-scraper): interview experiences and the questions asked, by company.
- [Welcome to the Jungle Jobs Scraper](https://apify.com/scrapifier/welcome-to-the-jungle-scraper): jobs and company profiles, France and Europe.

### 💬 Support

Questions, bugs or a feature request? Open an issue in the **Issues** tab of this Actor, I answer quickly. If Glassdoor Jobs Scraper saves you time, a rating on the Store helps others find it.

# Actor input Schema

## `keyword` (type: `string`):

What to search for (e.g. "data engineer", "product manager", "nurse"). Combine with a location below.

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

City, region or country (e.g. "Paris", "London", "United States"). Empty = everywhere.

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

Paste one or more Glassdoor jobs-search URLs (the page you get after searching on Glassdoor). Works on any Glassdoor country domain. Leave empty to use keyword + location above.

## `country` (type: `string`):

Which Glassdoor domain to search when using keyword + location. (Pasted URLs keep their own domain.)

## `sessionCookies` (type: `array`):

Optional. Paste your Glassdoor login cookies to run as a logged-in user (matches exactly what you see when signed in). How to get them: log in to Glassdoor in your browser, then export the cookies with a free extension like 'Cookie-Editor' or 'EditThisCookie' (use its 'Export' → JSON), and paste the JSON array here. Leave empty to run without logging in, you still get the full data. Via the API you can also pass one 'name=value; name2=value2' string.

## `maxJobs` (type: `integer`):

How many jobs to collect per search (0 = as many as Glassdoor exposes).

## `datePosted` (type: `integer`):

Only jobs posted within the last N days (e.g. 1, 3, 7, 14, 30). Empty = any time.

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

Employment type.

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

Only remote-friendly jobs.

## `minRating` (type: `string`):

Only jobs at companies rated at least this on Glassdoor.

## `flatten` (type: `boolean`):

Add a flat attributesText column for CSV/Excel.

## `emitInputStatus` (type: `boolean`):

Add an input_status report to the run's OUTPUT record.

## `maxLoadMoreClicks` (type: `integer`):

Safety cap on how far the Actor pages through results (each step loads ~30 more jobs).

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

How many retry attempts if a page fails to load. Increase only if runs report being blocked.

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

Glassdoor answers datacenter addresses with a block page — measured: datacenter 403, residential 200 on the same request. Keep this on residential.

## Actor input object example

```json
{
  "keyword": "data engineer",
  "location": "France",
  "country": "www",
  "maxJobs": 100,
  "jobType": "",
  "remoteOnly": false,
  "minRating": "",
  "flatten": false,
  "emitInputStatus": true,
  "maxLoadMoreClicks": 60,
  "maxChallengeRetries": 8,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}
```

# Actor output Schema

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

All Glassdoor jobs extracted by 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 = {
    "keyword": "data engineer",
    "location": "France",
    "maxJobs": 100,
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ],
        "apifyProxyCountry": "US"
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapifier/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 = {
    "keyword": "data engineer",
    "location": "France",
    "maxJobs": 100,
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
        "apifyProxyCountry": "US",
    },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapifier/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 '{
  "keyword": "data engineer",
  "location": "France",
  "maxJobs": 100,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ],
    "apifyProxyCountry": "US"
  }
}' |
apify call scrapifier/glassdoor-jobs-scraper --silent --output-dataset

```

## MCP server setup

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