praxyjobs

FOR job-data buyers and recruiting-product leaders

Job Postings Are Not Hires: A Buyer’s Methodology Guide

Before using job-posting data for a board, model, or market report, learn what active stock, new flow, expiry, duplicates, and missing fields actually measure.

Praxy Jobs Engineering··8 min read

THE FINDING

Job postings measure employer advertising behavior, not completed hiring. They are still powerful: active postings describe visible opportunity stock, new postings describe advertising flow, and closures describe lifecycle movement. Trouble starts when a product silently turns one measure into another. A reliable buyer should demand source provenance, stable identity, explicit date coverage, modification and expiry events, deduplication policy, and a limitations statement before trusting a volume chart or wiring the data into a customer-facing feature.

Evidence: Production corpus audit plus comparison with published labor-market data methodologies · Snapshot: 2026-07-17

Start by naming the thing you intend to measure

A job record can participate in several valid metrics. New postings in a week measure advertising flow. All postings believed open on Friday measure active opportunity stock. Postings that disappeared or were explicitly closed measure expiry flow. Modified postings measure employer edits. None of these directly counts applications, interviews, accepted offers, workers, or net employment.

The distinction sounds obvious until a dashboard labels active postings as ‘jobs created’ or a sales deck calls posting growth ‘hiring growth.’ Active stock depends on both arrivals and duration. If employers leave roles open longer, the stock can rise while the rate of new advertising falls. If roles close faster, stock can fall during a healthy hiring period. A product must choose the event and the question together.

One posting is not guaranteed to represent one vacancy. Employers publish evergreen pipelines, multi-hire requisitions, duplicated location variants, and roles that are paused without being removed. Conversely, one real opening may appear on a company career site, an ATS-hosted page, several boards, and a staffing site. A posting dataset can be an excellent leading or directional signal while remaining a poor literal vacancy count.

A measurement dictionary for job-posting products
MeasureWhat it can answerWhat it cannot prove
New-posting flowWhat employers started advertising in a periodHow many people were hired
Active-posting stockWhat visible opportunities appear open at a point in timeHow many net jobs were created
Expiry flowWhich advertised roles left the active setWhether each role was filled
Modification flowWhich titles, locations, descriptions, or terms changedWhy the employer changed them
Posting durationHow long an advertisement remained observableTime-to-hire without downstream hiring events

Source provenance is the beginning of quality, not a footnote

A buyer should be able to trace a normalized record to the employer-controlled or ATS-hosted source where it was observed. Provenance makes direct apply links possible, helps operators investigate stale records, and distinguishes first-party employer inventory from listings copied through several intermediaries. Without it, a suspicious title or location becomes a support ticket with no evidence trail.

Source diversity is useful only when it is visible. In the July 17 Praxy Jobs snapshot, 38 source families contributed to the 2.68 million open-job corpus. Workday represented roughly 814,000 records, while SmartRecruiters, Greenhouse, ADP, iCIMS, Paycom, Dayforce, and Workable were also material contributors. That mix gives breadth, but it also means an aggregate can move when one large source changes independently of the labor market.

Every analytical export should therefore include source identifiers and observation timestamps. Every recurring report should publish a source-mix check. When coverage expands, the report should either restate history on a comparable universe or mark the break. A silent coverage improvement can otherwise masquerade as an economic trend.

Identity and lifecycle determine whether a feed stays trustworthy

Stable identity is required to distinguish a new role from an edit, refresh, relocation, or repost. The best available identifier is usually an employer or ATS requisition ID scoped to a company and source. Even that needs care: identifiers can be recycled, location variants can share a requisition, and migrations can change every source key. Title-plus-company matching alone is too fragile for lifecycle accounting.

A production feed should expose at least four events: first observation, modification, confirmed or inferred closure, and reappearance. Consumers need idempotent cursors so retries do not duplicate work. They need tombstones or expired records so a board can remove dead jobs. They need field-level changes when a salary, location, remote status, or description changes after initial ingestion.

Freshness is not one number. Collection freshness asks when the source was last checked. Record freshness asks when a specific job was last observed. Semantic freshness asks whether the employer still considers it open. A crawler can run every hour while a broken source silently returns an old cached page. Monitoring must cover successful checks, observed record movement, and source-specific age distributions.

  • Require a stable job key and document its scope.
  • Ask whether updates keep the same key and whether reposts receive a new one.
  • Consume explicit active, modified, and expired streams rather than rebuilding state from search results.
  • Track first_seen, last_seen, date_posted, modified_at, and closed_at as different concepts.
  • Test a replay after failure and confirm it produces the same downstream state.

Missing fields are part of the dataset

Coverage percentages should accompany every derived field. In the Praxy snapshot, work-arrangement coverage was about 97% and language coverage about 94%. Employment type and experience level were available on roughly a quarter of records. Salary and structured skills coverage were each around 6%. Those gaps do not make the corpus unusable; they determine which questions can be answered responsibly.

