# Levels.fyi Salary Scraper (`axiomworks/levels-fyi-salary-scraper`) Actor

Scrapes Levels.fyi salary pages and organizes public pay data into records for each job level. Results include company and job-family details, location, total compensation, base, stock, bonus, currency, and percentile ranges. Use company names, slugs, or supported Levels.fyi URLs as inputs.

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

## Pricing

from $2.38 / 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

**Returns:** one row per job level with `company`, `jobFamily`, `location`, `level`, `currency`, `totalCompensation`, `baseSalary`, `sourceUrl`.
**Input:** `{"companies": ["google"], "jobFamilies": ["software-engineer"], "maxItems": 10}`
**Best for:** compensation benchmarking, salary band research for job offers, and HR or recruiting market reports.

```json
{
    "company": "Google",
    "jobFamily": "Software Engineer",
    "location": "United States",
    "level": "L3",
    "currency": "USD",
    "totalCompensation": 209680,
    "baseSalary": 154958,
    "sourceUrl": "https://www.levels.fyi/companies/google/salaries/software-engineer"
}
```

### What does Levels.fyi Salary Scraper do?

Levels.fyi Salary Scraper is a Levels.fyi scraper and unofficial Levels.fyi API alternative that collects public compensation data for a company, job family and location. For each page it returns one record per job level, such as L3, L4 or L5 at Google, with total compensation, base salary, stock and bonus, plus the percentile ranges for the whole job family. It needs no login and reads only pages that are public.

Each record stands alone. The job-family percentiles (p10, p25, p50, p75 and p90 for total compensation, base salary, stock and bonus) are repeated on every level record of the page, so you can load the dataset into a spreadsheet or database and filter by level without joining tables. Amounts are given twice: in the local currency of the location (for example GBP for the United Kingdom) and in US dollars.

The Actor is a good fit for three jobs. Compensation teams can benchmark pay bands across companies and levels. Candidates and recruiters can check what a level pays in a given city or country before negotiating. Analysts can build market reports by scraping many companies and job families on a schedule and tracking how the figures move.

You can start from company names, from company slugs, or from Levels.fyi URLs. You can also ask for every job family a company lists by passing `all`, and add locations such as `new-york-city-area`, `san-francisco-bay-area`, `united-kingdom` or `india`.

### What data can you get from Levels.fyi?

Every record has the fields below. Fields the page does not provide are returned as `null`.

