Pay Band Calculator — Salary Ranges from Your Own Job Data avatar

Pay Band Calculator — Salary Ranges from Your Own Job Data

Pricing

from $4.00 / 1,000 pay bands

Go to Apify Store
Pay Band Calculator — Salary Ranges from Your Own Job Data

Pay Band Calculator — Salary Ranges from Your Own Job Data

Salary bands from job data you already have: median and p10-p90 yearly pay by department, seniority, title or location, split by currency. Give numbers or whole posting text; bonuses are not read as pay. For pay equity and offers. No scraping.

Pricing

from $4.00 / 1,000 pay bands

Rating

0.0

(0)

Developer

Northbell

Northbell

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

5 hours ago

Last modified

Share

Pay Band Calculator

You already have the job data — your own openings, an ATS export, a competitor feed, the output of a job scraper. What you need is the band: what does a senior engineer get here, what does the middle 80% look like, and how many jobs is that based on. Give this Actor the jobs, with the pay as numbers or as the posting text, and get median, p10, p25, p75 and p90 yearly pay per department, seniority, title or location — one band per currency, never mixed. Nothing is scraped: the Actor only reads what you send.

$0.005 per band ($5 per 1,000 bands), plus $0.01 per run.

The last step of a three-step job data toolkit. Each step reads data you already have:

  1. Job Posting Parser: posting text → pay, skills, remote, visa
  2. Job Title Normalizer: title → department, seniority, core title
  3. Pay Band Calculator (this one): jobs → median and p10–p90 yearly pay per group

The rows of the Job Posting Parser and of our LinkedIn Salary Scraper go in as they are, and so do other scrapers' rows that have title and description.

Example

Input (five jobs: numbers, an hourly rate, and one posting given as text):

{
"postings": [
{ "title": "Senior Software Engineer", "location": "Austin, TX", "salaryMin": 150000, "salaryMax": 185000, "currency": "USD", "period": "year" },
{ "title": "Software Engineer II", "location": "Remote, US", "salaryMin": 120000, "salaryMax": 150000, "currency": "USD" },
{ "title": "Sr. Software Engineer (Backend)", "location": "New York, NY", "description": "The base salary range for this role is $165,000 - $200,000 per year. Sign-on bonus: $15,000." },
{ "title": "Software Engineer", "location": "Denver, CO", "salaryMin": 55, "salaryMax": 65, "currency": "USD", "period": "hour" },
{ "title": "Product Manager", "location": "Austin, TX", "salaryMin": 140000, "salaryMax": 170000, "currency": "USD" }
],
"groupBy": ["function", "seniority"]
}

Output (a real run of this input, shortened):

functionsenioritycurrencypostingsWithPayp10medianp90lowSample
engineeringseniorUSD2169,000175,000181,000true
engineeringmidUSD2125,820129,900133,980true
productmidUSD1155,000155,000155,000true

"Senior" and "Sr." land in the same band; the $55–65 hourly rate counts as $124,800 a year; the $15,000 sign-on bonus is not read as pay. With five jobs every band is lowSample — with your real data the bands fill up. On 320 real LinkedIn postings (122 with pay) the same run gave 13 bands across USD, CAD, EUR, AUD and INR.

Run it again and again

  • On a schedule — save your input as a task and add a Schedule: every week or month on that period's postings. Send each run to Google Sheets, Slack or email with an integration on the task.
  • Watch for changes — Run the same Group by each time: the bands line up period by period.
  • In bulk — Send the whole period's postings in Postings in one call.

How a band is made

  • One number per job: the middle of its range, as yearly pay (hour × 2,080, day × 260, week × 52, month × 12). A job with only "from X" or "up to X" counts at that number. The period is read from period or salaryPeriod; a yearly figure already worked out (annualMin/annualMax or annualSalaryMin/annualSalaryMax) is used as it is.
  • Pay given as text is read with the same reader as our LinkedIn Salary Scraper: an amount counts only when it carries a pay signal of its own, so bonuses, funding and budgets are left out. A bare $ is read as the local dollar when the location is in Canada, Australia and other dollar countries.
  • Department, seniority and the title without level words come from the title, with the same rules as the Job Title Normalizer.
  • Currencies are never converted or mixed: each currency gets its own band.
  • Fewer than 5 jobs with pay: the band is still returned, with lowSample: true and a note.

What you get

Field
function, seniority, coreTitle, locationthe grouping you chose
currencythe band's currency
postingsWithPayjobs in the band with readable pay
postingsWithoutPayjobs with the same grouping but no readable pay (they have no currency, so the count is shown on every currency's band of that group)
p10, p25, median, p75, p90, min, maxyearly pay
lowSample, notefewer than 5 jobs with pay

Use it for

  • Offers and pay reviews — where a number sits against your own openings or the market data you collected
  • Pay transparency — the band you will publish, checked against what is already out there
  • Market reports — bands from any job scraper's output, without spreadsheets

Pricing

$0.005 per band ($5 per 1,000 bands), plus $0.01 per run. A run over 10,000 jobs grouped by department and seniority is typically a few dozen bands. Bands with no pay are free.

For AI agents

Call with {"postings": [{"title": "...", "salaryMin": 100000, "salaryMax": 130000, "currency": "USD"}], "groupBy": ["seniority"]} — a few seconds. Each row has type: "band".

Bands straight from live LinkedIn postings for a title and place: LinkedIn Salary Benchmark. Pay, skills, remote and visa per posting: Job Posting Parser.