A salary filter on 6% coverage can still serve users if the interface says ‘salary disclosed’ and does not imply that excluded jobs pay nothing. A compensation trend, however, needs a missingness analysis by occupation, geography, source, and employer. Disclosure laws and employer practices can change the observed sample. The average of disclosed salaries is not automatically the average salary of all jobs.

Derived fields need their own evidence. Remote status may come from structured ATS metadata, deterministic location rules, description inference, or a model. Skills may be explicitly listed or inferred from free text. Buyers should receive both the normalized value and enough provenance to set their own confidence threshold. A clean schema should not erase the difference between observed and inferred facts.

Selected field coverage in the July 17, 2026 Praxy Jobs production snapshot
FieldApproximate coverageSafe use
Work arrangement97.2%Search facet with provenance-aware fallback
Language94.2%Localization and routing, after classifier review
Experience level26.5%Optional facet; never treat missing as entry level
Employment type24.7%Optional facet with an explicit unknown state
Salary6.0%Disclosed-salary search; not population pay without weighting
Structured skills5.7%High-precision enrichment subset, not universal coverage

Deduplication should match the product decision

There is no universal duplicate definition. Two location variants may be duplicates for a national salary analysis and distinct opportunities for a local job board. A role syndicated from an employer ATS to an aggregator is likely one advertisement observed twice, while two requisitions with identical text may represent real separate openings. Deduplication must preserve the source records even when a consumer view collapses them.

Revelio Labs describes a two-stage approach: normalize primary attributes to reduce the candidate set, then compare temporally overlapping postings using finer similarity. That general pattern scales better than exact hashes and is more explainable than treating every near-match as identical. But the confidence threshold and grouping fields should be validated against the intended use case.

Ask a vendor for examples at the boundary: remote roles with many city pages, the same requisition on two ATS domains, franchise locations, staffing-firm reposts, and a role reopened after a month. A deduplication rate by itself says little. Precision errors can hide genuine inventory; recall errors can inflate demand and annoy job seekers.

An acceptance test for job-data vendors

Begin with a written product decision, then build a representative evaluation set. Include large and small employers, several ATS sources, countries, remote and on-site roles, sparse records, recent changes, and confirmed closures. Do not let the vendor choose only clean examples. Run the same queries repeatedly over several weeks so lifecycle behavior becomes visible.

Measure source validity, active-link rate, duplicate precision and recall, field coverage, classification accuracy, update latency, closure latency, and cost per usable record. Segment every metric. An overall 95% can hide a source or country that is unusable for the exact niche you plan to serve. Review raw examples behind every aggregate failure.

Finally, test operational behavior: authentication, quotas, pagination, cursor replay, partial outages, schema changes, deletion requests, and support response. The data will change every day. The commercial question is not whether the first export looks large. It is whether your product can remain correct when jobs appear, mutate, disappear, and occasionally arrive incomplete.

# Minimal lifecycle acceptance loop
active = fetch_active(cursor=checkpoint)
upsert(active.jobs)
save_checkpoint(active.next_cursor)

modified = fetch_modified(cursor=modified_checkpoint)
apply_field_changes(modified.events)

expired = fetch_expired(cursor=expired_checkpoint)
mark_closed(expired.jobs, reason=expired.close_reason)

What Praxy can and cannot claim from this snapshot

Praxy can state the observed size and composition of its production index on the snapshot date, describe source coverage, and publish field-coverage and freshness statistics. It can use repeated snapshots to study changes after controlling for source mix and classification revisions. It can provide individual source records so customers can audit results.

This snapshot alone cannot establish national hiring growth, completed hires, unemployment, or the total number of vacancies. The corpus is not a probability sample of all employers. Date fields and enrichments are incomplete. Currently open jobs overrepresent postings with longer observable duration. Job closures do not reveal whether a hire occurred.

A serious data product should make those boundaries easy to find. Methodology is not a disclaimer attached after the chart; it is part of the API contract. Buyers build better products when they know which measure they have, where it came from, and how it can fail.

FREQUENTLY ASKED QUESTIONS

Questions teams ask

Are job postings a reliable measure of hiring demand?+

They are a useful, timely proxy for employer advertising demand when source coverage, deduplication, dates, and revisions are handled explicitly. They do not directly measure completed hires, workers, or exact vacancies, and the strength of the proxy varies by occupation, employer, geography, and source.

What should a job-data API expose besides search results?+

It should expose stable identity, provenance, first and last observation, modifications, expirations, explicit unknown values, field-level evidence, and replayable incremental cursors. Those capabilities let a customer maintain correct downstream state instead of repeatedly downloading a changing search result.

SOURCES & METHOD

Check the evidence

Related field notes