# Tech Salary Data API: Pay Ranges from Job Postings (`worthwhile_quinsy/tech-salary-data-api`) Actor

Salary benchmarks from posted pay ranges: median, P25 and P75 by role, country and seniority, from 47,000+ live job posts refreshed every day.

- **URL**: https://apify.com/worthwhile\_quinsy/tech-salary-data-api.md
- **Developed by:** [Eki Soka](https://apify.com/worthwhile_quinsy) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $20.00 / 1,000 salary benchmarks

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## Tech Salary Data API: pay ranges from fresh job postings

Get **salary benchmarks** built from thousands of open job postings that publish a pay range, taken straight from companies' own job boards (**Greenhouse, Ashby, Lever, Workable, Recruitee, SmartRecruiters, BambooHR, Personio**) and refreshed every day.

One row per role (and optionally country, seniority or company) with the **median, P25, P75, average min/max and range**, the number of postings and companies behind it, and example companies.

**Database today:** about 48,000 open jobs from 1,250+ company job boards; postings with a published pay range feed the benchmarks.

### Who uses it

- **HR and compensation teams:** check current market pay for a role before opening it or making an offer.
- **Founders and hiring managers:** set salary bands from what similar companies actually publish.
- **Job boards, newsletters and career sites:** show "typical pay" for a role.
- **Researchers and analysts:** pay-transparency and labour-market studies.

### Examples

Software engineer pay by country:

```json
{ "keywords": ["software engineer", "backend engineer"], "groupBy": "role_country" }
```

Data roles in the US, split by seniority, USD only:

```json
{ "keywords": ["data scientist", "data engineer"], "countries": ["US"], "currencies": ["USD"], "groupBy": "role_country_seniority" }
```

Which companies pay most for account executives:

```json
{ "keywords": ["account executive"], "groupBy": "company", "minSamples": 1 }
```

### Output

| Field | Example |
| --- | --- |
| `role`, `country`, `seniority`, `company` | Backend Engineer, US, senior |
| `currency`, `period` | USD, year |
| `salary_median`, `salary_p25`, `salary_p75` | 165000, 148000, 182000 |
| `salary_median_by_company` | 158000: median of each company's own median, so one company posting many roles does not set the benchmark |
| `salary_min_avg`, `salary_max_avg`, `salary_lowest`, `salary_highest` | averages and extremes of the posted ranges |
| `sample_size`, `companies` | 37 postings from 29 companies |
| `remote_share`, `top_companies`, `sample_titles`, `sample_job_urls` | context and links to source postings |

Salaries are converted to **per year** (hourly x 2080, monthly x 12) but **never converted between currencies**: each currency gets its own row. `median` uses the midpoint of each posted range. When a few companies post many roles (for example frontier AI labs), compare `salary_median` with `salary_median_by_company`: the second counts every company once.

### Pricing

Pay per event: one **salary benchmark row**. A run that finds nothing charges nothing. Use **Max results** or Apify's maximum cost per run to cap spend.

### Coverage and limits

- Only postings that publish a pay range are used (common in the US, Canada, UK and for many remote roles; rarer elsewhere).
- Roles are grouped by a cleaned job title (seniority words removed). Use keywords to define the role you want.
- `seniority` and `country` are derived from the posting with rules, so treat them as good filters, not perfect labels.
- Pay ranges come from the structured salary fields of Ashby, Lever and Recruitee and from the pay-range sentence in the job text for Greenhouse, Workable, Personio and others (for example "Salary: $150,000 - $200,000/yr").
- Sales postings often publish on-target earnings (base + commission). Those OTE ranges are **left out by default** so the benchmarks show base pay; set `includeOte` to include them.

### FAQ

**Where does the data come from?** The official public job board endpoints that companies use for their own career pages, read once a day at a low request rate.

**How fresh is it?** Refreshed daily; closed jobs drop out on the next refresh.

**Can I integrate it?** Yes: call it through the Apify API, schedule it, or connect it to Make, Zapier, n8n, Google Sheets or webhooks.

### Data and use

Only public job-posting data, aggregated. No personal data.

### What you can do with it

- Get salary data for software engineers, product managers, designers and sales roles
- Compare pay by country and currency (US, Canada, UK, Germany and more)
- Benchmark compensation by seniority: junior, mid, senior, staff, manager
- See what a specific company publishes for a role (group by company)
- Set salary bands from real posted pay ranges, refreshed daily
- Export salary benchmarks to CSV, Google Sheets or BI tools

### What it costs

| Example | Cost |
| --- | --- |
| 20 salary benchmarks | about $0.40 |
| 100 salary benchmarks | about $2.00 |

You only pay for rows you get. Set **Max results** (or a maximum cost per run in Apify) to cap spend. Apify's free plan includes monthly credit, so you can try it at no cost. Apify subscribers get automatic Store discounts on some events.

### Use it from code, no-code tools or AI agents

**Python** (`pip install apify-client`):

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("worthwhile_quinsy/tech-salary-data-api").call(run_input={'keywords': ['software engineer'], 'groupBy': 'role_country', 'maxResults': 20})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)
```

**JavaScript / Node.js** (`npm install apify-client`):

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

const client = new ApifyClient({ token: 'YOUR_APIFY_TOKEN' });
const run = await client.actor('worthwhile_quinsy/tech-salary-data-api').call({"keywords": ["software engineer"], "groupBy": "role_country", "maxResults": 20});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

**One HTTP call** (returns the rows directly):

```bash
curl -X POST 'https://api.apify.com/v2/acts/worthwhile_quinsy~tech-salary-data-api/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"keywords": ["software engineer"], "groupBy": "role_country", "maxResults": 20}'
```

**No-code:** connect it to **Make, Zapier, n8n, Google Sheets, Slack** or a **webhook** from the Integrations tab, and run it on a **Schedule** (for example every morning).

**AI agents (MCP):** use it as a tool in Claude, ChatGPT, Cursor or any MCP client through the Apify MCP server: `https://mcp.apify.com?tools=worthwhile_quinsy/tech-salary-data-api`. Your agent can then ask for live job data in plain language. Use this tool when the user asks for typical salary or pay range for a role, country or seniority.

