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

Scrape Glassdoor job listings by keyword and location: title, company and its rating, pay range, posting date, Easy Apply, plus optional full descriptions, apply links and company profiles. Filters for date, remote, job type, seniority and salary. No login, no browser. Pay only for results.

- **URL**: https://apify.com/axlymxp/glassdoor-jobs-scraper.md
- **Developed by:** [axly](https://apify.com/axlymxp) (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 $4.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?

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

Get Glassdoor job listings as clean JSON or CSV: search by keyword and location, filter by posting date, remote work, job type, seniority, minimum salary, Easy Apply and company rating, and optionally open every listing for the full description, apply link, geo coordinates and the employer's profile and ratings. The actor reads Glassdoor's mobile app data source, so it needs **no login and no browser**, returns up to 100 listings per request and includes Glassdoor's **pay range and company rating on every row**.

Built for recruiters and sourcing teams tracking openings by role and city, job boards and aggregators, labour-market analysts (pay ranges, posting volume by region), sales teams that use hiring as a buying signal, and candidates who want new postings delivered on a schedule.

### What you get

One row per job listing. Rows are deduplicated across pages and keywords within a run.

| Field | Description |
| --- | --- |
| `listing_id`, `url` | Glassdoor listing id and a link that opens the listing |
| `title`, `normalized_title` | Title as posted and Glassdoor's normalised title |
| `company_name`, `company_id`, `company_logo_url`, `company_rating` | Employer with its Glassdoor id, logo and overall rating (1-5) |
| `location`, `location_id` | Job location as shown on Glassdoor, e.g. `San Francisco, CA` or `Remote` |
| `age_in_days`, `posted_date` | How long the job has been up and the posting date |
| `pay_min`, `pay_median`, `pay_max`, `pay_currency`, `pay_period`, `salary_source` | Pay range (employer-provided or Glassdoor estimate), currency (USD, GBP, ...) and period (annual, hourly) |
| `easy_apply`, `is_sponsored`, `is_expired` | Apply on Glassdoor, paid placement, expired flag |
| `industry`, `sector` | Employer's industry and sector |
| `search_keyword`, `search_location` | Which search found the job |
| `scraped_at` | UTC timestamp |

With **Fetch job details** on, every row also gets:

| Field | Description |
| --- | --- |
| `description_html`, `description_text` | The full job description |
| `job_types`, `is_remote` | `fulltime`, `parttime`, `contract`, `temporary`; work-from-home flag |
| `apply_url`, `serp_url` | Glassdoor's apply link (redirects to the employer's application) and search-page link |
| `discover_date`, `posted_date` | Exact dates from the listing |
| `latitude`, `longitude`, `city`, `state`, `country` | Geocoded job location |
| `company_website`, `company_headquarters`, `company_size`, `company_revenue`, `company_type`, `company_year_founded`, `company_ceo` | Employer profile |
| `company_rating_career_opportunities`, `company_rating_compensation_benefits`, `company_rating_culture_values`, `company_rating_senior_management`, `company_rating_work_life_balance`, `company_recommend_to_friend_pct`, `company_ceo_approval_pct` | Employer ratings breakdown |
| `company_overview_url`, `company_reviews_url`, `company_salaries_url` | The employer's Glassdoor pages |

### Use cases

- **Sourcing and recruiting.** Pull every "data engineer" opening in Austin posted in the last 7 days with pay ranges and company ratings, and refresh the list daily.
- **Hiring as a sales signal.** Companies posting many senior roles are growing: filter by seniority and keyword, join on `company_id`, and route accounts with new postings to sales.
- **Pay benchmarking.** Compare `pay_median` for the same title across cities and countries (local currency is returned, e.g. GBP for London).
- **Job boards and aggregators.** Keep a niche board fresh with full descriptions and apply links, deduplicated by `listing_id`.
- **Research.** Posting volumes, remote share and salary transparency by role, region and industry over time.

### Input

