Salary Benchmarks — Live Pay Bands from Job Postings
Pricing
from $0.50 / 1,000 results
Salary Benchmarks — Live Pay Bands from Job Postings
Extract salary bands from live remote job postings: min, max, midpoint, currency and an annualised figure. Reports coverage honestly — only postings that disclose pay become rows.
Pricing
from $0.50 / 1,000 results
Rating
0.0
(0)
Developer
alaudin burki
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 hours ago
Last modified
Categories
Share
Salary bands from live remote job postings: minimum, maximum, midpoint, currency and an annualised figure — from two keyless feeds (Jobicy and RemoteOK).
The number most salary datasets hide
Only 48 of 149 current postings disclosed pay. Most job ads do not publish a salary, so a tool
that quietly averages whatever it found is reporting on a third of the market and calling it "the
market". This Actor puts the coverage in SUMMARY beside the rows:
postingsFetched: 149 · postingsWithSalary: 48 · coveragePct: 32
You always know what share of the data you are looking at.
Three rules it will not break
1. Currency is never converted. A USD 190,500 role and a PLN 240,000 role are not comparable
by multiplying, and an exchange rate applies today's guess to next month's data. Each row carries its
own currency; SUMMARY.byCurrency gives a median per currency, and comparisons happen there.
2. Annualising states its assumption. Sources post yearly, monthly and hourly pay. To compare them the Actor converts to a yearly figure and writes the assumption on the row:
{ "period": "hourly", "annualised": true,"annualAssumption": "2080 hours per year for hourly; 12 months for monthly" }
The raw salaryMin / salaryMax are kept beside the derived annualMin / annualMax, because an
hourly contract without paid leave is not literally 2,080 hours.
3. A midpoint needs both ends. A posting with only a floor has no midpoint, so annualMid is
null — not the minimum restated as if it were an average.
Real output
| title | currency | salaryMin | salaryMax | annualMid |
|---|---|---|---|---|
| Senior Finance Manager | USD | 190,500 | 214,767 | 202,634 |
| Product Manager, Onboarding | USD | 180,000 | 260,000 | 220,000 |
| Business Development Rep | USD | 70,000 | 75,000 | 72,500 |
Use cases
- Candidates — what a role actually pays before the first call.
- Recruiters — a defensible range instead of a guess.
- Compensation analysts — a live sample, refreshed on a schedule, with the coverage figure attached.
- Job boards — which roles publish pay and which do not, by company.
Limits
- Remote-first sources. These feeds skew remote and tech; the sample is not the whole labour market.
- Posted ranges, not offers. A posted band is the employer's stated intent, not what anyone accepted.
- Coverage varies by source. RemoteOK disclosed on 20 of 99 postings, Jobicy on 28 of 50 in one run.
- No role normalisation. "Senior Finance Manager" and "Finance Manager, Senior" stay separate rows; grouping them is analysis, not extraction.
Verified
36 unit tests on the reader — every period multiplier, the one-ended range, an inverted range, the no-salary case and the median — plus 15 live checks against both feeds: 149 postings fetched, 48 with pay, hourly rows flagged, midpoints only where both ends exist, and every row flat.
One row per paying posting, highest midpoint first, with the coverage stated.
Fields
| Field | Type | What it holds |
|---|---|---|
id | string | Stable row identity across sources. |
source | string | Which feed produced the row: jobicy or remoteok. |
title | string | The role as posted. |
company | string | The hiring company. |
location | string | Where the role is based, as the source states it. |
level | string | Seniority when the source publishes it. |
industry | string | Industry when the source publishes it. |
salaryMin | number | The bottom of the posted range, in the posted period and currency. |
salaryMax | number | The top of the posted range. |
currency | string | ISO currency code, or 'not stated'. Never converted. |
period | string | The period the posted figures are in: yearly, monthly, hourly and so on. |
annualMin | number | salaryMin annualised. Equals the raw value when the period is yearly. |
annualMax | number | salaryMax annualised. |
annualMid | number | Midpoint of the annual range — null when only one end was posted. |
annualised | boolean | True when a non-yearly figure was converted, so the assumption is visible. |
annualAssumption | string | The conversion applied, e.g. 2080 hours per year for hourly pay. Null when no conversion was needed. |
rangeWasInverted | boolean | True when the source posted max below min; the row is ordered and the swap is disclosed. |
publishedAt | string | When the posting was published. |
url | string | The posting. |
scrapedAt | string | When this run fetched it. |