The completeness of salary information in a job postings dataset is a rate you measure on a sample, and it is rarely one number. Pay is stated on some postings and absent on others, and the split follows the job's location, the employer and the date. This post explains why, sets out what pay transparency rules require and where, gives a test for the share of postings with pay, and brings ranges in different currencies and periods to one scale.
Why pay is stated on some postings and absent on others
Pay appears on a posting when a rule requires it for that job, or when the employer chooses to publish it. Google's guide to job posting markup lists pay as a recommended property and not a required one, so where no rule applies the choice is the employer's. The share of postings with pay follows place, employer and date.
Whether a stated figure reaches a dataset is a second question, because pay can sit in a machine-readable field or only in the text of the advertisement. The schema.org JobPosting type has a baseSalary property for the base salary of the job and a separate estimatedSalary property, whose definition notes that estimates are often computed by outside organisations and not by the hiring organisation. Google's guide to job posting markup lists baseSalary among the recommended properties and not among the required ones, says that only employers can provide it, writes a range as a minValue and a maxValue, and gives the pay period in unitText as HOUR, DAY, WEEK, MONTH or YEAR.
Three things follow.
- A posting can carry every required property and no pay.
- Pay written only in the text has to be extracted, so the rate you measure reflects the provider's reading as well as the employer's choice.
- A filled pay field can hold an estimate. Ask whether each value is the employer's own figure, and keep estimates in a separate column.
What pay transparency rules require, and where
Pay transparency rules differ in three ways that matter to a dataset: whether pay must appear in the posting itself or only reach the applicant before the interview, which employers are covered, and the date the rule applies from. The table summarises official pages as read on 7 October 2026. It is a reading aid for data work, not legal advice.
| Place | What the official source says | Date the source gives |
|---|---|---|
| European Union | Under Directive (EU) 2023/970, employers will have to tell job seekers the starting salary or its range, in the vacancy notice or ahead of the interview (European Commission) | Member States must transpose the directive into national law by 7 June 2026 |
| Colorado | An employer discloses in each posting for each job opening the hourly or salary compensation, or a range of it, and a general description of the benefits and other compensation (2019 act, session law). The 2023 act rewrites this as a disclosure in good faith in the notification of each job opportunity, and adds the date the application window is expected to close (2023 act, session law) | Effective 1 January 2021, and 1 January 2024 for the 2023 act |
| California | An employer with 15 or more employees includes the pay scale for a position in any job posting, read by the Labor Commissioner as covering a position that may ever be filled in California, in person or remotely (Labor Commissioner's FAQ) | Stated as current law, with no start date on the page |
| New York State | Businesses with four or more employees list compensation ranges for job, promotion and transfer opportunities (Department of Labor): the minimum and maximum annual salary or hourly pay the employer believes accurate at the time of posting (Labor Law section 194-b) | Went into effect on 17 September 2023 (Department of Labor FAQ) |
| Washington State | Employers with 15 or more employees include a wage scale or salary range, or the fixed wage amount where only that is offered, and a general description of benefits and of other compensation, in job postings (Department of Labor and Industries) | The 2022 act takes effect 1 January 2023 |
| Illinois | Employers with 15 or more employees include a position's pay scale and benefits in all internal and external job postings, for work performed at least in part in Illinois, or reporting to a supervisor, office or work site there (Department of Labor) | As of 1 January 2025 |
Each cell paraphrases the linked page, and the linked text governs. The six places are those read for this post, not a complete list. Three points turn the table into tests.
- Cut by the job's location. The California and Illinois rules above name where the work is done or could be done, so measure completeness by job location and keep remote roles apart.
- Look for the step at each date. Compare postings first seen before and after a rule's date, in that place and for employers of the size it names.
- Read national law in the EU. The Commission's summary names two routes, the vacancy notice or ahead of the interview, and Member States transpose the directive into national law. Check whether that law is in force or not yet in force in a Member State before you expect its postings to carry pay.
Measuring the completeness of salary information in a job postings dataset
Measure salary completeness as the share of distinct postings that carry a usable pay value, on a sample you fix first: one row per posting, one period, one list of companies. Report four rates, from any stated pay down to pay converted to one scale, and break each by job location, job function and first-seen date.
| Rate | Postings counted | A low value points to |
|---|---|---|
| Stated pay | A minimum or a maximum is present | Employers that publish no pay, or pay left in the text |
| Complete range | Both bounds, a currency and a period | Single figures, "up to" amounts, a missing period |
| Employer-stated | The value is the employer's own figure | A field filled by estimates |
| On one scale | Pay converted to one currency and one period | Rows lost in conversion |
The denominator matters as much as the numerator. Like data coverage, completeness is measured on your own sample: count distinct postings after duplicates are removed, and print the count beside every share.
On Job Postings in Fokals data, three of the rates come from one query. Pay there is the figure the employer states, so the employer-stated rate equals the first.
select
country,
count(*) as postings,
sum(case when salary_min is not null or salary_max is not null
then 1 else 0 end) as stated_pay,
sum(case when salary_min is not null and salary_max is not null
and salary_currency is not null and salary_period is not null
then 1 else 0 end) as complete_range,
sum(case when salary_usd_annual_min is not null
or salary_usd_annual_max is not null
then 1 else 0 end) as on_one_scale
from job_postings
where first_seen_at >= timestamp '2026-09-28 00:00:00'
and first_seen_at < timestamp '2026-10-05 00:00:00'
and not found_on_first_read
group by country
order by postings desc;The query takes the postings first seen in one week and leaves out those that carry the baseline flag, whose first-seen date is not an opening date. Divide each count by the postings in its row. Then repeat it by job function and by seniority, and read twenty rows against the public posting each one links to.
Last, compare the two groups. Employers that publish pay are a subset, so set the mix of their postings beside the mix of all postings before you call a median a market rate.
Three sources, read the same way
The four rates apply to any source.
Salary and compensation data in the Lightcast job postings dataset
Lightcast's documentation defines Advertised Salary as the salary information given by the company or entity advertising the position, extracted from the posting where it is present. It states that no estimated salary is presented for an individual posting, and that reports show the count of postings with salary data.
The same article says the percentage of postings with salary information depends on the geography, the occupation, the industry and the job title, and points to its occupational and industry earnings data for actual earnings. Its methodology for job posting analytics adds that hourly salaries are converted to annual formats, and the reverse, using work hours appropriate to each country. On an extract, ask for the count with salary beside every total and for the hours behind each annual figure.
Salary fields in the Adzuna job postings API
The sample responses in Adzuna's search documentation carry a minimum salary, a maximum salary and a flag for a predicted salary. Three tests on a sample show what the fields hold: how often the two bounds are filled, whether a filled value is the employer's stated figure or an estimate, and which currency and pay period it carries.
The UK Office for National Statistics, which built vacancy indicators on Adzuna data, describes Adzuna as an online job search engine that collates adverts from many sources, from employers' own websites to recruitment software providers and job boards, and lists salary information among the data Adzuna made available to it. Its note, last revised on 14 June 2021, records two rounds of deduplication: Adzuna removes entries where all the information on an advert is the same, and the statisticians then matched near-identical descriptions with the same job title.
One advertisement collected from several places counts several times in the denominator. Deduplicate before you measure, and say which copy's pay you kept.
Salary fields in a job postings dataset from Kaggle
Treat a salary-from and salary-to pair in a public job postings dataset, from Kaggle or anywhere else, as a lower and an upper bound whose meaning you have to establish. Read the publisher's column descriptions, then test for zeros standing in for empty values, bounds in the wrong order, mixed pay periods and mixed currencies.
Two official sources show the same shape. The USAJOBS search API of the US federal government returns remuneration objects that hold a MinimumRange, a MaximumRange and a RateIntervalCode, which its reference describes as giving the pay range and frequency. A pair of bounds needs that third field before it can be used. The US government's data catalogue lists Jobs NYC Postings, the current postings of the City of New York's official jobs site, with internal postings for city employees and external postings for the public both included. Check whether one job appears under both before you compute a share.
Four tests apply to any such file.
- A zero or negative bound. Treat it as empty and recount the share.
- A lower bound above the upper. The columns are swapped or the text was misread.
- Equal bounds. A single stated figure, counted apart from ranges.
- Values in two clusters. Tens beside tens of thousands mean hourly and annual pay in one column.
Putting ranges in different currencies and periods on one scale
Bring every range to one scale in three steps, each with a stated convention: convert the pay period to a year, convert the currency at a dated reference rate, and keep both bounds, taking a midpoint only where one figure is needed. Keep the stated values beside the converted ones so that the conversion can be redone.
Period. An hourly, daily, weekly or monthly figure becomes annual by a factor, and the factor is a convention. The US Bureau of Labor Statistics multiplies the hourly wage by a typical work year of 2,080 hours in its occupational wage statistics, and Lightcast's methodology uses work hours appropriate to each country. State your factors.
Currency. The euro foreign exchange reference rates of the European Central Bank are quoted against the euro, are usually updated around 16:00 CET every working day and are published for information purposes only. Because each rate is against the euro, a conversion between two other currencies is a cross rate through it. One fixed date keeps exchange-rate moves out of a comparison across postings. The rate of the latest day re-values earlier postings each time it moves.
Range. Keep both bounds, and report the width beside any midpoint.
Job Postings in Fokals data carries the stated minimum, maximum, currency and period beside the same pay on one annual US-dollar scale, so both rates can be measured and the conversion redone at a rate of your choosing.
A worked example: Acme Robotics
Acme Robotics is an invented company, and every figure in this example is illustrative.
Assumptions:
- A sample of 40 postings first seen in one week, one row per posting after duplicates are removed.
- Exchange rates of 1 EUR = 1.10 USD and 1 EUR = 0.88 GBP, assumed for the arithmetic and not market rates. The cross rate is 1.10 / 0.88, so 1 GBP = 1.25 USD.
- Period factors of 2,080 hours and 12 months to the year.
- A range is summarised by its midpoint.
First, completeness by job location.
| Job location | Postings | Stated pay | Complete range | Share with stated pay |
|---|---|---|---|---|
| United States | 24 | 18 | 18 | 75% |
| Germany | 10 | 2 | 2 | 20% |
| United Kingdom | 6 | 3 | 2 | 50% |
| All | 40 | 23 | 22 | 57.5% |
The headline rate of 57.5% describes no location: it is 75% in one and 20% in another. Of the 23 postings with pay, 18 are in the United States, which is 78% of the pay sample against 60% of all postings, so a median over the 23 is mostly a US figure. The rate also moves with the mix. If Germany opens 10 more postings at the same 20%, the sample becomes 50 postings with 25 stating pay, and the headline falls to 50% although no location's rate changed.
Second, four of the ranges on one scale.
| Posting | Stated | To a year | In US dollars | Midpoint |
|---|---|---|---|---|
| A, United States | USD 120,000 to 150,000 a year | Unchanged | USD 120,000 to 150,000 | USD 135,000 |
| B, United Kingdom | GBP 60,000 to 70,000 a year | Unchanged | USD 75,000 to 87,500 | USD 81,250 |
| C, Germany | EUR 5,000 to 6,000 a month | EUR 60,000 to 72,000 | USD 66,000 to 79,200 | USD 72,600 |
| D, United States | USD 30 to 40 an hour | USD 62,400 to 83,200 | USD 62,400 to 83,200 | USD 72,800 |
The median of the four midpoints is USD 77,025, halfway between USD 72,800 and USD 81,250. At 1,950 hours, a 37.5-hour week for 52 weeks, posting D becomes USD 58,500 to 78,000 with a midpoint of USD 68,250, which is 6.25% lower. At 1 EUR = 1.00 USD, the midpoint of posting C falls from USD 72,600 to USD 66,000 with no change in the pay advertised. Print the factors and the date of the rate with every converted figure.
Advertised pay in Fokals data
Job Postings holds every role a company publishes, with pay as the employer states it and on one annual US-dollar scale. Each posting carries its location, its job function and seniority, and the dates it was first seen, last seen and closed, so each rate above can be cut by place, role and date. Hiring Activity adds the median annual pay of a company's open postings for each closed day, and Sales Pay Benchmarks gives the quartiles of advertised base pay and on-target earnings by role and country.
The data dictionary defines the fields, and the hiring dataset page shows what is delivered. Our note on reading job postings from the company's own board covers duplicates and dates, and the guide to benchmarking pay and talent demand builds a pay range from the same fields.
Frequently asked questions
What share of job postings include salary information?
No single share holds. Lightcast's documentation says the percentage of postings with salary information depends on the geography, the occupation, the industry and the job title, and pay transparency rules add steps by place and date. Measure it on your own sample: the share of distinct postings with stated pay, by job location, job function and first-seen month, with the count of postings beside each share.
Does the EU Pay Transparency Directive require a salary in every job advert?
The European Commission's summary says employers will have to tell job seekers the starting salary or its range, in the vacancy notice or ahead of the interview, and its page on equal pay says Member States must transpose the directive into national law by 7 June 2026. The summary names two routes, so read the national law of the country concerned for what a posting there must carry. This is a reading of official pages on 7 October 2026, not legal advice.
Which US states require a pay range in job postings?
This post reads official pages on the pay disclosure rules of five states and makes no claim to be a complete list: Colorado, California, New York, Washington and Illinois. The California, Washington and Illinois pages name employers with 15 or more employees, and the New York page names businesses with four or more. The sources give 1 January 2021 for Colorado's act, 1 January 2023 for Washington's, 17 September 2023 for New York's and 1 January 2025 for Illinois.
How do you convert an hourly wage to an annual salary?
Multiply by the hours in a working year, and state the figure you used. The US Bureau of Labor Statistics multiplies the hourly wage by a typical work year of 2,080 hours in its occupational wage statistics, and Lightcast's methodology uses work hours appropriate to each country. At 2,080 hours, USD 30 an hour is USD 62,400 a year.
Is an advertised salary the same as the pay an employee receives?
No. A posting states what an employer advertises for a role: a range, or sometimes a single figure. It records an intention to hire, and the pay agreed with the person hired is settled later. Use advertised pay to see where offers start and how they move, and earnings statistics or a compensation survey for pay received.
Should I use the midpoint of a salary range?
Use the midpoint where one figure per posting is needed, for a median or a chart, and keep the two bounds beside it. A midpoint hides the width of a range, and widths differ between employers. Report the lower quartile of the minimums and the upper quartile of the maximums next to the median of the midpoints.
The queries and code on this page are examples to adapt. Test them in your own environment before you rely on them.
What this page says about the products it names was checked against their public documentation on 7 October 2026. Product and company names are trademarks of their owners. Fokals is not affiliated with them or endorsed by them.