# Salary Data API with Pay Percentiles: Payscale Jobalyzer (`nabeelbaghoor/salary-data-api-compensation-benchmarks`) Actor

Get market salary percentiles (10th to 90th), total and hourly pay, bonus, pay by years of experience, and skill, certification and education pay premiums for any job title and location through the Payscale Jobalyzer API, plus job title matching. Bring your own key.

- **URL**: https://apify.com/nabeelbaghoor/salary-data-api-compensation-benchmarks.md
- **Developed by:** [Nabeel Hassan](https://apify.com/nabeelbaghoor) (community)
- **Categories:** Business, Developer tools, Integrations
- **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 pay reports

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

## Salary Data API with Pay Percentiles: Payscale Jobalyzer

Get market salary percentiles, pay by years of experience and the pay premium of every skill, certification and degree for any job title and location from the Payscale Jobalyzer API, with your own API key, as clean rows you can export to CSV, Excel or JSON or feed into your own app.

Payscale runs one of the largest crowdsourced compensation surveys, with tens of millions of salary profiles, and models pay ranges from the profiles that best match a job title, location, experience, education, skills and industry. Its Jobalyzer API serves that model to Data API customers. This actor wraps the Jobalyzer API on jobalyzer.payscale.com: it requests the reports, waits for them to finish, and flattens the answers into one row per job or per skill. Use it for salary benchmarking, pay range and pay transparency postings, offer letters, compensation planning, job board salary estimates and HR analytics. Bring your own API key.

BYOK, not live tested: every route, parameter and response field comes from Payscale's public developer documentation at developers.payscale.com (the Jobalyzer guides and the Swagger schema behind its API reference), and every route was probed on 2026-10-27 with invalid credentials. The actor has not been run against a live Payscale key.

### What it does

- **Pay report**: base pay, total cash compensation and hourly pay at the 10th, 25th, 50th (median), 75th and 90th percentiles, with averages, the number of matched profiles, bonus, commission and profit sharing, total companies and incumbents, the location level used and Payscale's report rating. One row per job title.
- **Pay by years of experience**: base pay percentiles and averages for each experience band of a job title (for example less than 1 year up to 8 years or more), and the experience points where pay steps up by about 15 percent.
- **Skill pay impact**: the top skills reported for a job title, with the share of profiles reporting each, its median base pay and its pay differential in USD and percent. One row per skill.
- **Certification and education pay impact**: the same for certifications (such as CPA or PMP) and education levels.
- **Job title match**: Payscale's ensemble title matcher turns any free text title into ranked confirmed Payscale titles, optionally with tasks and typical experience.
- **Answer autocomplete and location search**: the exact job titles, skills, certifications, industries, degrees and locations Payscale accepts, so reports match what you mean.
- **Test mode**: Payscale's documented test flag returns random data and spends none of your report credits, for checking an integration first.
- **Pay only for data**: empty reports, test rows and lookups Payscale refuses are recorded as a free row that says why, never charged.

### How to use it

1. Get Payscale Data API access. Jobalyzer clients are issued with a commercial Data API contract through Payscale's sales team; you receive a client ID and a client secret.
2. Paste them into the Client ID and Client secret fields, or set the DATA_API_KEY environment secret as `clientId:clientSecret`. The actor exchanges them for a short lived token at accounts.payscale.com/connect/token, as Payscale documents, and removes both from everything it logs.
3. Pick a mode, add job titles (and a country, state, city and other answers for reports) or search terms, and run. Turn on test mode for a first run that spends no report credits.
4. Download the dataset as JSON, CSV or Excel, or connect it to your workflow through the Apify API, webhooks or integrations.

Missing or rejected credentials, or an account out of report credits, end the run cleanly with a status message that explains what to change, and nothing is charged.

### Input

| Field | Modes | Description |
| --- | --- | --- |
| `mode` | all | `payReport` (default), `yearsExperienceReport`, `skillsImpact`, `certificationsImpact`, `educationImpact`, `jobTitleMatch`, `autocomplete` or `locations` |
| `jobTitles` | report, impact, match | One job title per line |
| `country`, `state`, `city` | reports | Location of the job; country is required (default United States) |
| `yearsExperience`, `highestDegreeEarned` | reports | Experience and education of the person |
| `skills`, `certifications` | reports | Payscale skill and certification names |
| `industry`, `averageSizeCompetitor`, `companySales` | reports | The competitive set of companies |
| `autoResolveJobTitle` | reports, impacts | Match free text titles to confirmed Payscale titles (default on) |
| `includeTasks` | job title match | Add tasks and typical years of experience |
| `autocompleteQuestion`, `searchTerms` | autocomplete, locations | What to search and the terms |
| `testMode` | all but autocomplete | Random data, no report credits spent, never charged |
| `maxResults`, `requestsPerMinute` | all | Row cap and pacing |
| `clientId`, `apiKey` | all | Your Payscale client ID and client secret |

### Example output

A pay report row (shortened; `record` holds the full answer with all 81 percentiles of each sub-report):

```json
{
  "mode": "payReport",
  "recordType": "payReport",
  "query": "Software Developer",
  "found": true,
  "jobTitle": "Software Developer",
  "matchedJobTitle": "Software Developer",
  "jobTitleRating": 100,
  "country": "United States",
  "state": "Washington",
  "city": "Seattle",
  "currency": "U.S. Dollar (USD)",
  "basePayP10": 52342.26,
  "basePayP25": 67851.95,
  "basePayP50": 83743.64,
  "basePayP75": 102032.42,
  "basePayP90": 121748.59,
  "basePayAverage": 86667.46,
  "basePayProfiles": 45,
  "totalCompanies": 49,
  "totalIncumbents": 3619,
  "totalProfilesAnalyzed": 51975,
  "levelUsed": "State",
  "reportRating": 0.27,
  "testData": false
}
```

A skill pay impact row:

```json
{
  "mode": "skillsImpact",
  "recordType": "skillImpact",
  "jobTitle": "Executive Assistant",
  "name": "Executive Support",
  "rank": 1,
  "profileCount": 3549,
  "percentReporting": 26.24,
  "medianBasePay": 55169.01,
  "payDifferential": 7152.97,
  "payDifferentialPercentage": 14.9,
  "currency": "USD"
}
```

### FAQ

#### What is the Payscale Jobalyzer API?

Jobalyzer is Payscale's REST API for compensation data. Given compensable factors such as job title, city, state, country, years of experience, education, skills and industry, it returns modeled pay distributions built from the best matching profiles in Payscale's salary survey, plus skill, certification and education pay impacts and title matching.

#### Do I need my own Payscale API key?

Yes. This actor is bring your own key: it calls Payscale with your client ID and client secret, and your Payscale Data API contract applies. Payscale does not offer self serve keys; access comes through its sales team.

#### Does running a report cost Payscale credits?

Yes. Payscale bills per report: each pay report and each years of experience report spends one report credit, and each impact request one more. Payscale does not bill a report whose report rating is 0. Test mode spends no credits. When the account runs out, Payscale answers that it has no reports left and this actor ends the run cleanly.

#### What do the percentiles mean?

`basePayP50` is the median base salary of the matched profiles; `basePayP10` and `basePayP90` are the 10th and 90th percentiles, the usual low and high ends of a market pay range. Total pay adds bonus, commission and profit sharing to base pay. Hourly pay is in currency per hour.

#### What is the report rating?

A score from 0 to 1 for how well the data supports the answers you gave. 1 means high confidence; 0 means sparse or conflicting data. A job title rating from 0 to 100 shows how well an auto resolved title matches the one you typed; 60 or more is generally good.

#### Why is a pay report empty?

Payscale returns empty reports when the matched profiles are too few or vary too much, for example a national report for a job whose pay follows state minimum wages, or an unusual mix of answers. Add a state or city, an industry or years of experience. Empty reports are free here.

#### How do I find skills that raise pay for a job?

Run the skill pay impact mode with the job title. Each row is one skill with its pay differential: the difference between the median base pay of profiles listing it among their top skills and the median of all profiles with that title. A negative value means the skill is common among lower paid holders of the title.

#### Which countries are covered?

Payscale reports pay in the currency of the country you set, such as United States, Canada or United Kingdom. Coverage depends on Payscale's profile data for each country and title.

#### What do I pay?

0.02 USD per pay report, 0.015 USD per years of experience report, 0.008 USD per skill, certification or education impact and 0.005 USD per job title, answer or location match, plus whatever your Payscale contract costs. Empty, test and refused lookups are free.

### Keyword map

salary data API, compensation data API, salary benchmarking API, pay percentiles, market pay data, salary range API, pay range for job postings, pay transparency data, total compensation data, hourly wage data, bonus data, pay by years of experience, skill pay premium, certification salary impact, education salary impact, job title matching API, job title normalization, HR analytics data, Payscale API, Payscale Jobalyzer, Payscale Data API.

### Routes and verification

| Mode | Route | Source | Probe with invalid credentials |
| --- | --- | --- | --- |
| Token | POST accounts.payscale.com/connect/token | Access patterns guide | 400 `{"error":"invalid_client"}`; invented /connect/tokenz 302 |
| Pay and experience reports | POST /jobalyzer/v2/reports | Swagger schema and guides | 401; invented /jobalyzer/v2/reportz 404 |
| Report results | GET /jobalyzer/v2/reports/{ReportId}/pay and /yoe (the returned link) | Swagger schema and guides | 401 |
| Skill pay impact | GET /jobalyzer/v2/impact/skills | Swagger schema | 401; invented /jobalyzer/v2/impactz/skills 404 |
| Certification pay impact | GET /jobalyzer/v2/impact/certs | Swagger schema | 401 |
| Education pay impact | GET /jobalyzer/v2/impact/education | Swagger schema | 401 |
| Job title match | GET /jobalyzer/v2/jobtitlematch | Swagger schema and matching guide | 401 |
| Autocomplete | GET /jobalyzer/v2/autocomplete/{QuestionId} | Matching guide | 401 |
| Location search | GET /jobalyzer/v2/locations/{SearchTerm} | Swagger schema | 401 |

Each probe was repeated with the same result. Report answers are fetched only from links on jobalyzer.payscale.com that point at its own report route. Usage export routes and the other report types named in the schema are not wrapped.

### Licensing and data use

This actor works only with your own Payscale API client, and your Data API agreement with Payscale governs how you may store, display and share its data. Check that agreement before you republish salary figures. This actor is not affiliated with or endorsed by Payscale, Inc.

# Actor input Schema

## `mode` (type: `string`):

Pay report gives base, total and hourly pay percentiles, bonus, commission and profit sharing for each job title and location. Pay by years of experience gives base pay percentiles per experience band. The pay impact modes list the skills, certifications or education levels of a job title with the pay premium of each. Job title match and answer autocomplete find the exact Payscale titles, skills and other answers to use; location search finds locations.

## `jobTitles` (type: `array`):

Report, pay impact and job title match modes. One job title per line. Payscale titles such as Software Developer work best; with auto resolve on, a free text title is matched to the closest confirmed title first.

## `country` (type: `string`):

Report modes. The country of the job, required by Payscale, such as United States, Canada or United Kingdom.

## `state` (type: `string`):

Report modes. Optional. The state or province in full, such as Washington or Ontario.

## `city` (type: `string`):

Report modes. Optional. The city, such as Seattle. Set the state too.

## `yearsExperience` (type: `integer`):

Report modes. Optional. Years of experience in the field; it changes the pay report.

## `highestDegreeEarned` (type: `string`):

Report modes. Optional. The education level, from Payscale's list.

## `skills` (type: `array`):

Report modes. Optional. Skills of the role, one per line, as Payscale names them (the autocomplete mode with Skills lists them).

## `certifications` (type: `array`):

Report modes. Optional. Certifications of the role, one per line, as Payscale names them.

## `industry` (type: `string`):

Report modes. Optional. The industry that defines the competing companies (Payscale's EmployerProductActivity), such as Software Development.

## `averageSizeCompetitor` (type: `integer`):

Report modes. Optional. The number of employees at companies competing for this hire, such as 5000.

## `companySales` (type: `integer`):

Report modes. Optional. Your company's estimated revenue this year, such as 3000000.

## `autoResolveJobTitle` (type: `boolean`):

Report and pay impact modes. Match each job title to the closest confirmed Payscale title before running. The matched title and its rating appear in each row.

## `includeTasks` (type: `boolean`):

Job title match mode. Also ask Payscale for the tasks of each matched title and typical years of experience.

## `autocompleteQuestion` (type: `string`):

Autocomplete mode. Which kind of answer to search. Job titles need at least 4 characters, skills and industries 2.

## `searchTerms` (type: `array`):

Autocomplete and location search modes. One search term per line, such as software, python or Seattle.

## `testMode` (type: `boolean`):

Send Payscale's documented test flag: it returns random data that ignores your answers and spends no Payscale report credits. Good for checking an integration. Test rows are never charged. Not used by autocomplete.

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

The most rows this run returns and charges for.

## `requestsPerMinute` (type: `integer`):

Pacing for calls to Payscale. Throttled calls are retried after a pause.

## `clientId` (type: `string`):

The client ID Payscale issued for your Jobalyzer API access. Stored as a secret. It is also sent as the documented CustomerId and User values.

## `apiKey` (type: `string`):

The client secret of the same Payscale API client. Stored as a secret, sent only to Payscale's token endpoint and never logged. You can instead set the DATA_API_KEY environment secret as clientId:clientSecret.

## Actor input object example

```json
{
  "mode": "payReport",
  "jobTitles": [
    "Software Developer"
  ],
  "country": "United States",
  "autoResolveJobTitle": true,
  "includeTasks": false,
  "autocompleteQuestion": "JobTitle",
  "testMode": false,
  "maxResults": 100,
  "requestsPerMinute": 120
}
```

# Actor output Schema

## `records` (type: `string`):

One row per report, pay impact or match the chosen mode read.

# 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 = {
    "jobTitles": [
        "Software Developer"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/salary-data-api-compensation-benchmarks").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 = { "jobTitles": ["Software Developer"] }

# Run the Actor and wait for it to finish
run = client.actor("nabeelbaghoor/salary-data-api-compensation-benchmarks").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 '{
  "jobTitles": [
    "Software Developer"
  ]
}' |
apify call nabeelbaghoor/salary-data-api-compensation-benchmarks --silent --output-dataset

```

## MCP server setup

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

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/DfSd6zUIABvUgvI7D/builds/7ikYsu5LGRt6jACCK/openapi.json
