Collect Glassdoor Builder data and return results
Data & analysis
Scavio Glassdoor
Try itResolve a company name to a Glassdoor employer id, then pull the employer profile with ratings and CEO approval, up to three full reviews, and salary percentiles by job title. 4 endpoints, 1 credit each, structured JSON.
What it does
Resolve a company name to a Glassdoor employer id, then pull the employer profile with ratings and CEO approval, up to three full reviews, and salary percentiles by job title. 4 endpoints, 1 credit each, structured JSON.
The skill document
Glassdoor via Scavio
Resolve a company name to its Glassdoor employer id, then read the employer profile, employee reviews and salary percentiles by job title. All endpoints return structured JSON.
When to trigger
Use this skill when the user asks to:
- Look up a company's Glassdoor rating, star distribution, CEO approval and per-category scores
- Read employee reviews with pros, cons, advice and the employer's response
- Pull salary percentiles (P10-P90, base and total pay) by job title for an employer
- Benchmark compensation or employer brand across companies
- Turn a company NAME into the employer id Glassdoor's URLs use
Note: Glassdoor is the slowest surface on this API. A profile call runs 3-47 seconds, reviews around 75, salaries around 41, and a call that ultimately fails can take up to ~170 seconds before it reports a 502. Set a client timeout of at least 180 seconds and expect the occasional retry.
Setup
Get a free API key at scavio.dev (50 free credits to get started, no card required):
export SCAVIO_API_KEY=sk_live_your_key
Every request is a POST with a JSON body and:
Authorization: Bearer $SCAVIO_API_KEY
Endpoints
Base URL: https://api.scavio.dev. Every Glassdoor endpoint costs 1 credit.
| Endpoint | Credits | What it returns |
|---|---|---|
POST /api/v1/glassdoor/companies | 1 | START HERE. Search Glassdoor for a company by name and resolve it to an employer_id |
POST /api/v1/glassdoor/company | 1 | Employer profile: description, mission, industry, sector, HQ, size and revenue bands, stock symbol, year founded, overall and per-category ratings, star distribution, CEO approval, awards, FAQ, five server-rendered reviews, plus reviews_url / salaries_url |
POST /api/v1/glassdoor/reviews | 1 | Up to three full reviews with per-axis scores, pros, cons, advice, job title, location, employment status and employer response - plus complete rating statistics, star distribution, aggregate pro/con highlight terms and per-job-title review counts |
POST /api/v1/glassdoor/salaries | 1 | Salaries by job title, 10 per page: base-pay and total-pay percentiles P10-P90 with medians, sample counts, currency, pay period, last-reported date |
Workflow
Start at /companies. /company, /reviews and /salaries all need an employer_id that exists only inside Glassdoor's /Overview/ URLs.
- Resolve the name: call
/glassdoor/companieswithquery. Each result row carriesemployer_id,nameandurl. - Profile: call
/glassdoor/companywith thatemployer_id. Keep thereviews_urlandsalaries_urlit returns. - Reviews and salaries: call
/glassdoor/reviewsand/glassdoor/salariespassing those saved URLs back asurl. That is the single-fetch path - addressing them byemployer_idinstead makes the API resolve the case-sensitive/Reviews/and/Salary/slugs off the profile first, which is two upstream fetches for the same one credit and roughly twice the latency on the slowest surface here.
employer_id must be a string - a JSON number is rejected. 1699, E1699 and IE1699 are all accepted.
company is cosmetic. The profile resolves on employer_id alone, company is ignored entirely when url is set, and it does not satisfy the required-identifier rule: a request carrying only company is rejected.
Pagination
/reviewshas nopageparameter and never will. Glassdoor's login wall caps the response at three reviews. Move the window withcategoryandemployment_status, and readfiltered_review_countto see how many reviews match the current filter (againsttotal_review_countfor the employer overall). Do not build a paging loop here and never claim you can retrieve all reviews./salariespages with a 1-basedpageat 10 job titles per page;page_counton the response says how many pages exist./companiesand/companyreturn a single response and take no paging parameter.
Parameters
Companies lookup (/companies)
| Parameter | Type | Default | Description |
|---|---|---|---|
query | string | required | Company name (1-120 chars) |
Company (/company)
| Parameter | Type | Default | Description |
|---|---|---|---|
employer_id | string | one of | 1699, E1699 or IE1699. String, not a number |
url | string | one of | Any glassdoor.com employer URL (/Overview/, /Reviews/, /Salary/). Non-glassdoor.com hosts are rejected |
company | string | -- | Cosmetic only; ignored when url is set; does not satisfy the identifier requirement |
employer_id or url is required.
Reviews (/reviews)
| Parameter | Type | Default | Description |
|---|---|---|---|
employer_id | string | one of | Employer id |
url | string | one of | Pass back reviews_url from /company to skip the resolve fetch |
company | string | -- | Cosmetic |
category | string | -- | career_development, compensation, culture, diversity_and_inclusion, management, work_life_balance |
employment_status | string | -- | full_time, part_time, contract, intern |
employer_id or url is required. There is no page parameter. Both filters are closed sets: Glassdoor ignores an unknown value and serves the unfiltered set under a 200, so an invented filter is a credit spent on nothing. A freelance status is absent because it was never confirmed to change the result set.
Salaries (/salaries)
| Parameter | Type | Default | Description |
|---|---|---|---|
employer_id | string | one of | Employer id |
url | string | one of | Pass back salaries_url from /company to skip the resolve fetch |
company | string | -- | Cosmetic |
page | integer | -- | 1-based, 10 job titles per page; page_count is on the response |
Examples
import requests
BASE = "https://api.scavio.dev"
# Your key from https://scavio.dev. Load it from your environment or secret
# store in real code - keep it out of source control.
API_KEY = "sk_your_key_here"
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
TIMEOUT = 180 # Glassdoor is slow - do not use a short client timeout
# 1. ALWAYS START HERE - a name is not an employer id
hits = requests.post(f"{BASE}/api/v1/glassdoor/companies", headers=HEADERS,
json={"query": "Anthropic"}, timeout=TIMEOUT).json()
employer_id = hits["data"]["results"][0]["employer_id"] # a STRING
# 2. Profile - keep the two URLs it hands back
company = requests.post(f"{BASE}/api/v1/glassdoor/company", headers=HEADERS,
json={"employer_id": employer_id}, timeout=TIMEOUT).json()["data"]
reviews_url, salaries_url = company["reviews_url"], company["salaries_url"]
# 3. Reviews via the saved URL - one upstream fetch instead of two.
# Up to THREE reviews. There is no page param; move the window with filters.
reviews = requests.post(f"{BASE}/api/v1/glassdoor/reviews", headers=HEADERS,
json={"url": reviews_url, "category": "work_life_balance",
"employment_status": "full_time"}, timeout=TIMEOUT).json()["data"]
print(reviews["count"], reviews["filtered_review_count"], reviews["total_review_count"])
# 4. Salary percentiles by job title, 10 per page
salaries = requests.post(f"{BASE}/api/v1/glassdoor/salaries", headers=HEADERS,
json={"url": salaries_url, "page": 1}, timeout=TIMEOUT).json()["data"]
print(salaries["page"], "of", salaries["page_count"], salaries["pay_period"])
Response shapes
Every response uses the envelope { data, response_time, credits_used, credits_remaining }. Key data fields:
- companies —
count,results[](pos,employer_id,name,url). - company —
employer_id,name,short_name,url,reviews_url,salaries_url,website,description,mission,logo,cover_photo,headquarters,size,type,revenue,stock_symbol,year_founded,industry,sector,office_count,is_active,rating,rating_max,rating_count,review_count,salary_count,ratings,industry_ratings,rating_distribution,ceo,awards,faq,breadcrumbs,reviews[](the five server-rendered ones). - reviews —
employer_id,name,url,reviews_url,salaries_url,rating,total_review_count,rating_count,filtered_review_count,ratings,rating_distribution,highlights[](term,type,text),reviews_by_job_title,count(at most 3),reviews[](pos,review_id,url,title,pros,cons,advice,rating,rating_career_opportunities,rating_compensation_and_benefits,rating_culture_and_values,rating_diversity_and_inclusion,rating_senior_management,rating_work_life_balance,business_outlook,ceo_opinion,recommends,job_title,location,employment_status,is_current_employee,years_employed,published_date,helpful_count,employer_response,employer_response_date). - salaries —
employer_id,name,url,location,pay_period,currency,salary_count,job_title_count,page,page_count,count,salaries[](pos,job_title,job_title_id,salary_count,currency,base_pay,total_pay,median_base_pay,median_total_pay,most_recent).
{
"data": {
"employer_id": "1699",
"name": "Example Corp",
"rating": 3.9,
"total_review_count": 17798,
"filtered_review_count": 13251,
"count": 3,
"reviews": [
{
"pos": 1,
"review_id": "98765432",
"title": "Good pay, heavy workload",
"pros": "Compensation is above market and the tooling is excellent.",
"cons": "On-call rotation is punishing during launches.",
"rating": 4,
"rating_work_life_balance": 3,
"job_title": "Software Engineer",
"location": "Austin, TX",
"employment_status": "full_time",
"is_current_employee": true,
"published_date": "2026-06-14"
}
]
},
"credits_used": 1,
"credits_remaining": 999
}
Guardrails
- Every call is 1 credit, including one that comes back empty or times out into a 502.
- Reviews are capped at three per response. Never promise, imply or attempt a full review dump, and never invent a
pageparameter for/reviews. Report the cap, and usefiltered_review_count/total_review_countto give the user the scale of what exists. - Three reviews are not a sample you can generalise from. Use the aggregate blocks -
rating_distribution,ratings,highlights,reviews_by_job_title- for anything sentiment-shaped, and quote the individual reviews as anecdotes. - Chain
reviews_url/salaries_urlfrom/companywhenever you already have them. Same price, half the upstream work, materially faster on a slow surface. employer_idmust be a string. Send"1699", not1699.- Never send
companyon its own expecting it to address an employer - it is cosmetic and the request is rejected withoutemployer_idorurl. - Salary figures are Glassdoor's estimates for the job title, not individual reported salaries. Say so whenever you quote one, along with
pay_periodandcurrency. - Never fabricate employer ids, ratings, salary figures or review text. Only return what the API returned.
- Reviews are written by identifiable employees. Summarise them; do not try to identify who wrote one.
Failure handling
400means an invalid or missing parameter - neitheremployer_idnorurl, a numericemployer_id, a non-glassdoor.comurl, or acategory/employment_statusoutside its set. Fix and retry.401means the API key is invalid or missing. CheckSCAVIO_API_KEY.404means the employer id or URL does not resolve. Re-run/companiesrather than guessing another id.429means rate or usage limit exceeded. Wait before retrying. See rate limits.502/503mean upstream is temporarily unavailable. This is the common failure here - Glassdoor sits behind a render-only, degraded pool. A failing call can take ~170 seconds before it reports. Retry once or twice with a short pause; do not hammer it, and do not shorten the client timeout to "fail faster" - you will abandon calls that were about to succeed.- If
/companiesreturns nothing useful, try the legal entity name or a shorter form of the brand. - If
SCAVIO_API_KEYis not set, prompt the user to export it before continuing.
SDKs
pip install scavio==0.15.0
from scavio import ScavioClient
client = ScavioClient() # reads SCAVIO_API_KEY
hits = client.glassdoor.companies("Anthropic")
employer_id = hits["data"]["results"][0]["employer_id"]
company = client.glassdoor.company(employer_id=employer_id)["data"]
reviews = client.glassdoor.reviews(url=company["reviews_url"], category="compensation")
salaries = client.glassdoor.salaries(url=company["salaries_url"], page=1)
npm install scavio@0.15.0
import { Scavio } from "scavio";
const client = new Scavio(); // reads SCAVIO_API_KEY
const hits = await client.glassdoor.companies({ query: "Anthropic" });
const company = await client.glassdoor.company({ employer_id: hits.data.results[0].employer_id });
const salaries = await client.glassdoor.salaries({ url: company.data.salaries_url, page: 1 });
Related skills
Search Indeed job postings, pull one posting in full with its original ATS link, and read employer profiles and employee reviews. 4 endpoints, 2 credits each, structured JSON for recruiting and labour-market research.
Look up salary for an Indeed job posting via RolesAPI.com. Pass a job key or a pasted Indeed URL and get min, max, currency, period, and employer-vs-estimate...
Collect Indeed Companies Info data and return results
Collect Indeed Job Listings data and return results
Researches job postings, hiring signals, and freelance gigs via the Crawlora API — Indeed, Google/Amazon/Apple/Meta/Tesla careers sites, any company's ATS board (Greenhouse, Lever, Workday, SmartRecruiters, Ashby, and more), plus Upwork and Fiverr — returning clean JSON. Use when the user wants to search job postings, see what a specific company is hiring for, aggregate hiring signals for a company, or research freelance gigs and sellers.