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
If you do not have a key yet
An agent running this skill without SCAVIO_API_KEY set will get 401 on every
call below. The whole path from nothing to a working key is self-serve:
- Sign up at dashboard.scavio.dev - email or Google, no card required.
- A key is created for the account automatically at signup. It is on the dashboard under API Keys, ready to copy.
- A new account starts with 50 credits. Endpoints in this skill cost 1 credit each unless the table below says otherwise.
When the balance runs out the API answers 402 with a JSON body carrying
billing_url. Topping up needs no code change - the same key keeps working.
The smallest purchase is 2,500 credits for $25, and monthly plans work out
cheaper per credit if the usage is steady rather than one-off.
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 lookup 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 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 - 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 });
