# ⚡Glassdoor Jobs Scraper (`silo/glassdoor-jobs-scraper`) Actor

Introducing the Glassdoor Jobs Scraper for Apify! This cutting-edge tool simplifies job listing extraction from Glassdoor. Ideal for job seekers, recruiters, and market analysts, it provides extensive customization to meet diverse job-hunting and research requirements effortlessly.

- **URL**: https://apify.com/silo/glassdoor-jobs-scraper.md
- **Developed by:** [Silo](https://apify.com/silo) (community)
- **Categories:** Lead generation, Jobs, Open source
- **Features:** Limited permissions
- **Stats:** 269 total users, 2 monthly users, 96.3% runs succeeded, 8 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $0.80 / 1,000 job listings

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

**Glassdoor job listings with pay, company ratings and apply links.**

Give it a keyword and a place, and get back every matching Glassdoor job as a
flat row: title, company, location, pay range, company rating, posting age and
apply link.

A default run collects up to 1,000 jobs, well under a minute of requests.

### What you can do with it

- **Track hiring**: which companies are hiring for a role, where, and how fast
  (`age_in_days`).
- **Benchmark pay**: employer-stated salary ranges, annual or hourly, by role and
  location.
- **Screen employers**: the company's Glassdoor rating next to each job, and a
  minimum-rating filter.
- **Feed a job board or a model**: flat rows with stable ids, ready for a
  spreadsheet, a database or a dataframe.

### Why this one

**Filters that Glassdoor applies.** Date posted, remote only, Easy Apply only,
minimum rating, radius, job type, seniority, salary range, company size,
industry, department and a single company. Glassdoor applies them to the search
itself, so a narrower search is faster and cheaper, and the results match what
you would see on the site.

**Pay you can compare.** Every pay range comes with `pay_type` (`ANNUAL` or
`HOURLY`) and `pay_source`. `pay_source` says whether the employer stated the
range or Glassdoor estimated it.

**Flat rows.** No nested objects to unpack.

**Public data only.** The actor sees what a signed-out visitor to Glassdoor
sees. It never signs in.

### Input

| Field | Default | What it does |
| --- | --- | --- |
| **Keyword** | required | A job title, skill or company, e.g. `software engineer`, `nurse`, `Google`. |
| **Location** | United States | A city, state or country as you would type it on Glassdoor. |
| **Glassdoor site** | glassdoor.com | Which of Glassdoor's 23 regional sites to search through. The jobs and their currency follow the location, not the site. Pick the local site when you type a local place name, e.g. `Ciudad de México` on glassdoor.com.mx. |
| **Max jobs** | 1,000 | Where the run stops. 1,000 is also the most per run. |

**Filters** (all optional): posted within, remote only, Easy Apply only, minimum
company rating, search radius, job type, seniority, minimum and maximum salary,
company size, industry, department, company ID, sort order.

Example:

```json
{
  "keyword": "data engineer",
  "location": "London",
  "domain": "https://www.glassdoor.co.uk",
  "maxJobs": 200,
  "daysOld": "7",
  "minRating": "3"
}
```

### Output

One row per job, 27 fields:

| Group | Fields |
| --- | --- |
| The job | `job_posting_id`, `job_title`, `url`, `job_application_link`, `job_snippet`, `age_in_days`, `easy_apply`, `sponsored`, `expired` |
| The company | `company_id`, `company_name`, `company_url_overview`, `company_logo_url`, `company_rating` |
| Where | `job_location`, `location_id`, `location_type`, `country_id` |
| Pay | `pay_source`, `pay_range_currency`, `pay_type`, `pay_min`, `pay_max`, `pay_median` |
| Provenance | `search_keyword`, `timestamp`, `job_link` |

A real row, with long text shortened:

```json
{
  "job_posting_id": 1010267258998,
  "job_title": "Product Manager II, Security & Privacy, Google Cloud",
  "url": "https://www.glassdoor.com/job-listing/product-manager-ii-security-privacy-google-cloud-google-JV_IC1147401_KO0,48_KE49,55.htm?jl=1010267258998",
  "job_application_link": "https://www.glassdoor.com/job-listing/j?jl=1010267258998",
  "job_snippet": "Master's degree in a technology or business related field. Work with partner teams (e.g., engineers, PgMs, UX) during pr…",
  "age_in_days": 1,
  "easy_apply": false,
  "sponsored": false,
  "expired": false,
  "company_id": 9079,
  "company_name": "Google Inc.",
  "company_url_overview": "https://www.glassdoor.com/Overview/W-EI_IE9079.htm",
  "company_logo_url": "https://media.glassdoor.com/sql/9079/google-squarelogo-1441130773284.png",
  "company_rating": 4.4,
  "job_location": "San Francisco, CA",
  "location_id": 1147401,
  "location_type": "C",
  "country_id": 1,
  "pay_source": "EMPLOYER_PROVIDED",
  "pay_range_currency": "USD",
  "pay_type": "ANNUAL",
  "pay_min": 163000,
  "pay_max": 236000,
  "pay_median": 199500,
  "search_keyword": "product manager",
  "timestamp": "2026-09-19T11:26:40Z",
  "job_link": "https://www.glassdoor.com/partner/jobListing.htm?pos=103&ao=1136043&s=58&guid=000001a…"
}
```

The dataset has two ready-made views: **Overview** (the job, pay and rating) and
**Company** (jobs by company and rating).

### Pricing

You pay a small fee per run and a fee per job delivered. The prices are on the
**Pricing** tab.

A run never scrapes more jobs than its maximum charge covers. The limit is
applied before scraping starts, so you never pay for jobs that were scraped
and then thrown away.

### Good to know

- **Remote only and Easy Apply only mean *only*.** They do not add remote or
  Easy Apply jobs to the other results.
- **Filters are Glassdoor's.** Results are what Glassdoor returns for that
  filter. Occasionally that includes an edge case, such as a 3.8-rated company
  under a "4 and up" filter.
- **Stopping a run keeps what it found.** Jobs are saved page by page, so a run
  you stop still has everything it scraped before stopping.
- **No matches is a valid result.** The log says so and suggests checking the
  filters.
- **An unknown location stops the run straight away**, with a message. Nothing
  is scraped.
- **Check where it searched.** Glassdoor matches place names loosely: on
  glassdoor.com, `Mexico City` finds the US state of New Mexico. The run
  summary records the place actually searched, and the log warns when it does
  not look like what you typed. Use the name Glassdoor uses, or the country's
  own Glassdoor site.
- **Deduplicate on `job_posting_id`** if you combine several runs.

### Run summary

Each run writes a summary to its key-value store as `OUTPUT`. It records:

- the input as the actor read it;
- the place Glassdoor actually searched (`run.location`);
- how many jobs were delivered;
- how many requests Glassdoor rate limited;
- what was charged.

# Actor input Schema

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

A job title, skill or company name to search for, e.g. "software engineer".

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

A city, state or country as you would type it on Glassdoor — "New York", "California", "United Kingdom". Resolved to Glassdoor's own place id before searching; if nothing matches, the run stops and says so.

## `domain` (type: `string`):

The regional Glassdoor to search through. The jobs you get, and their currency, follow the Location, not this. What it changes is how place names are read: a local site knows local names, e.g. 'Ciudad de México' on glassdoor.com.mx. Links mostly point to this site.

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

Stop after this many jobs. 1,000 by default, which is also the most one run can collect.

## `daysOld` (type: `string`):

Only jobs posted in the last N days.

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

Return only remote jobs. This is "remote only", not "include remote".

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

Return only jobs you can apply to through Glassdoor.

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

Only companies rated at least this, out of 5.

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

Distance around the location. Metric Glassdoor sites label the same numbers in kilometres.

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

Employment type.

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

Level of the role.

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

Lower bound on pay, in the site's own currency.

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

Upper bound on pay, in the site's own currency.

## `employerSize` (type: `string`):

Headcount band of the hiring company.

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

Industry of the hiring company.

## `jobFunction` (type: `string`):

Function the role sits in.

## `companyId` (type: `integer`):

Restrict the search to one employer, by its Glassdoor id — the number in an Overview URL, e.g. 40772 in /Overview/...IE40772.htm.

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

Order Glassdoor returns results in.

## Actor input object example

```json
{
  "keyword": "software engineer",
  "location": "United States",
  "domain": "https://www.glassdoor.com",
  "maxJobs": 1000,
  "daysOld": "",
  "remoteOnly": false,
  "easyApplyOnly": false,
  "minRating": "",
  "radiusMiles": "",
  "jobType": "",
  "seniority": "",
  "employerSize": "",
  "industry": "",
  "jobFunction": "",
  "sortBy": "relevant_desc"
}
```

# Actor output Schema

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

Every job scraped, one item each.

## `runSummary` (type: `string`):

What was requested, where Glassdoor searched, what arrived, how many requests it took and what was charged.

# 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": "software engineer",
    "location": "United States",
    "maxJobs": 1000
};

// Run the Actor and wait for it to finish
const run = await client.actor("silo/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": "software engineer",
    "location": "United States",
    "maxJobs": 1000,
}

# Run the Actor and wait for it to finish
run = client.actor("silo/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": "software engineer",
  "location": "United States",
  "maxJobs": 1000
}' |
apify call silo/glassdoor-jobs-scraper --silent --output-dataset

```

## MCP server setup

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