levels.fyi Salary Scraper — Tech Compensation Data avatar

levels.fyi Salary Scraper — Tech Compensation Data

Pricing

from $2.00 / 1,000 salary records

Go to Apify Store
levels.fyi Salary Scraper — Tech Compensation Data

levels.fyi Salary Scraper — Tech Compensation Data

Scrape individual salary & total-compensation records from levels.fyi by company slug, company-salaries URL, or job-family URL. One flat row per submission: title, level, focus, years of experience, base, stock, bonus, total comp, location & demographics. JSON/CSV.

Pricing

from $2.00 / 1,000 salary records

Rating

0.0

(0)

Developer

Muhamed Didovic

Muhamed Didovic

Maintained by Community

Actor stats

0

Bookmarked

41

Total users

9

Monthly active users

2 days ago

Last modified

Categories

Security

Limited permissions

Share

levels.fyi Salary Scraper 💰

How the levels.fyi Salary Scraper works

Pull real, individual salary and total-compensation records from levels.fyi — the community-sourced database that tech workers use to benchmark pay. Feed it a company slug (google, meta, amazon), a company-salaries URL, or a specific job-family URL, and get back one clean, flat row per submission: company, title, level, focus, years of experience, base / stock / bonus, total comp, location, work arrangement and self-reported demographics. Points from a company's level chart come with level and total comp only, and are marked so you can tell them apart.

No login, no browser automation, no manual copy-paste from tables — just structured JSON/CSV you can drop straight into a spreadsheet, a comp model, or a dashboard.


💡 Why use this scraper

  • Individual records, not just averages. Most levels.fyi views show medians. This actor returns one row per submission, the raw data points behind the charts. recordDetail tells you which rows are full records and which are level-chart points with total comp only.
  • Benchmark compensation across companies, levels and locations for offer negotiation, comp-band design or market research.
  • Whole-company sweeps. Give it just google and it walks every job family (Software Engineer, Product Manager, Data Scientist, Sales, and 50+ more) automatically.
  • Rich per-row detail — base salary, average annual stock, bonus, total comp, first-year figures, focus tag (e.g. Machine Learning), years of experience / at company / at level, work arrangement, and demographics when the submitter shared them.
  • Fast & reliable — pure HTTP over residential IPs against the embedded page data; typical runs finish in seconds.

📋 What you can scrape

InputExampleWhat you get
Company sluggoogleEvery job family on Google's salaries page → all individual records
Company-salaries URLhttps://www.levels.fyi/companies/meta/salariesSame as above, from a pasted URL
Job-family URLhttps://www.levels.fyi/companies/amazon/salaries/software-engineerJust that one role's individual records
Job-family filter["software-engineer", "product-manager"]Restrict a company sweep to specific roles

🔧 Input

FieldTypeDescription
companySlugsarrayCompany slugs, e.g. ["google", "meta", "amazon"]. Each expands to every job family on that company's salaries page.
startUrlsarrayCompany-salaries URLs and/or specific job-family salary URLs. Auto-classified.
jobFamiliesarrayOptional filter — only scrape these job-family slugs (e.g. software-engineer, data-scientist). Empty = all.
fullRecordsOnlybooleanSkip level-chart points that carry only level and total comp, so you get (and pay for) full submissions only. Default false.
maxItemsintegerHard cap on total rows for the run.
maxItemsPerCompanyintegerCap records harvested per company.
maxConcurrencyintegerParallel requests (default 6).
proxyobjectFree-tier proxy config (defaults to Apify Residential, US). Paid runs use a built-in US residential pool.

Example input

{
"companySlugs": ["google", "meta"],
"jobFamilies": ["software-engineer", "product-manager"],
"maxItems": 2000
}

⚙️ How it works

  1. Company page — for each company slug / URL, the actor loads /companies/{slug}/salaries and reads the embedded page data to enumerate every job family listed for that company.
  2. Job-family pages — it then visits each /companies/{slug}/salaries/{jobFamily} page and extracts the individual salary submissions embedded in the page's data payload (grouped by company level).
  3. Flat rows — every submission becomes one dataset row with a stable uuid, so re-runs and multi-family sweeps deduplicate cleanly.

All requests go through US residential proxies with automatic session rotation and retries on rate-limits, so runs stay reliable at scale.


📤 Output

Each row is one individual compensation submission:

{
"rowType": "salary",
"recordDetail": "full",
"uuid": "6e828129-7eb5-400f-8c56-85f9c6379956",
"company": "Google",
"companySlug": "google",
"title": "Software Engineer",
"jobFamily": "Software Engineer",
"jobFamilySlug": "software-engineer",
"level": "L3",
"levelName": "L3",
"focusTag": "Full Stack",
"yearsOfExperience": 0,
"yearsAtCompany": 0,
"yearsAtLevel": null,
"offerDate": "2026-06-07T05:33:59.048Z",
"location": "Pittsburgh, PA",
"countryId": 254,
"dmaId": 508,
"workArrangement": "hybrid",
"compPerspective": "offer",
"employmentType": "full_time",
"currency": "USD",
"originalCurrency": "USD",
"baseSalary": 139000,
"totalCompensation": 159000,
"avgAnnualStockGrantValue": 20000,
"avgAnnualBonusValue": 0,
"gender": "female",
"ethnicity": null,
"education": null,
"sourceUrl": "https://www.levels.fyi/companies/google/salaries/software-engineer",
"scrapedAt": "2026-07-06T03:19:23.279Z"
}