| Field | Description | Example |
|---|---|---|
| `id` | Stable record ID: company slug, job family slug, location slug and level slug joined with `\|` | `google\|software-engineer\|united-kingdom\|l3` |
| `sourceUrl` | The Levels.fyi page the record came from | `https://www.levels.fyi/companies/google/salaries/software-engineer/locations/united-kingdom` |
| `company` | Company name | `Google` |
| `companySlug` | Company slug | `google` |
| `jobFamily` | Job family name | `Software Engineer` |
| `jobFamilySlug` | Job family slug | `software-engineer` |
| `location` | Location the figures apply to | `United Kingdom` |
| `locationSlug` | Location slug | `united-kingdom` |
| `locationType` | Kind of location: `dma`, `country` or `city` | `country` |
| `countryCode` | ISO country code | `GB` |
| `level` | Primary level name | `L3` |
| `levelSlug` | Level slug | `l3` |
| `levelTitles` | Titles used for the level | `["L3", "SWE II"]` |
| `levelIndex` | Position of the level, 0 is the most junior | `0` |
| `levelUrl` | Levels.fyi page for the level | `https://www.levels.fyi/companies/google/salaries/software-engineer/levels/l3` |
| `currency` | Currency of the local amounts | `GBP` |
| `exchangeRateFromUsd` | Rate used to convert USD to local currency | `0.756` |
| `totalCompensation` | Average yearly total compensation, local currency | `117611` |
| `baseSalary` | Average base salary, local currency | `89438` |
| `stock` | Average yearly stock value, local currency | `22589` |
| `bonus` | Average yearly bonus, local currency | `5585` |
| `totalCompensationUsd` | Average yearly total compensation in USD | `155570` |
| `baseSalaryUsd` | Average base salary in USD | `118304` |
| `stockUsd` | Average yearly stock value in USD | `29879` |
| `bonusUsd` | Average yearly bonus in USD | `7388` |
| `submissionCount` | Salary submissions behind the level figures | `38` |
| `submissionsLast12Months` | Submissions in the last 12 months | `39` |
| `yearsOfExperienceMedian` | Median years of experience | `2` |
| `yearsOfExperienceAvg` | Average years of experience | `3` |
| `jobFamilyMedianTotal` | Median total compensation of the job family, local currency | `151217` |
| `jobFamilyMedianTotalUsd` | Median total compensation of the job family in USD | `200021.89` |
| `totalCompensationPercentiles` | p10, p25, p50, p75, p90 of total compensation, local currency | `{"p10": 131669, "p50": 151216}` |
| `baseSalaryPercentiles` | Base salary percentiles, local currency | `{"p10": 91770, "p50": 108023}` |
| `stockPercentiles` | Stock percentiles, local currency | `{"p10": 19183, "p50": 40471}` |
| `bonusPercentiles` | Bonus percentiles, local currency | `{"p10": 0, "p50": 14171}` |
| `percentileSampleSize` | Submissions behind the percentiles | `1200` |
| `companyTotalSubmissions` | All-time submissions for the company and job family | `12000` |
| `vestingSchedule` | Stock vesting schedule listed for the company | `25/12,25/12,25/12,25/12` |
| `companyIndustry` | Reported industry | `Tech` |
| `companyEmployeeCountRange` | Reported employee range | `10,001+` |
| `companyTicker` | Reported ticker | `GOOG` |
| `companyCareerUrl` | Careers link, not visited | `https://careers.google.com/` |
| `companyHeadquartersCity` | Headquarters city | `Mountain View` |
| `companyWebsite` | Company website | `https://www.google.com` |
| `recentSubmissions` | Anonymous recent submissions for the level, only when enabled | `[{"level": "L3", "totalCompensation": 125702.58}]` |
| `scrapedAt` | ISO timestamp of the scrape | `2026-10-03T10:00:00.000Z` |

When `includeRecentSubmissions` is enabled, each sample also includes nullable `isRedacted`, copied from the source. A value of `true` means Levels.fyi withheld details such as title, location, experience and compensation components. Those details remain `null`; total compensation can still be available. The Actor does not reconstruct withheld information. Recent submission amounts remain in USD.

Local-currency amounts are the USD figures from the page multiplied by the page's own exchange rate and rounded, which matches what Levels.fyi displays. The raw USD values are always included next to them.

Company context comes from the same salary page, without extra requests. Missing profile values are null. Set `minSubmissionCount` to require a minimum number of reports behind each level, alongside the existing level and compensation filters. This uses `submissionCount`, not the separate last-year count; it is a sample-size filter, not a guarantee of statistical reliability. The default 0 keeps all levels.

### How to use Levels.fyi Salary Scraper

1. Open the Actor in Apify Console and go to the Input tab.
2. Enter one or more companies, for example `google` or `Meta`, or paste Levels.fyi salary URLs into the URLs field.
3. Set the job families (default `software-engineer`) and, if you want, locations. Leave locations empty for the United States.
4. Set `maxItems` to the number of level records you want and start the run.
5. When the run finishes, open the Output tab and export the dataset as JSON, CSV, Excel, XML or HTML, or read it through the API.

Tips:

Each company, job family and location combination is one page. Many companies have 5 to 12 levels, so 10 pages usually give 50 to 120 records.
Use `all` as the job family to scrape every job family a company lists.
If a company name returns a not-found message, copy the URL from the site instead of typing the name. Names are converted to slugs automatically, but a few companies use a different slug.
Pages with too few submissions have no level data and are skipped with a warning in the log.
A proxy is not normally needed. Switch on Apify Proxy in the Advanced section only if requests start being blocked.

### Input

