# Glassdoor Salary Scraper — Pay Data & Percentiles (`axlymxp/glassdoor-salary-scraper`) Actor

Scrape Glassdoor salary estimates — base + total pay percentiles (P10–P90) per employer, by job title or keyword, filtered by location, company and experience. Reliable mobile-API backend, no anti-bot. Pay only for the results you get.

- **URL**: https://apify.com/axlymxp/glassdoor-salary-scraper.md
- **Developed by:** [axly](https://apify.com/axlymxp) (community)
- **Categories:** Jobs, Business
- **Stats:** 2 total users, 1 monthly users, 85.7% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $6.00 / 1,000 dataset items

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?

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 Salary Scraper

Extract **Glassdoor salary estimates at scale** as clean, flat JSON — base and
total-pay percentiles (P10–P90), additional pay, currency and company ratings —
for any job title or keyword, filtered by location, employer and years of
experience.

Built on Glassdoor's **mobile API**, which is anonymous and has no anti-bot wall,
so runs are reliable and don't break when Glassdoor rotates its web protection.

### Who it's for

- **Compensation & HR analysts** — build pay bands by title, company, location and
  experience; calibrate offers and salary ranges against the market.
- **Recruiters & talent-market intelligence** — benchmark competitor pay to win
  candidates.
- **PropTech / HR-SaaS developers** — a stable, documented salary schema to power
  compensation features, webhooks and dashboards.
- **Researchers & economists** — labor-market pay distributions across employers
  and geographies.

### What you get — output fields

| Field | Type | Description |
| ----- | ---- | ----------- |
| `query` / `query_type` | string | The title/keyword searched and how it was matched |
| `location_name` | string | Location scope (null = US nationwide) |
| `company_id` / `company_name` | int / string | Glassdoor employer id + name |
| `company_rating` | number | Employer overall rating (1–5) |
| `company_global_job_count` | int | Open jobs for this employer |
| `job_title` / `job_title_id` / `goc_id` | string / int | Normalized title + Glassdoor ids |
| `pay_period` / `currency` | string | e.g. ANNUAL / USD |
| `base_pay_mean` | number | Mean base pay (keyword mode) |
| `base_pay_median` / `_p10` / `_p25` / `_p75` / `_p90` | number | Base-pay percentiles (title mode) |
| `total_pay_median` / `_p10` / `_p25` / `_p75` / `_p90` | number | Total pay (base + bonus/stock) percentiles |
| `additional_pay_mean` | number | Mean additional pay (bonus, stock, tips) |
| `confidence` | string | Glassdoor confidence level, when provided |
| `scraped_at` | string | UTC ISO-8601 timestamp |

### High-value use cases

1. **Salary benchmarking** — pull "Software Engineer" across the top 200 employers
   in a metro to build a percentile pay band in minutes.
2. **Offer calibration** — compare a candidate's target title + experience band
   against real market P25/P50/P75.
3. **Competitive pay intelligence** — track how a rival's pay for a role compares
   to yours over time.
4. **Product data** — feed a compensation dashboard or "salary insights" feature
   with a stable JSON schema.
5. **Labor-market research** — distributions of pay by occupation cluster (`goc_id`)
   and geography.

### Input parameters

| Field | Type | Default | Description |
| ----- | ---- | ------- | ----------- |
| `queries` | array<string> | `["Software Engineer"]` | Job titles or keywords; each paginated separately |
| `searchBy` | enum | `title` | `title` (exact match) or `keyword` (broad) |
| `location` | string | — | Place name, e.g. "San Francisco"; empty = US nationwide |
| `locationType` | enum | `city` | `city` / `state` / `country` |
| `company` | string | — | Restrict to one employer by name |
| `yearsOfExperience` | enum | — | `LESS_THAN_ONE`, `ONE_TO_THREE`, `FOUR_TO_SIX`, `SEVEN_TO_NINE`, `TEN_TO_FOURTEEN` |
| `maxResultsPerQuery` | integer | 200 | Cap salary rows per query |

### Example input

```json
{
  "queries": ["Software Engineer", "Product Manager"],
  "searchBy": "title",
  "location": "San Francisco",
  "locationType": "city",
  "maxResultsPerQuery": 200
}
```

### Example output row

```json
{
  "query": "Software Engineer",
  "query_type": "title",
  "location_name": "San Francisco",
  "company_id": 575263,
  "company_name": "Uber",
  "company_rating": 3.7,
  "job_title": "Software Engineer",
  "pay_period": "ANNUAL",
  "currency": "USD",
  "base_pay_mean": 177373.92,
  "total_pay_median": 286865.03,
  "total_pay_p10": 205654.54,
  "total_pay_p90": 421695.31,
  "additional_pay_mean": 109491.11,
  "scraped_at": "2026-09-09T02:33:34Z"
}
```

### Scheduling & integrations

- **Schedule** runs (daily/weekly) from the Apify Console to keep pay bands fresh.
- **Webhooks** fire on run completion — push new rows to your app, Make or Zapier.
- **Export** to JSON, CSV, Excel or Google Sheets, or pull from the dataset API.

### Use with AI assistants (MCP)

Apify Actors are callable from AI assistants via the Model Context Protocol, so an
agent can fetch live salary benchmarks on demand (e.g. "get median total pay for a
Senior Data Scientist at the top 20 employers in New York"). Point your MCP client
at this Actor and pass the same input schema.

### FAQ

**How many salary rows can I get?** Each title returns up to ~100k rows (one per
employer/title estimate); set `maxResultsPerQuery` to cap it. `numPages` in the
API bounds the real total.

**How fresh is the data?** Live — every run queries Glassdoor's current salary
estimates at request time.

**Keyword vs title mode?** `title` matches an exact Glassdoor job title and reports
base-pay percentiles; `keyword` is a broader match and reports mean base pay. Both
return full total-pay percentiles.

**Do I need a proxy?** Yes — use **Residential** proxy (the default). Glassdoor's
mobile API serves residential IPs only and blocks datacenter IPs, so runs without
residential proxy return no data. No login or credentials are needed.

**Is scraping this legal?** You are responsible for your use. The Actor collects
only publicly available, aggregate salary estimates (no personal data) and is
intended for market research and analytics; comply with Glassdoor's terms and
applicable law.

**Reliability?** The mobile API is a stable JSON/GraphQL backend with no Cloudflare
JS challenge, so this Actor does not break on web anti-bot rotations; transient
network errors are retried automatically. It does require Residential proxy (the
default) because the API blocks datacenter IPs.

# Actor input Schema

## `queries` (type: `array`):

One or more job titles (e.g. "Software Engineer") or keywords to pull salary estimates for. Each is searched and paginated separately.

## `searchBy` (type: `string`):

"title" matches an exact Glassdoor job title (cleaner grouping); "keyword" is a broader free-text match.

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

Optional place name to scope salaries, e.g. "San Francisco", "California" or "United States". Leave empty for nationwide (US).

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

How to interpret the location name.

## `company` (type: `string`):

Restrict salaries to a single employer by name, e.g. "Google". Resolved automatically to a Glassdoor employer id.

## `yearsOfExperience` (type: `string`):

Filter salaries by an experience band.

## `maxResultsPerQuery` (type: `integer`):

Stop after this many salary rows per job title/keyword. Each row is one employer's pay estimate for that title.

## `pageSize` (type: `integer`):

Salary rows fetched per API request (max 20).

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

Proxy used to reach Glassdoor. Glassdoor's mobile API blocks datacenter IPs, so RESIDENTIAL proxy is required — keep the default. Runs from unproxied datacenter IPs return no data.

## Actor input object example

```json
{
  "queries": [
    "Software Engineer",
    "Product Manager"
  ],
  "searchBy": "title",
  "location": "San Francisco",
  "locationType": "city",
  "company": "Google",
  "yearsOfExperience": "",
  "maxResultsPerQuery": 200,
  "pageSize": 20,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `salaries` (type: `string`):

All scraped salary rows 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 = {
    "queries": [
        "Software Engineer"
    ],
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axlymxp/glassdoor-salary-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "queries": ["Software Engineer"],
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("axlymxp/glassdoor-salary-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "queries": [
    "Software Engineer"
  ],
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call axlymxp/glassdoor-salary-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,axlymxp/glassdoor-salary-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/kpRwCWRRuPVdQW40N/builds/BfIue8mE1WdKFM388/openapi.json
