Salary benchmarking

Check what a role pays - advertised-salary percentiles for an occupation or a title, by country and seniority.

The salary benchmark answers "what does this role pay?" from live job postings that state pay. Each call that returns data costs 1 credit; an empty answer costs nothing.

Need more than pay - which occupations and industries are hiring, which skills are rising, or how exposed a role is to AI demand? That labour-market data is available on request: book a demo and we'll walk you through it.

Benchmark a salary

Check an offer against the market. The benchmark takes an occupation code or a title, plus optional country and seniority (entry, mid, senior, lead, exec).

curl https://api.jobspipe.dev/v1/insights/salary/benchmark \
  -H "Authorization: Bearer jp_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "data engineer",
    "country": "US",
    "seniority": "senior",
    "window_days": 90
  }'
import requests

HEADERS = {"Authorization": "Bearer jp_live_your_key_here"}

bench = requests.post(
    "https://api.jobspipe.dev/v1/insights/salary/benchmark",
    headers=HEADERS,
    json={"title": "data engineer", "country": "US", "seniority": "senior", "window_days": 90},
).json()

offer = 165000
if bench["suppressed"]:
    print("Not enough postings with stated pay to benchmark.")
else:
    p = bench["percentiles"]
    band = next((k for k in ["p10", "p25", "p50", "p75", "p90"] if offer <= p[k]), "above p90")
    print(f"{offer} is at or below {band} (median {p['p50']}, n={bench['count']}, {bench['confidence']})")
const headers = { Authorization: "Bearer jp_live_your_key_here" };

const bench = await fetch("https://api.jobspipe.dev/v1/insights/salary/benchmark", {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({ title: "data engineer", country: "US", seniority: "senior", window_days: 90 }),
}).then((r) => r.json());

if (bench.suppressed) console.log("Not enough postings with stated pay to benchmark.");
else console.log("Median:", bench.percentiles.p50, "n =", bench.count, bench.confidence);

The response carries count, currency, percentiles (p10 to p90), confidence and suppressed.

Reading the numbers

  • Pay is advertised pay from postings that state it, normalized to annual USD. It measures what employers offer publicly, which is not the same as survey-based earnings.
  • Small samples are withheld. Under 30 postings, the response has suppressed: true and percentiles: null.
  • confidence follows the sample size: low (30 to 99 postings), medium (100 to 999), high (1,000 or more). The exact count is always included.
  • Occupation codes are ISCO-08: 4 digits exact (2512), or 1-3 digits to roll up a whole group (25).

On this page