| Field | Type | Required | Description |
|---|---|---|---|
| `companies` | array of strings | Yes, unless `startUrls` is given | Company slugs, names or Levels.fyi company URLs, e.g. `google`, `Meta`. |
| `jobFamilies` | array of strings | No | Job family slugs or names, e.g. `software-engineer`, `Product Manager`. Use `all` for every job family the company lists. Default `["software-engineer"]`. |
| `locations` | array of strings | No | Location slugs or names, e.g. `new-york-city-area`, `united-kingdom`, `india`. Empty means the United States. |
| `startUrls` | array | No | Levels.fyi salary page URLs, as strings or `{url}` objects. A company URL expands to all job families. A level URL keeps only that level. |
| `maxItems` | integer | No | Maximum number of records, 1-10000, default 50. |
| `levels` | array | No | Only return these levels, by name or slug, e.g. `L5` or `Senior Software Engineer`. Default: all levels. |
| `minSubmissionCount` | integer | No | Minimum level submission count; default 0 disables filtering |
| `minTotalCompensationUsd` | integer | No | Skip levels whose average total compensation is below this USD amount. Default: no filter. |
| `includeRecentSubmissions` | boolean | No | Adds `recentSubmissions` to each record. Default false. |
| `proxyConfiguration` | object | No | Proxy settings. Default: no proxy. |

At least one of `companies` or `startUrls` must be given. If both are given, both are scraped, with duplicate IDs saved once and one shared `maxItems` budget. Plain company names use `jobFamilies` and `locations`; explicit salary URLs use the family and location in their path. Company-only URLs expand all families. The `levels` filter matches primary names or slugs, not every alternate title. If no rows match, remove `levels`, lower `minTotalCompensationUsd`, or check the company, job family and location slugs. Persistent blocks require retrying later or enabling `proxyConfiguration`.

```json
{
    "companies": ["amazon"],
    "jobFamilies": ["data-scientist", "product-manager"],
    "locations": ["new-york-city-area"],
    "startUrls": [
        { "url": "https://www.levels.fyi/companies/stripe/salaries/product-manager" }
    ],
    "maxItems": 50,
    "includeRecentSubmissions": false,
    "proxyConfiguration": { "useApifyProxy": false }
}
```

### Output

The dataset has one item per level. This trimmed record came from the local Google software-engineer prefill run on 2026-10-13. Salary values can change between runs:

```json
{
    "id": "google|software-engineer|united-states|l3",
    "company": "Google",
    "companySlug": "google",
    "jobFamily": "Software Engineer",
    "jobFamilySlug": "software-engineer",
    "location": "United States",
    "locationSlug": "united-states",
    "locationType": "country",
    "countryCode": "US",
    "level": "L3",
    "levelSlug": "l3",
    "levelTitles": [
        "L3",
        "SWE II"
    ],
    "levelIndex": 0,
    "levelUrl": "https://www.levels.fyi/companies/google/salaries/software-engineer/levels/l3",
    "currency": "USD",
    "exchangeRateFromUsd": 1,
    "totalCompensation": 209680,
    "baseSalary": 154958,
    "stock": 40007,
    "bonus": 14714,
    "totalCompensationUsd": 209680,
    "baseSalaryUsd": 154958,
    "stockUsd": 40007,
    "bonusUsd": 14714,
    "submissionCount": 60,
    "submissionsLast12Months": 780,
    "yearsOfExperienceMedian": 2,
    "yearsOfExperienceAvg": 2.73,
    "jobFamilyMedianTotal": 281000,
    "jobFamilyMedianTotalUsd": 281000,
    "totalCompensationPercentiles": {
        "p10": 177500,
        "p25": 212000,
        "p50": 281000,
        "p75": 393000,
        "p90": 535000
    },
    "baseSalaryPercentiles": {
        "p10": 144000,
        "p25": 164000,
        "p50": 196000,
        "p75": 230000,
        "p90": 250000
    },
    "stockPercentiles": {
        "p10": 30000,
        "p25": 40000,
        "p50": 70000,
        "p75": 150000,
        "p90": 250000
    },
    "bonusPercentiles": {
        "p10": 0,
        "p25": 0,
        "p50": 24000,
        "p75": 43000,
        "p90": 57000
    },
    "percentileSampleSize": 176,
    "companyTotalSubmissions": 23436,
    "vestingSchedule": "38/12,32/12,20/12,10/12|33/12,33/12,22/12,12/12|50/12,28/12,12/12,10/12|36/12,28/12,20/12,16/12|25/12,25/12,25/12,25/12|25/4,25/4,25/4,25/4|33/4,33/4,34/4",
    "companyWebsite": "https://www.google.com",
    "scrapedAt": "2026-10-13T10:31:08.506Z",
    "sourceUrl": "https://www.levels.fyi/companies/google/salaries/software-engineer"
}
```