| Parameter | Type | Default | Description |
| --- | --- | --- | --- |
| `keywords` | array | – | One search per keyword: job title, skill or company name. |
| `location` | string | – | City (`San Francisco, CA`, `Chicago`), state or region (`Texas`, `England`, `London`), country (`United Kingdom`, `Germany`) or `Remote`. A region wins a name tie, so write `New York, NY` for the city. Empty = anywhere. |
| `maxJobs` | integer | `100` | Jobs per keyword, after deduplication. |
| `fetchDetails` | boolean | `false` | Open every listing for the detail fields above (one extra request per job). |
| `postedWithinDays` | enum | `any` | `1`, `3`, `7`, `14`, `30` |
| `remoteOnly` | boolean | `false` | Work-from-home jobs only. |
| `jobType` | enum | `any` | `fulltime`, `parttime`, `contract`, `temporary` |
| `seniority` | enum | `any` | `entrylevel`, `midseniorlevel`, `director`, `executive` |
| `minSalary` | integer | `0` | Minimum annual pay in the location's currency. |
| `easyApplyOnly` | boolean | `false` | Only jobs that can be applied to on Glassdoor. |
| `minCompanyRating` | enum | `any` | `1` to `4` stars. |
| `sortBy` | enum | `relevance` | `relevance` or `newest`. |
| `proxyConfiguration` | object | RESIDENTIAL | Fallback only: the actor connects directly and switches to this proxy if Glassdoor refuses the connection. |

#### Example input

```json
{
  "keywords": ["software engineer"],
  "location": "San Francisco, CA",
  "postedWithinDays": "30",
  "maxJobs": 30,
  "fetchDetails": true
}
```

#### Example output

```json
{
  "listing_id": 1010265191807,
  "title": "Backend Software Engineer",
  "normalized_title": "back end engineer",
  "company_name": "Rise Technical Recruitment Limited",
  "company_id": 778114,
  "company_logo_url": "https://media.glassdoor.com/sql/778114/rise-technical-recruitment-squareLogo-1742983220582.png",
  "company_rating": 3.9,
  "location": "San Francisco, CA",
  "location_id": 1147401,
  "age_in_days": 18,
  "posted_date": "2026-09-16",
  "easy_apply": true,
  "is_sponsored": true,
  "is_expired": false,
  "pay_currency": "USD",
  "pay_period": "ANNUAL",
  "pay_min": 145000.0,
  "pay_median": 162500.0,
  "pay_max": 180000.0,
  "salary_source": "EMPLOYER_PROVIDED",
  "industry": "Staffing & Subcontracting",
  "sector": "Human Resources & Staffing",
  "url": "https://www.glassdoor.com/job-listing/j?jl=1010265191807",
  "search_keyword": "software engineer",
  "search_location": "San Francisco, CA",
  "scraped_at": "2026-10-05T01:54:30Z",
  "description_text": "Backend Software Engineer\n\nSan Francisco, California (Hybrid)\n\n$145,000 - $180,000 + Equity + Healthcare + 401(k) + PTO\n\nAre you a Backend Software Engineer looking to take full ownership of production...",
  "discover_date": "2026-09-16",
  "job_types": ["fulltime"],
  "is_remote": false,
  "apply_url": "https://www.glassdoor.com/partner/jobListing.htm?pos=101&ao=1110586&tgt=APPLY_START&jobListingId=1010265191807&...",
  "latitude": 37.775,
  "longitude": -122.41833,
  "city": "San Francisco, CA",
  "state": "California",
  "country": "United States",
  "company_website": "https://www.risetechnical.co.uk",
  "company_headquarters": "Bristol, United Kingdom",
  "company_size": "51 to 200 Employees",
  "company_type": "Company - Private",
  "company_year_founded": 2005,
  "company_ceo": "Ben McCarthy",
  "company_rating_work_life_balance": 3.9,
  "company_recommend_to_friend_pct": 0.74,
  "company_reviews_url": "https://www.glassdoor.com/Reviews/Rise-Technical-Recruitment-Reviews-E778114.htm"
}
```

### Speed

One request returns up to 100 listings, so a listings-only run of 500 jobs takes a few seconds. With details on, each job costs one extra request of about half a second: 100 jobs with full descriptions finish in about a minute.

### Scheduling and integrations

Create an Apify schedule (hourly, daily or weekly), set `sortBy` to `newest` and `postedWithinDays` to `1` or `3`, and connect a webhook or integration (Slack, Google Sheets, Make, Zapier, n8n). Results download as JSON, CSV, Excel or XML, or can be read through the Apify API; `listing_id` is stable, so deduplicating across runs is a single key.

### Use with AI assistants