### More tools from the same job-data suite

All of these read the same daily database of jobs from company career pages, so results are consistent across tools.

| Actor | What it gives you |
| --- | --- |
| [Company Jobs Search + Hiring Signals](https://apify.com/worthwhile_quinsy/ats-jobs-search) | Search all jobs in the database, check your own list of companies, or get per-company hiring signals. |
| [Remote Jobs API](https://apify.com/worthwhile_quinsy/remote-jobs-api) | Only remote jobs, ready for job boards, newsletters and alert bots. |
| [Companies Hiring by Tech Stack](https://apify.com/worthwhile_quinsy/companies-hiring-by-tech-stack) | B2B buying signals: which companies are hiring for the tools you sell into. |
| [Company Hiring Trends](https://apify.com/worthwhile_quinsy/company-hiring-trends) | Which companies are ramping up hiring, and which are slowing down. |
| [ATS Detector](https://apify.com/worthwhile_quinsy/ats-detector) | Which applicant tracking system (Greenhouse, Lever, Ashby...) a company uses, plus its career page. |
| [Greenhouse Jobs Scraper](https://apify.com/worthwhile_quinsy/greenhouse-jobs-scraper) | All open jobs from any Greenhouse job board, or search every Greenhouse board we track. |
| [Lever Jobs Scraper](https://apify.com/worthwhile_quinsy/lever-jobs-scraper) | All open jobs from any Lever job board, or search every Lever board we track. |
| [Ashby Jobs Scraper](https://apify.com/worthwhile_quinsy/ashby-jobs-scraper) | All open jobs from any Ashby job board, or search every Ashby board we track. |

### Questions and feedback

Found a bug, need another filter, field or ATS? Open an **Issue** on this Actor's page; issues are answered quickly. If it saved you time, a short **review** helps other people find it.

# Actor input Schema

## `keywords` (type: `array`):

Keep roles whose title contains any of these, e.g. 'software engineer', 'data scientist', 'account executive'.

## `excludeKeywords` (type: `array`):

Drop roles whose title contains any of these, e.g. 'intern', 'manager'.

## `countries` (type: `array`):

Country names or 2-letter codes, e.g. 'United States', 'DE', 'Singapore'. Derived from the posting's location.

## `seniority` (type: `array`):

Heuristic level from the job title.

## `technologies` (type: `array`):

Keep roles that mention any of these tools, e.g. 'Python', 'React', 'Snowflake'.

## `departments` (type: `array`):

Keep roles whose department or team contains any of these, e.g. 'Engineering', 'Sales'.

## `remoteOnly` (type: `boolean`):

Only use postings marked remote.

## `currencies` (type: `array`):

Only these currencies, e.g. 'USD', 'EUR', 'GBP'. Postings are never converted between currencies.

## `includeOte` (type: `boolean`):

Sales postings often publish on-target earnings (base + commission). They are left out by default so the benchmarks show base pay; turn this on to include them.

## `groupBy` (type: `string`):

How to group postings into benchmark rows.

## `minSamples` (type: `integer`):

Only return benchmarks based on at least this many postings.

## `maxResults` (type: `integer`):

Maximum benchmark rows to return (each row is billed).

## Actor input object example

```json
{
  "keywords": [
    "software engineer"
  ],
  "remoteOnly": false,
  "includeOte": false,
  "groupBy": "role_country",
  "minSamples": 3,
  "maxResults": 100
}
```

# Actor output Schema

## `benchmarks` (type: `string`):

No description

# 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 = {
    "keywords": [
        "software engineer"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("worthwhile_quinsy/tech-salary-data-api").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 = { "keywords": ["software engineer"] }

# Run the Actor and wait for it to finish
run = client.actor("worthwhile_quinsy/tech-salary-data-api").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 '{
  "keywords": [
    "software engineer"
  ]
}' |
apify call worthwhile_quinsy/tech-salary-data-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,worthwhile_quinsy/tech-salary-data-api"
        }
    }
}
```

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/e4BnOa7p5RypuUtOO/builds/77Xj9FxfybVWSq31z/openapi.json