You can download the data as JSON, CSV, Excel, XML or HTML from the dataset page, and the Overview view shows the most useful columns.

### How much does it cost to scrape Levels.fyi?

Levels.fyi Salary Scraper is charged per result. You pay only for the records returned, and `maxItems` caps how many that can be, so a run can never go past the limit you set. See the Pricing tab for the current price. The Actor makes about one request per second and one request returns all levels of a page, so runs are quick and use little compute.

### Use with AI agents (MCP)

Connect Levels.fyi Salary Scraper to Claude, Cursor or any MCP client through the Apify MCP server:

```json
{
    "mcpServers": {
        "apify": {
            "url": "https://mcp.apify.com/?tools=axiomworks/levels-fyi-salary-scraper"
        }
    }
}
```

Example prompts:

1. "Get the total compensation by level for software engineers at Google and Meta from Levels.fyi."
2. "Compare product manager base salary and stock at Stripe in the United Kingdom and the United States on Levels.fyi."
3. "Scrape every job family at Amazon in the New York City area from Levels.fyi and list the ten highest median totals."

### Integrations and API

Run Levels.fyi Salary Scraper from your own code with the Apify API. Set `APIFY_TOKEN` to your Apify API token (send it in the `Authorization` header, never in the URL).

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run = client.actor("axiomworks/levels-fyi-salary-scraper").call(
    run_input={"companies": ["google"], "jobFamilies": ["software-engineer"], "maxItems": 50}
)
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["level"], item["totalCompensation"], item["currency"])
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });
const run = await client.actor('axiomworks/levels-fyi-salary-scraper').call({
    companies: ['google'],
    jobFamilies: ['software-engineer'],
    maxItems: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
```

**cURL**

```bash
curl -X POST "https://api.apify.com/v2/acts/axiomworks~levels-fyi-salary-scraper/run-sync-get-dataset-items" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"companies": ["google"], "jobFamilies": ["software-engineer"], "maxItems": 50}'
```

The Integrations tab connects the Actor to Make, Zapier, n8n, Google Sheets and webhooks, and you can put it on a schedule to track pay changes over time.

### FAQ

**How many records will I get?**
One record per level for each company, job family and location page. Companies usually have between 3 and 12 levels per job family. The run stops when it reaches `maxItems`.

**What currency are the amounts in?**
The fields `totalCompensation`, `baseSalary`, `stock` and `bonus` use the currency in the `currency` field, which follows the location you chose. The fields ending in `Usd` always use US dollars.

**Are these individual salaries?**
No. The per-level numbers are aggregates that Levels.fyi computes from anonymous submissions. Individual entries are only returned when you turn on `includeRecentSubmissions`, and they are anonymous as well.

**Why did my run return 0 results?**
The company, job family or location slug probably does not exist, or the page has too few submissions to show levels. The run still finishes successfully and the status message names the page that was not found. Check the slug on the site and paste the URL into `startUrls`.

**How fresh is the data?**
Each run reads the live page, so the figures are as current as the site. The `scrapedAt` field tells you when a record was collected.

**Do I need a proxy?**
Usually not. Requests are plain page loads at a modest rate. If the site starts blocking, enable Apify Proxy and blocked requests are retried on a new IP.

**Can I scrape one level only?**
Yes. Put a level URL such as `https://www.levels.fyi/companies/google/salaries/software-engineer/levels/l5` into `startUrls` and only that level is returned.

**Why is a field null?**
Some pages do not publish every number, for example the vesting schedule of small companies. Those fields are returned as `null` and never filled with guesses.

### Is it legal to scrape Levels.fyi?

The Actor collects only data that is publicly visible without logging in. The salary figures are anonymous aggregates and the Actor does not collect personal data. You are responsible for how you use the data, including compliance with the website's terms and applicable laws such as GDPR. This is not legal advice. This Actor is an independent tool and is not affiliated with or endorsed by Levels.fyi.

### Feedback

Found a bug or need a field that isn't here? Open an issue on the Issues tab and we'll look at it.

# Actor input Schema

## `companies` (type: `array`):

Company names, slugs or Levels.fyi company URLs, e.g. \["google", "Meta"]. Supply companies or startUrls; both are combined. Names are slugified; for a 404, paste the site URL. Salary URLs with a job family use that family; company-only URLs expand all families. Plain names use jobFamilies and locations.

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

Job family names or slugs for plain company names, e.g. \["software-engineer", "Product Manager"]. Default \["software-engineer"]. Use \["all"] to expand each company overview. Explicit startUrls and company URLs use the family in the URL; company-only URLs expand all families.

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

Location names or slugs for plain company targets, e.g. \["united-kingdom", "new-york-city-area"]. Default \[] uses United States. Each company x job family x location is a page. Explicit salary URLs use their own location; company-only URLs expand families across these locations.

## `levels` (type: `array`):

Level names or slugs to keep on every target, e.g. \["L5", "e6"]. Matches primary level names or slugs, case-insensitively; not every alternate title. Default \[] keeps all levels. A level URL additionally restricts to its URL level. If no levels match, returns zero rows successfully; remove this filter or check the level slug.

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

Levels.fyi company or salary URLs, e.g. \[{"url":"https://www.levels.fyi/companies/google/salaries/software-engineer"}]. Supply this or companies; both are combined. Company-only URLs expand all families, /levels/{slug} keeps one level, /locations/{slug} selects a location. Query/hash and .md are stripped. Default \[].

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

Maximum level rows across all companies, URLs, job families and locations combined: 1-10000, default 50, e.g. 10. Duplicate IDs are saved once. Stops at this shared cap; fewer rows are returned when data is unavailable or filters exclude levels. Only saved rows are charged.

## `includeRecentSubmissions` (type: `boolean`):

Set true to add available anonymous recentSubmissions to each level row, e.g. true; default false returns null. Submission amounts are USD, even when aggregate rows use another currency. Unavailable or source-redacted submission values remain null. Does not change the one-row-per-level result count.

## `minTotalCompensationUsd` (type: `integer`):

Minimum aggregate annual totalCompensationUsd to keep a level, e.g. 200000. Applies across all targets alongside levels. Default 0 (or omitted) disables this filter. Compared in USD regardless of the location currency. If every level is below the threshold, returns zero rows successfully; lower or remove the threshold.

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

Proxy options, e.g. {"useApifyProxy":false} (default: direct requests). Enable {"useApifyProxy":true} to use Apify Proxy for requests and fresh-session retries on blocks. Persistent blocks return no rows for that target and the run continues; retry later or enable a proxy. No login or CAPTCHA solving.

## `minSubmissionCount` (type: `integer`):

Minimum submissionCount required for each level row, e.g. 20. Default 0 disables this filter. Uses the source level count, not submissionsLast12Months or the job-family percentile sample size. Combined with levels and minTotalCompensationUsd before maxItems. Missing counts are excluded when enabled; no matches returns zero rows successfully.

## Actor input object example

```json
{
  "companies": [
    "google"
  ],
  "jobFamilies": [
    "software-engineer"
  ],
  "locations": [],
  "levels": [],
  "startUrls": [],
  "maxItems": 10,
  "includeRecentSubmissions": false,
  "minTotalCompensationUsd": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  },
  "minSubmissionCount": 0
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset with one item per result, in the order found.

# 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 = {
    "companies": [
        "google"
    ],
    "jobFamilies": [
        "software-engineer"
    ],
    "maxItems": 10,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("axiomworks/levels-fyi-salary-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 = {
    "companies": ["google"],
    "jobFamilies": ["software-engineer"],
    "maxItems": 10,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("axiomworks/levels-fyi-salary-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 '{
  "companies": [
    "google"
  ],
  "jobFamilies": [
    "software-engineer"
  ],
  "maxItems": 10,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call axiomworks/levels-fyi-salary-scraper --silent --output-dataset

```

## MCP server setup

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