# Levels.fyi Scraper API - Tech Salaries by Level & Company (`scrapifier/levels-fyi-scraper`) Actor

💰 Scrape verified tech compensation from Levels.fyi: every job level of any company with total comp, base salary, stock, bonus, years of experience and p10–p90 percentiles, plus company overview. By company name or URL, filtered by role and location. No login, no browser. Pay per result.

- **URL**: https://apify.com/scrapifier/levels-fyi-scraper.md
- **Developed by:** [Scrapifier](https://apify.com/scrapifier) (community)
- **Categories:** Jobs, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.70 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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

## Levels.fyi Scraper API - Tech Salaries by Level & Company

Benchmark tech compensation, feed salary models, or research an offer with verified data from [Levels.fyi](https://www.levels.fyi) — the reference for levels and pay in tech.

⚡ **Scrape the full compensation ladder of any company by name or URL: one clean row per job level with median total compensation, base salary, stock grant and bonus, years-of-experience stats, submission counts, the level's meaning on the company ladder, and the whole job family's p10–p90 percentile distribution. Filter by job family and location. No login, no browser, pay per result.**

### What you get

One row per **company × job family × level**:

| Field | Example |
|---|---|
| `company`, `companySlug` | Google, `google` |
| `jobFamily` | Software Engineer |
| `level`, `levelAltName`, `levelTitles` | L4, SWE III, `["L4", "SWE III"]` |
| `totalCompensation` | 308430 |
| `baseSalary` / `stockGrant` / `bonus` / `commission` | 193095 / 92186 / 23149 / 0 |
| `salaryCount`, `salaryCountLast12Months` | 58, 826 |
| `yearsOfExperienceAvg`, `yearsOfExperienceMedian` | 5.52, 5 |
| `percentWorkforce`, `levelDescription` | 20, "L3 is the new grad role at Google" |
| `familyPercentiles` | p10–p90 for total comp, base, stock, bonus |
| `familyMedianTotalCompensation` | 284000 |
| `location`, `currency` | New York City, USD |
| `companyWebsite`, `companyHq`, `companyEmployees`, `companyTicker` | company context on every row |
| `levelUrl`, `url`, `matchedInput` | deep links + which input produced the row |

Turn on **Flatten rows** to get spreadsheet-ready columns (`family_totalComp_p50`, `family_base_p90`…) instead of nested objects.

### Inputs

| Field | Type | Default | Meaning |
|---|---|---|---|
| Company names | `companyNames` | `["Google"]` | Company names; resolved to the right Levels.fyi page automatically. |
| Company URLs | `startUrls` | — | Any Levels.fyi company page: `/companies/google/salaries`, a job family (`.../salaries/software-engineer`) or a family + location (`.../salaries/software-engineer/locations/new-york-city-area`). |
| Job families | `jobFamilies` | all | Only these families ("Software Engineer", "Product Manager", "Data Scientist"…). |
| Locations | `locations` | default scope | Scope the numbers to locations ("New York City Area", "Seattle Area", "India"…). |
| Maximum rows | `maxItems` | 500 | Total row cap — the number of results you pay for. 0 = no limit. |
| Flatten rows | `flatten` | off | Flat columns for CSV/Excel. |
| Input status report | `emitInputStatus` | on | OUTPUT lists what each input resolved to and why anything returned 0. |

### Examples — all live-verified

**1. A company's full compensation ladder**

```json
{ "companyNames": ["Google"] }
```

Every job family at Google, every level: engineering, product, data, design, sales… one row per level.

**2. Compare one role across companies**

```json
{ "companyNames": ["Google", "Meta", "Stripe"], "jobFamilies": ["Software Engineer"] }
```

The SWE ladders of three companies, side by side: L3–L8 vs E3–E8, with percentiles per family.

**3. A role in one metro area**

```json
{ "companyNames": ["Google"], "jobFamilies": ["Software Engineer"], "locations": ["New York City Area"] }
```

NYC-scoped numbers for Google SWE levels.

**4. Straight from URLs**

```json
{ "startUrls": [{ "url": "https://www.levels.fyi/companies/jpmorgan-chase/salaries/software-engineer" }] }
```

**5. Spreadsheet export for a comp review**

```json
{ "companyNames": ["Microsoft"], "jobFamilies": ["Product Manager"], "flatten": true, "maxItems": 50 }
```

### Why this scraper

- **Complete rows** — not just the headline number: base/stock/bonus split, YoE, counts, ladder meaning and family percentiles on every row.
- **Every input wired** — names, URLs, families and locations all actually filter the scrape.
- **Honest reporting** — the `input_status` report in OUTPUT tells you what each input returned and why anything came back empty.
- **Fast and cheap** — no browser: structured data read directly, hundreds of rows a minute.

### FAQ

**Is this legal?** The Actor reads only publicly displayed aggregate statistics, the same numbers any visitor sees. No accounts, no personal data, no individual submissions. You are responsible for using the output in compliance with applicable laws and Levels.fyi's terms.

**A company returns 0 rows?** Check `input_status` in the run's OUTPUT: small companies may have too few submissions for a given family, and location filters narrow the data further. Try without filters, or pass the exact company URL.

**What currency are the numbers in?** The `currency` field says — location-scoped pages are converted by Levels.fyi to the location's currency; default pages are USD.

***

Looking for more workforce data? See the rest of the family: [Indeed Salaries](https://apify.com/scrapifier/indeed-salaries-scraper), [Glassdoor Salaries](https://apify.com/scrapifier/glassdoor-salaries-scraper), [Glassdoor Company Search](https://apify.com/scrapifier/glassdoor-company-search-scraper), [Indeed Jobs](https://apify.com/scrapifier/indeed-jobs-scraper), [Upwork Jobs](https://apify.com/scrapifier/upwork-jobs-scraper).

# Actor input Schema

## `companyNames` (type: `array`):

Company names as they appear on Levels.fyi ("Google", "JPMorgan Chase"). The scraper resolves each name to the right company page automatically.

## `startUrls` (type: `array`):

Any Levels.fyi company page: https://www.levels.fyi/companies/google/salaries, a specific job family (.../salaries/software-engineer) or a family + location (.../salaries/software-engineer/locations/new-york-city-area).

## `jobFamilies` (type: `array`):

Only scrape these job families ("Software Engineer", "Product Manager", "Data Scientist"...). Leave empty for every job family the company has. Names are matched to Levels.fyi slugs automatically.

## `locations` (type: `array`):

Scope salaries to these locations ("New York City Area", "Seattle Area", "India"...), as named on Levels.fyi. Leave empty for the company's default (usually country-wide) numbers. Each location multiplies the pages scraped.

## `maxItems` (type: `integer`):

Stop after this many level rows in total — the number of results you pay for. 0 = no limit.

## `flatten` (type: `boolean`):

Emit flat columns (family_totalComp_p50, family_base_p90...) instead of nested objects, for spreadsheet-friendly exports.

## `emitInputStatus` (type: `boolean`):

Write an input_status report to OUTPUT: which companies/families resolved, how many rows each returned, and why any returned nothing.

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

Proxy to route requests through. The default Apify proxy works fine.

## Actor input object example

```json
{
  "companyNames": [
    "Google"
  ],
  "maxItems": 500,
  "flatten": false,
  "emitInputStatus": true,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

## `salaries` (type: `string`):

All per-level compensation rows extracted by this run.

# 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 = {
    "companyNames": [
        "Google"
    ],
    "maxItems": 500,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapifier/levels-fyi-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 = {
    "companyNames": ["Google"],
    "maxItems": 500,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("scrapifier/levels-fyi-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 '{
  "companyNames": [
    "Google"
  ],
  "maxItems": 500,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call scrapifier/levels-fyi-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,scrapifier/levels-fyi-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/9cuLWM5tcHQmYgkXA/builds/qwTXfMkGljrjCuqfp/openapi.json
