---
title: "Glassdoor API: Company Reviews and Salaries as JSON"
description: "Find a Glassdoor employer ID, then pull reviews and salary percentiles as JSON. Real responses, parameters and 1 credit per call."
url: https://perceptlayer.com/blog/glassdoor-salary-data-api
---

[Blog](https://perceptlayer.com/blog) / [API guides](https://perceptlayer.com/blog/category/api-guides)

# Glassdoor API: Company Reviews and Salaries as JSON

14 Aug 2026 Perceptlayer 8 min read

Glassdoor's own API is closed to new developers, so you can't sign up for one. The Perceptlayer Glassdoor API returns the same kind of data as JSON instead: search a company by name, take its `employer_id`, then call the reviews, overview and salaries endpoints. Each successful call costs 1 credit, and failed calls cost nothing.

## Key takeaways

-   Glassdoor's partner API stopped taking new applications in 2021, so a self-serve key from Glassdoor isn't available.
-   The flow is two steps: `companies-search` returns an `id` for the employer, and every other company endpoint takes that value as `employer_id`.
-   `companies-reviews` returns company-level review fields (rating, pros, cons, job title, location) plus paging fields such as `total_pages` and `has_more`.
-   `salaries` returns `total_pay` percentiles from `p10` to `p90` per employer, and an overall `estimate` block for the job title.
-   All six Glassdoor endpoints cost 1 credit per successful call, and the free tier gives 1,000 credits every month.

## Is there an official Glassdoor API you can still use?

Not for a new project. Glassdoor's Partner API program was [closed to new applications in 2021](https://providers.apievangelist.com/providers/glassdoor/) (API Evangelist, 2021), and Zuplo's guide to the API says the same: [Glassdoor closed off public access to its API in 2021](https://dev.to/zuplo/what-is-the-glassdoor-api-how-to-use-it-and-alternatives-35d7) (Zuplo, 2024). That leaves no self-serve route where you request a key and start calling.

If you hold an existing partner agreement, use it: that's the first-party route and the one with Glassdoor's terms attached. If you don't, the options are scraping the pages yourself or calling an API that returns the public data as JSON. For the maintenance side of the first option, see [what maintaining a scraper really involves](https://perceptlayer.com/blog/scraper-vs-api-maintenance-cost).

## What does the Glassdoor API return?

The [Glassdoor API](https://perceptlayer.com/apis/glassdoor) has six endpoints in the [Jobs area](https://perceptlayer.com/verticals/jobs). Three look up companies, one returns reviews, one returns salaries and one searches job listings. Every response is JSON with named fields, and the data is collected from publicly available sources and returned as found at the time of the call.

| Endpoint | Returns | Credits | Required | Optional |
| --- | --- | --- | --- | --- |
| [`/v1/glassdoor/companies-autocomplete`](https://perceptlayer.com/apis/glassdoor/companies-autocomplete) | Companies Autocomplete | 1 | `query` | none |
| [`/v1/glassdoor/companies-search`](https://perceptlayer.com/apis/glassdoor/companies-search) | Companies Search | 1 | `query` | `page`, `limit` |
| [`/v1/glassdoor/companies-overview`](https://perceptlayer.com/apis/glassdoor/companies-overview) | Companies Overview | 1 | `employer_id` | none |
| [`/v1/glassdoor/companies-reviews`](https://perceptlayer.com/apis/glassdoor/companies-reviews) | Companies Reviews | 1 | `employer_id` | `page`, `limit` |
| [`/v1/glassdoor/salaries`](https://perceptlayer.com/apis/glassdoor/salaries) | Salaries | 1 | `job_title` | `employer_id`, `page`, `limit` |
| [`/v1/glassdoor/jobs-search`](https://perceptlayer.com/apis/glassdoor/jobs-search) | Jobs Search | 1 | `keyword` | `cursor` |

The string parameters ( `query`, `job_title`, `keyword`) accept up to 100 characters. `employer_id` and the paging parameters `page` and `limit` are integers. The catalogue doesn't document defaults or page sizes for `page` and `limit`, so read `page`, `total_pages` and `has_more` from each response instead of assuming a size.

## How do you find a company's employer ID?

Call `companies-search` with the company name. The response lists matching employers, and each one has an `id` you pass as `employer_id` to the other endpoints. The search can return several employers with similar names, so check the name and `review_count` before you pick one.

```bash
curl "https://api.perceptlayer.com/v1/glassdoor/companies-search?query=Stripe" \
  -H "X-API-Key: $API_KEY"
```

A recorded response, trimmed:

```json
{
  "success": true,
  "data": {
    "query": "Stripe",
    "companies": [
      {
        "id": 671932,
        "name": "Stripe",
        "rating": 3.8,
        "review_count": 1619,
        "salary_count": 4702,
        "job_count": 3
      },
      {
        "id": 5554043,
        "name": "Stripe OLT",
        "rating": 4,
        "review_count": 24,
        "salary_count": 38,
        "job_count": 0
      }
    ],
    "page": 1,
    "total_pages": 5,
    "has_more": true
  },
  "meta": {
    "endpoint_family": "company_search",
    "billable": true
  }
}
```

Two employers match "Stripe". The first, `671932`, has 1,619 reviews; the second has 24. A script that blindly takes `companies[0]` works here, but for ambiguous names it's safer to compare `name` exactly and fall back to the highest `review_count`.

For a type-ahead box rather than a full result list, [`companies-autocomplete`](https://perceptlayer.com/apis/glassdoor/companies-autocomplete) takes the same `query` parameter. Use `companies-search` when you need the counts and ratings to disambiguate.

## How do you get company reviews as JSON?

Pass the employer ID to `companies-reviews`. The response holds a `company` object, a `reviews` array and paging fields. In the recorded Stripe response, `total_reviews` is 1564 across 157 pages. Reviews are returned as company-level data: a rating, free text, a job title and a location, with no reviewer names.

```bash
curl "https://api.perceptlayer.com/v1/glassdoor/companies-reviews?employer_id=671932" \
  -H "X-API-Key: $API_KEY"
```

A recorded response, trimmed:

```json
{
  "success": true,
  "data": {
    "company": {
      "id": 671932,
      "name": "Stripe",
      …
    },
    "reviews": [
      {
        "id": 106035163,
        "date": "2026-10-20T11:12:55Z",
        "summary": "Progressive environment with intense performance expectations",
        "pros": "Progressive workplace environment\nGood benefits\nGood compensation",
        "cons": "Intense performance ecosystem\nOffice is moving to less convenient location",
        "rating": 4,
        "job_title": "Software Engineer",
        "is_current_employee": true,
        "location": "Toronto, ON"
      },
      {
        "id": 106018689,
        "rating": 3,
        "ratings": {
          "career_opportunities": 3,
          "compensation_and_benefits": 3,
          "culture_and_values": 3,
          "diversity_and_inclusion": 4,
          "senior_leadership": 3,
          "work_life_balance": 3
        },
        …
      }
    ],
    "page": 1,
    "total_pages": 157,
    "total_reviews": 1564,
    "has_more": true
  },
  …
}
```

### Which review fields can you rely on?

The excerpt above shows the first review in full and only the rating fields of the second; the full recorded sample has two reviews. Both carry `id`, `date`, `summary`, `pros`, `cons`, `rating`, `job_title`, `is_current_employee` and `location`. Only the second also carries a `ratings` object (shown above) with `career_opportunities`, `compensation_and_benefits`, `culture_and_values`, `diversity_and_inclusion`, `senior_leadership` and `work_life_balance`. Treat `ratings` as optional in your code.

`pros` and `cons` are plain strings with line breaks ( `\n`), and some reviewers format them as bullet lists with leading dashes. Split on newlines and strip a leading `- ` if you want one point per row.

### What can you do with review data?

Aggregate it. Average `rating` per month, count reviews by `job_title`, or split by `is_current_employee` to compare current and former staff. Because every review has an `id`, you can store them and deduplicate when you re-pull. Keep the analysis at company level: group and count, and don't try to identify who wrote a review.

## How do you get salary data by job title?

Call `salaries` with a `job_title`. `employer_id` is optional. In the recorded call below, which doesn't pass it, the response holds rows for several employers plus an `estimate` block for the whole title. Each row has base pay, additional pay and `total_pay` percentiles.

```bash
curl "https://api.perceptlayer.com/v1/glassdoor/salaries?job_title=software+engineer" \
  -H "X-API-Key: $API_KEY"
```

A recorded response, trimmed:

```json
{
  "success": true,
  "data": {
    "job_title": "software engineer",
    "salaries": [
      {
        "job_title": "Software Engineer",
        "employer": {
          "id": 9079,
          "name": "Google",
          "rating": 4.4
        },
        "currency": "USD",
        "pay_period": "ANNUAL",
        "base_pay_mean": 184722.83,
        "additional_pay_mean": 126972.82,
        "total_pay": {
          "p10": 207909.08,
          "p25": 251388.51,
          "p50": 311695.65,
          "p75": 396273.52,
          "p90": 486503.67
        }
      },
      …
    ],
    "page": 1,
    "total_pages": 10438,
    "total_results": 104377,
    "has_more": true,
    "estimate": {
      "location": "United States",
      "confidence": "CONFIDENT",
      "salaries_count": 727155,
      "total_pay": {
        "p10": 99464.84,
        "p50": 152101.59,
        "p90": 237195.82
      },
      …
    }
  },
  …
}
```

### How do you read the percentiles?

In this recording, the Google row has a `total_pay` median ( `p50`) of 311,695.65 USD a year, against 152,101.59 USD for the `estimate` across all employers in the United States. The gap between `base_pay_mean` (184,722.83) and `additional_pay_mean` (126,972.82) shows why total pay, not base pay, is the field to compare for employers that pay in stock and bonuses.

Two cautions. These are figures as found at the time of the call, not a guarantee of accuracy, and the `estimate` carries its own `confidence` value and `salaries_count`. Check both before you quote a number. Also, with 10,438 pages for one title, don't page through everything: plan your questions so one page answers them.

### Which parameters narrow a salary query?

| Parameter | Type | Required | Use |
| --- | --- | --- | --- |
| `job_title` | string, up to 100 characters | yes | The title to look up, such as `software engineer` |
| `employer_id` | integer | no | An employer `id` from `companies-search` |
| `page` | integer | no | Move through results; read `total_pages` and `has_more` |
| `limit` | integer | no | Ask for a number of rows per page |

## What does it cost to pull a company's data?

Every Glassdoor endpoint is 1 credit per successful call, and a failed call returns `X-Credits-Used: 0` and bills nothing. A full pull of one company is cheap: one search call, one overview call and one call per page of reviews.

Using the recorded Stripe numbers, 157 pages of reviews means 157 calls. The arithmetic: 1 search + 1 overview + 157 review pages = 159 credits, which fits inside the 1,000 free credits you get every month after verifying an email address. No credit card is needed.

At volume, you buy prepaid credit packs of 10,000 (Starter), 50,000 (Build), 200,000 (Growth), 500,000 (Pro), 1,000,000 (Scale) or 5,000,000 (Volume) credits. Purchased credits last 12 months. See [pricing](https://perceptlayer.com/pricing) for what credits cost.

Tracking 100 employers, each pulled once with all 157 pages as in the Stripe example, is 100 × 159 calls × 1 credit = 15,900 credits. That's more than the Starter pack's 10,000 and within the Build pack's 50,000. Real companies vary widely in review count, so read `total_pages` from the first reviews response before you loop. See [credits in the docs](https://docs.perceptlayer.com/credits).

Every successful response carries `X-Credits-Used` and `X-Credits-Remaining`, so you can stop a loop when the balance gets low. The service is prepaid: when credits run out, calls return `insufficient_credits` (402) and nothing more is debited.

## How do you handle errors and rate limits?

Errors come back with an HTTP status and a JSON body: `{"error": {"code", "message", "request_id"}}`. The ones you'll meet on this API are `invalid_parameters` (422) for parameters the endpoint doesn't accept, `invalid_api_key` (401), `insufficient_credits` (402), `rate_limited` (429) and `temporarily_unavailable` (503).

For 429 and 503, wait the number of seconds in the `Retry-After` header and try again. Requests have no idempotency key, so if a client timeout hides the reply, the call may have succeeded and been billed. Count that possibility in your retry logic, and see [the error codes](https://docs.perceptlayer.com/errors) and [rate limits](https://docs.perceptlayer.com/rate-limits) in the docs. The pattern is covered in [retrying web API calls without paying twice](https://perceptlayer.com/blog/retry-web-api-calls-without-paying-twice).

## How do you page through a long reviews list?

Loop on `page` until `has_more` is false. Start at 1, keep the `id` of every review you store, and stop early if `X-Credits-Remaining` falls under your floor. On a 429 or 503, wait the `Retry-After` seconds and retry the same page. The loop below needs only `requests`.

```python
import os
import time
import requests

BASE = "https://api.perceptlayer.com/v1/glassdoor"
HEADERS = {"X-API-Key": os.environ["API_KEY"]}
CREDIT_FLOOR = 50

def get(path, **params):
    while True:
        r = requests.get(f"{BASE}/{path}", headers=HEADERS, params=params, timeout=30)
        if r.status_code in (429, 503):
            time.sleep(int(r.headers.get("Retry-After", "1")))
            continue
        r.raise_for_status()
        return r.json()["data"], int(r.headers["X-Credits-Remaining"])

(found, _) = get("companies-search", query="Stripe")
company = found["companies"][0]
reviews, page = {}, 1
while True:
    data, remaining = get("companies-reviews", employer_id=company["id"], page=page)
    for review in data["reviews"]:
        reviews[review["id"]] = review
    if not data["has_more"] or remaining < CREDIT_FLOOR:
        break
    page += 1

print(company["name"], len(reviews), "reviews;", remaining, "credits left")
```

Keying the dictionary on `id` means a repeated page can't create duplicates. A free account is limited to 1 request a second (60 a minute), so the 157 pages of the Stripe example take about 3 minutes, and a 429 sends the loop to sleep for the `Retry-After` it is given. Paid accounts run at least 5 requests a second. If a client timeout hides a reply, that page may have been billed once already, which the `id` keys absorb on the re-pull but the credits don't. For a fuller treatment, see [paginating a web data API in Python](https://perceptlayer.com/blog/paginate-web-data-api-python), and to avoid paying twice for the same page, [cache API responses](https://perceptlayer.com/blog/cache-web-data-api-responses).

Run the first call in the playground on the [Glassdoor API page](https://perceptlayer.com/apis/glassdoor) to see the shape before you write code, then [get a free API key](https://perceptlayer.com/signup). For authentication details, see [the docs](https://docs.perceptlayer.com/authentication). If you're building job-market tooling, the [Indeed Jobs API guide](https://perceptlayer.com/blog/indeed-jobs-api-json) covers postings, and the [Trustpilot reviews guide](https://perceptlayer.com/blog/trustpilot-reviews-api) covers customer reviews of the same companies.

## APIs in this post

-   [Glassdoor **1 credit per call** · 6 endpoints](https://perceptlayer.com/apis/glassdoor)

## Frequently asked questions

### Does Glassdoor have a public API?

Not one you can join today. Its Partner API was [closed to new applications in 2021](https://providers.apievangelist.com/providers/glassdoor/) (API Evangelist, 2021), and [public access to the API ended that year](https://dev.to/zuplo/what-is-the-glassdoor-api-how-to-use-it-and-alternatives-35d7) (Zuplo, 2024). The Perceptlayer Glassdoor API fills that gap with six endpoints and one key, at 1 credit per successful call.

### How much does the Glassdoor API cost?

Each of the six endpoints costs 1 credit per successful call. You get 1,000 free credits every month after verifying an email, with no credit card. Paid packs start at 10,000 credits (Starter), so 10,000 calls × 1 credit = 10,000 credits; [pricing](https://perceptlayer.com/pricing) has what credits cost. Failed calls cost nothing.

### Can I get reviewer names from the reviews endpoint?

The recorded `companies-reviews` response has no reviewer names. Each review has a rating, summary, pros, cons, job title, employment status and location. That fits company-level analysis such as rating trends and themes, and you should keep your analysis at that level too.

### How do I get salaries for one company only?

Look up the company with `companies-search`, then call `salaries` with both `job_title` and that company's `employer_id`, which is an optional parameter. The recorded call without it returned rows across many employers plus an overall `estimate`. Check the rows' `employer` field for the company you asked about. Both forms cost 1 credit per call.

### Can an AI agent call these endpoints?

Yes. The MCP server at `https://api.perceptlayer.com/mcp` exposes `search_endpoints`, `get_endpoint` and `call_endpoint`. The first two only look up the catalogue and cost nothing; `call_endpoint` spends the endpoint's 1 credit on success. Setup is in the [MCP docs](https://docs.perceptlayer.com/ai-agents).

glassdoor company reviews salary data jobs

## More from the blog

1.  [Web data by industry](https://perceptlayer.com/blog/category/web-data) 6 Oct 2026 Perceptlayer 7 min read
    
    ## [Salary Data from Job Sites: Reading Ranges Without Bias](https://perceptlayer.com/blog/salary-data-job-sites-bias)
    
    Glassdoor's salaries endpoint returns p10 to p90 total pay, a currency and a national count. How to read those ranges and the biases of self-reported pay.
    
2.  [API guides](https://perceptlayer.com/blog/category/api-guides) 3 Aug 2026 Updated 26 Oct 2026 Perceptlayer 8 min read
    
    ## [Indeed Jobs API: Get Job Postings as JSON](https://perceptlayer.com/blog/indeed-jobs-api-json)
    
    One GET to /v1/indeed/jobs returns job postings with company, location and apply URL as JSON for 1 credit. Parameters, a real response and monthly cost.
    
3.  [API guides](https://perceptlayer.com/blog/category/api-guides) 23 Oct 2026 Perceptlayer 7 min read
    
    ## [Cars.com API: Used Car Listings and Price Evaluations](https://perceptlayer.com/blog/cars-com-api-listings-price-evaluation)
    
    Search Cars.com listings with its six required parameters (zip, radius\_miles, stock\_type, sort, page, page\_size), then listing, dealer and price-eval calls.