Key output fields

FieldMeaning
recordDetailfull = the whole submission. total_comp_only = a point from a company's level chart: one real submission, with only its level, levelName and totalCompensation
uuidStable levels.fyi submission id (dedup key; empty on total_comp_only rows)
company / title / levelCompany, role and company-native level (L3, E5, …)
focusTagSpecialization (e.g. Machine Learning, Full Stack)
yearsOfExperience / yearsAtCompany / yearsAtLevelExperience context
currencyUnit of every amount in the row: always USD
originalCurrencyCurrency the person submitted in (e.g. GBP, EUR); amounts are already converted to USD
baseSalary / avgAnnualStockGrantValue / avgAnnualBonusValueComp breakdown
totalCompensationHeadline total comp
firstYearTotalCompensationFirst-year total (where reported)
location / workArrangement / compPerspectiveWhere, how and offer-vs-current
gender / ethnicity / educationSelf-reported demographics (when shared)
offerDateWhen the offer/submission was dated

❓ FAQ

Are these individual data points or averages? Individual submissions, one row each, so you can slice and aggregate them yourself. How much detail a row carries depends on what levels.fyi shows publicly. For each role you get the median submission and the latest submissions in full (recordDetail: "full"). Companies with a level ladder (Google, Meta, Stripe…) add every point from the level chart, which levels.fyi publishes with level and total comp only (recordDetail: "total_comp_only"). Full records come first in the dataset, so a small maxItems still gets the detailed rows. Set fullRecordsOnly: true to leave the chart points out of the run entirely, so you are not charged for them. For Google software engineers that is 4 full rows instead of 90 rows in total.

Which companies are supported? Any company on levels.fyi. Use the slug from the URL — https://www.levels.fyi/companies/**stripe**/salaries → stripe.

Which job families can I scrape? Whatever the company page lists — Software Engineer, Product Manager, Software Engineering Manager, Data Scientist, Hardware Engineer, Sales, Recruiter, Technical Program Manager and dozens more. Leave jobFamilies empty to grab them all.

Is the money in USD? Yes, every amount is in USD, including roles outside the US. levels.fyi keeps each submission converted to USD. originalCurrency tells you what the person was paid in (a London offer shows GBP), so you can convert back at the rate you prefer.

How much data can I get per company? levels.fyi surfaces a bounded set of recent sample records per level, so expect dozens to a few hundred individual records per company depending on how many families and levels it has. Smaller companies return fewer: when a role has only a handful of submissions, levels.fyi shows just a salary range to keep contributors anonymous, and the run reports 0 records for it.


🛟 Support

Run into a company that won't parse, a field you need added, or a schema question? Open an issue on the actor's Issues tab with the input you used — most requests are quick fixes.


🤖 For AI Agents & LLM Apps

Compact reference for AI agents calling this actor via the Apify MCP server or the Apify API (actor: memo23/levels-fyi-salary-scraper).

Purpose: Extract individual, per-submission salary and total-compensation records from levels.fyi (not just medians) as one flat row per submission.

Minimal input:

{ "companySlugs": ["google"], "maxItems": 50 }

Instead of companySlugs, you can pass startUrls with company-salaries URLs (https://www.levels.fyi/companies/meta/salaries) or specific job-family URLs (.../salaries/software-engineer); they are auto-classified.

Output: one dataset row per salary submission — rowType, recordDetail (full, or total_comp_only for level-chart points that carry only level and total comp), uuid (dedup key, empty on total_comp_only), company, companySlug, title, jobFamily, jobFamilySlug, level, levelName, focusTag, yearsOfExperience, yearsAtCompany, yearsAtLevel, offerDate, location, countryId, dmaId, workArrangement, compPerspective, employmentType, currency (always USD), originalCurrency, baseSalary, totalCompensation, avgAnnualStockGrantValue, avgAnnualBonusValue, gender, ethnicity, education, sourceUrl, scrapedAt.

Behaviors an agent should know:

  • Always set maxItems — each row is one paid salary event, and an uncapped company sweep walks every job family. Free-tier runs are additionally capped at 100 rows.
  • companySlugs expands each company to every job family; jobFamilies filters a sweep to specific role slugs; maxItemsPerCompany caps records per company.
  • startUrls and companySlugs can be combined; URLs are auto-classified as company-salaries or single job-family pages.
  • Re-runs and multi-family sweeps deduplicate on the stable uuid.
  • Records are self-reported and levels.fyi surfaces a bounded set of recent samples per level, so expect dozens to a few hundred per company.
  • Optional enrichEmails (default false) adds contactEmail + contactWebsite and an emailEnrichment object (best-effort).

⚠️ Disclaimer

This actor collects publicly available compensation data from levels.fyi for research, benchmarking and analytics. It does not access any login-gated content and stores no personal-account data. Individual submissions on levels.fyi are self-reported and anonymized by the source. You are responsible for using the scraped data in compliance with levels.fyi's Terms of Service and all applicable laws (including data-protection regulations). This actor is not affiliated with, endorsed by, or sponsored by levels.fyi.


🔎 SEO Keywords

levels.fyi scraper, levels fyi salary scraper, tech salary data, total compensation scraper, tech comp benchmarking, software engineer salary data, FAANG salary scraper, compensation dataset, salary benchmarking API, levels.fyi API, stock and bonus data, tech pay data, salary negotiation data, comp band research, levels fyi companies salaries.