Call the actor from an agent through the Apify API or the Apify MCP server, for example: "find remote senior Python jobs posted this week paying at least $180,000 and summarise what the companies have in common". Pay ranges, ratings and the plain-text description arrive as separate fields, so the model can reason without parsing pages.

### FAQ

**Do I need a Glassdoor account?** No. Everything returned is public on Glassdoor without logging in.

**How many jobs can one search return?** Glassdoor reports a total (for example 93,000 for "software engineer" anywhere) but, like the website, serves a ranked subset through its pages. Narrow searches with a location and a posting-date filter are the way to get complete coverage; broad searches work best with `maxJobs` of a few hundred per keyword.

**Why are some pay fields empty?** Glassdoor shows a pay range on most listings (employer-provided or estimated), but not on all of them. `salary_source` tells you which kind you got.

**Where are the job types and remote flag?** They come from the listing itself, so they are filled only when `fetchDetails` is on. Without details, `location` reads `Remote` for remote jobs and the `remoteOnly` filter works either way.

**How are locations matched?** The location is looked up in Glassdoor's own location index: an exact state, region or country name wins (`Texas`, `England`, `London`, `Germany`), otherwise the best matching city. If Glassdoor does not know the place, the run stops with a clear message rather than searching the wrong area. Write the city with its qualifier (`New York, NY`, `Paris, France`) when the name is also a region.

**Does it need a proxy?** Usually not. If Glassdoor refuses the connection, the actor switches to the configured Apify Proxy (RESIDENTIAL by default) and continues.

**Is this legal?** The actor collects publicly visible job listings and company data. You are responsible for using the data in line with Glassdoor's terms and the laws that apply to you.

# Actor input Schema

## `keywords` (type: `array`):

One search per keyword, as you would type it into Glassdoor's job search: a job title ("software engineer"), a skill ("python"), or a company name. Each keyword gets up to 'Max jobs per keyword' rows.

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

City ("San Francisco, CA", "Chicago", "London, England"), state or region ("Texas", "California", "England", "London"), country ("United Kingdom", "Germany") or "Remote". A region wins a name tie, so write "New York, NY" for the city. Empty = anywhere (Glassdoor then returns mostly US jobs).

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

Stop after this many jobs for each keyword. Duplicates across pages and keywords are removed, so a run never charges the same listing twice.

## `fetchDetails` (type: `boolean`):

Also open every listing and add the full description (HTML and text), job types, remote flag, apply link, geo coordinates, posting date and the company's profile and ratings. One extra request per job, charged as a separate event.

## `postedWithinDays` (type: `string`):

Only jobs posted in the last N days.

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

Keep only work-from-home jobs (Glassdoor's remote filter).

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

Employment type filter.

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

Experience level filter.

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

Only jobs whose estimated or posted annual pay is at least this amount, in the local currency of the location (USD for US cities, GBP for London). 0 = no filter.

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

Keep only jobs that can be applied to on Glassdoor itself.

## `minCompanyRating` (type: `string`):

Only jobs at companies with at least this Glassdoor rating.

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

Order of results. 'Newest' is best for monitoring new postings.

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

Used only as a fallback: the actor connects directly and switches to this proxy if Glassdoor refuses the connection. Keep the default RESIDENTIAL group.

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "location": "San Francisco, CA",
  "maxJobs": 100,
  "fetchDetails": false,
  "postedWithinDays": "any",
  "remoteOnly": false,
  "jobType": "any",
  "seniority": "any",
  "minSalary": 0,
  "easyApplyOnly": false,
  "minCompanyRating": "any",
  "sortBy": "relevance",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# 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 = {
    "keywords": [
        "software engineer"
    ],
    "location": "San Francisco, CA",
    "proxyConfiguration": {
        "useApifyProxy": true,
        "apifyProxyGroups": [
            "RESIDENTIAL"
        ]
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axlymxp/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": ["software engineer"],
    "location": "San Francisco, CA",
    "proxyConfiguration": {
        "useApifyProxy": True,
        "apifyProxyGroups": ["RESIDENTIAL"],
    },
}

# Run the Actor and wait for it to finish
run = client.actor("axlymxp/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": [
    "software engineer"
  ],
  "location": "San Francisco, CA",
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}' |
apify call axlymxp/glassdoor-jobs-scraper --silent --output-dataset

```

## MCP server setup

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