Job data API: how to evaluate one before you build on it
Every job data API claims millions of postings, real-time updates, and clean structured fields. None of that is falsifiable from a landing page. Here are the seven dimensions job posting data actually varies on - coverage, latency, dedup, normalization, ID stability, status tracking, and provenance - and a test you can run for each one inside a two-week trial.
Dvir Atias
Founder, JobsPipe
Every job data API landing page makes the same three claims: millions of postings, real-time updates, clean structured fields. All three are cheap to say and none is falsifiable from the page you read them on. The gap between a job data product that demos well and one that survives a year in production sits entirely in details nobody advertises.
This is the due-diligence pass, not a comparison and not an integration guide. For a side-by-side of specific providers see the best jobs APIs of 2026, and for the wiring see how to add job search to your product. What follows is the seven dimensions job posting data actually varies on, each with a test you can run in a trial using a key and a spreadsheet.
1. Coverage: what “millions of jobs” actually means
Index size is the number every vendor leads with and the one that tells you least. It is usually cumulative rather than live, counting every posting ever seen instead of every posting open today. It is usually measured before deduplication, so a role syndicated to five places counts five times. And it is never evenly distributed: almost every index is dense in US English-language white-collar roles and thin everywhere else.
You do not need millions of jobs, you need the jobs in your slice - your geographies, your job families, your company list - and the only honest coverage number is one you measure on that slice yourself.
The test. Pick 20 to 30 companies you actually care about, open each careers page or ATS board, and count the roles matching your filter over the last 30 days. That hand count is your denominator. Then ask the API the same question, one company at a time:
curl -s https://api.jobspipe.dev/v1/jobs/search \
-H "Authorization: Bearer jp_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"company_name_partial_match_or": ["monzo"],
"job_country_code_or": ["GB"],
"job_title_or": ["backend engineer", "platform engineer"],
"posted_at_max_age_days": 30,
"include_total_results": true,
"limit": 25
}'Divide metadata.total_results by your hand count and you have recall for that company. Report the spread, not the average: a provider at 95% on fifteen companies and 10% on five has a structural gap in a source you depend on, and the mean hides it. Then read the misses. If they all come from one ATS or one country, you have learned something no index-size figure could tell you.
2. Freshness and latency: measure the gap, not the promise
“Real-time” means nothing without a unit, and two quantities get blurred. Index latency is the gap between a posting going live at the source and appearing in the API. Refresh interval is how often an already-indexed record is re-checked for changes or closure. A provider can have excellent latency and terrible refresh, and it is the second that rots your database.
Latency varies enormously by source, and not randomly. ATSs publishing structured public boards are cheap to poll often, so those roles land fast. Aggregators and bot-defended boards must be crawled through proxy infrastructure, which makes cadence a cost decision, so the harder a source is to read the staler it usually is. Ask for latency per source, never as one blended figure. And pin down the date field: posted_at is normally when the employer published the role, not when the provider first saw it, and those can be a week apart.
The test. Pick roles you know went live today, your own openings ideally, and record when each appeared at the source. Poll the API hourly with posted_at_max_age_days set to 1 and record first-seen. Report p50 and p90 per source over at least 30 postings. The p90 is what matters: means are flattered by the easy sources, and it is the tail that breaks anything time-sensitive.
3. Deduplication: the hardest problem in this data
One requisition opens in an ATS, gets syndicated to an aggregator, mirrored onto a professional network, picked up by two niche boards, and reposted by a staffing agency. That is six records with six IDs. Titles differ (“Senior Backend Engineer” versus “Senior Backend Engineer (Remote, EU)”), locations differ (“Berlin” versus “Remote - EMEA”), and descriptions differ because boards truncate. There is no shared key.
Good deduplication clusters, it does not delete. The record you get should say it represents a cluster and which sources fed it, because that lineage is what you need when a field looks wrong. There are two failure modes, they pull in opposite directions, and a vendor tuned to avoid one is usually failing the other.
- Under-merging leaks duplicates into your product. Query one company over a fixed window, group results by normalized title plus location, and count the groups holding more than one record for the same requisition.
- Over-merging collapses genuinely distinct roles into one, and it is the dangerous one because it is silent. Large companies routinely open several real requisitions with identical titles across teams or cities. Find one doing that, count the reqs on their own board, and see what the API returns. If five come back as one, you are undercounting hiring volume and every headcount trend you draw is wrong in a direction you never notice.
Ask which way the vendor errs and why. “We never return duplicates” is not a reassuring answer; it is a description of aggressive over-merging.
4. Normalization: which fields become real types
Normalization is what separates a job data API from scraped HTML. Title, seniority, location, remote status, employment type, company identity and compensation all have to become typed fields, and every one of them arrives as free text somewhere in your source mix.
Company identity is the most underrated. If “Acme”, “Acme Inc.” and a wholly-owned subsidiary do not resolve to one entity, every company-level rollup is quietly wrong. Remote status is treated as a boolean and is not one: fully remote, remote within one country, hybrid, and onsite are four states. Query with remote set to true, read fifty descriptions, and count how many say hybrid. That is what the flag actually means.
Compensation is the hardest field in the schema, because it lives in prose and arrives in every shape: hourly or annual, range or point, base only or base plus bonus plus equity, in a dozen currencies, often only inside a jurisdiction-mandated block bolted onto the end of the description. The classic silent failure is an hourly rate parsed as an annual salary, which poisons every benchmark built on it.
Be skeptical of near-complete salary coverage claims. Even in the most transparent market the ceiling is nowhere near 100%: the New York Fed found that the share of US online job postings carrying pay information rose from about 15% before 2018 to roughly 53% since January 2024, and that as of January 2025 about 24% of ads covered by pay transparency laws still did not comply. A global index mixing in non-US markets and raw ATS feeds lands lower. Ask whether the vendor counts any mention of pay as coverage, or estimates it. Estimates are a legitimate product, but they have to be flagged as estimates in the response.
The test. Pull 100 postings at random, open each at the source, and sort the compensation field into three buckets: correct, missing while the description states pay, and wrong. The second is parser recall, the third is parser precision. A small third bucket and a large second one means the vendor is being conservative. The reverse should end the evaluation.
5. Identity and stability: does the ID survive the next crawl
A posting’s ID becomes a foreign key in your database the moment you store it. Users save jobs against it, you track which ones you have shown, your analytics join on it. If the ID is not stable across crawls, all of that corrupts silently: the same job reappears as new, saved-job rows point at nothing, and your “new postings this week” metric measures the provider’s crawler instead of the labor market.
Instability is usually structural rather than careless. Many providers derive the ID from a hash of content or URL because there is nothing else to use: schema.org’s identifier property, the employer’s own requisition number, is only recommended rather than required in Google’s job posting spec, so a large share of source records carry no employer-side ID at all. With a content hash, any title edit or URL rewrite mints a brand new job that is not new.
The test. Run one fixed query today and store every ID. Re-run it daily for two weeks and compute the share of yesterday’s IDs still present. Then fetch 20 of the originals by job_ids after a week. If they resolve, the ID is a real key; if they fail while the same role is obviously still open under a different ID, you are looking at a content hash. Ask one more thing: are IDs ever recycled? A reused ID is worse than an unstable one, because it silently attaches new data to old rows.
6. Status tracking: closed, or just gone?
There is an enormous difference between an API that tells you a posting closed and one that simply stops returning it, and it stays invisible until you try to do anything over time. Disappearance is ambiguous by construction: the role might have been filled, or withdrawn, or the crawl failed, or the source blocked the provider. If all you have is absence, you cannot tell a hiring slowdown from a vendor outage, and every time-to-fill or churn metric you compute is partly a measurement of the provider’s crawl reliability. For time-series work this dimension alone can disqualify a provider.
What good looks like: an explicit status field with a closure timestamp, records retained and queryable after they close, and a documented rule for how closure is decided - the source returned 404 or 410, its validThrough date passed, or it was absent from the feed for N consecutive checks. The upstream signal usually exists, since Google requires expired postings to be removed or marked past validThrough; the question is whether the provider recorded it. If historical postings are the actual need, we went through the options in how to find expired job postings.
The test. Pick 30 live postings you can watch at the source, check them daily, and note when each comes down. Does the API mark them closed, and how many days later? A provider flagging closure within a day or two is doing real liveness checking. One that just stops returning them is leaving the inference to you.
7. Provenance and compliance
Every record should tell you where it came from, ideally down to the original URL. That matters for four reasons: you cannot debug a wrong field without reading the original posting, your legal review will ask, you may want to weight or exclude sources you do not trust, and provenance is what makes a dedup cluster auditable instead of a black box. A provider that will not name the source behind a record is asking you to build on an input you cannot audit.
While you are asking, cover the rest: which sources are first-party or licensed feeds versus crawled, the posture on robots and terms of service, whether there is any indemnification, retention periods, and the deletion process. Access models differ across applicant tracking systems, which is worth knowing before assuming a source is safely available - see public versus gated ATS APIs.
The evaluation checklist
Take this into the trial: one question for the vendor, one test you run yourself, per dimension.
| Dimension | Ask the vendor | Verify it yourself |
|---|---|---|
| Coverage | How many postings are open right now, after dedup, in my countries and job families? | Hand-count 20 companies and compare recall company by company |
| Freshness | What is p50 and p90 latency per source, and how often is a record re-checked? | Poll hourly against roles you watched go live, and measure the tail |
| Dedup | Do you cluster or delete, and do you err toward over-merging or under-merging? | Test duplicate leakage, then distinct same-title reqs at a large employer |
| Normalization | Which fields are parsed, which are inferred, and are inferred values flagged? | Audit 100 records against their source pages, compensation especially |
| Identity | What is the posting ID derived from, and is it ever reused? | Store IDs, re-query for 14 days, refetch by ID after a week |
| Status | Do you emit a closure event, and what rule decides a posting is closed? | Watch 30 postings close and measure the lag |
| Provenance | Does each record name its source and original URL? | Check a sample resolves back to a real, readable source page |
None of this takes long, and it tells you more than any documentation will. If you are still choosing a source type, the seven-source comparison of where to get job posting data covers APIs, datasets and scrapers side by side, and the job market dataset guide covers the bulk and historical route. If you have settled on a single normalized endpoint, that is what a unified job posting API is for.
The point is not to catch anyone out. Vendors who answer these questions with numbers are a different population from the ones who answer with adjectives, and an hour of asking tells them apart.
Run the whole checklist against JobsPipe on the free tier - no card, 100 requests a month.
Get a free API keyFrequently asked questions
What is a job data API?
A job data API is an HTTP endpoint that returns job postings collected from many sources - applicant tracking systems, job boards and aggregators - as structured, normalized records rather than raw HTML. Instead of scraping each site yourself, you send filters such as title, country, remote status and posting age, and get back a consistent JSON shape with fields like company, location, seniority, compensation and a stable posting ID. The value is not the HTTP call, which is trivial, but the collection, deduplication and normalization behind it.
How do I evaluate a job data API?
Test seven dimensions during a trial rather than reading the marketing page: coverage on your specific slice, index latency and refresh interval, deduplication behavior, field normalization, posting ID stability, whether closures are reported explicitly, and per-record provenance. Each has a cheap test - hand-count 20 companies for coverage, poll hourly against roles you watched go live for latency, store IDs and re-query for two weeks for stability. Two afternoons of manual checking will tell you more than any vendor documentation.
What is the difference between a job data API and a job board API?
A job board API is scoped to one board or one employer's own listings, and it is often designed for writing jobs in rather than reading them out. A job data API reads across many sources at once and returns them in a single schema, so your code never branches per source. The practical difference is that a job board API gives you one publisher's inventory in that publisher's format, while a job data API gives you cross-source coverage plus the deduplication and normalization work required to make those sources comparable.
How fresh should job posting data be?
It depends on the use case, and you should specify it as a percentile rather than an average. A candidate-alerting product typically needs postings within hours of going live, so p90 index latency matters more than a flattering median. A market analytics product can usually tolerate daily or weekly latency but is far more sensitive to refresh interval, meaning how often existing records are re-checked for changes and closure. Ask for both numbers broken out per source, since crawled sources are almost always slower than sources with structured public feeds.
How do job data APIs handle duplicate postings?
The same role often syndicates from an applicant tracking system out to aggregators and job boards, producing several records with different IDs, slightly different titles and different location strings. Good providers cluster those records into one canonical posting while retaining which sources contributed, rather than silently deleting the extras. There are two failure modes to test for: under-merging, which leaks visible duplicates into your product, and over-merging, which collapses genuinely distinct requisitions that happen to share a title and quietly makes you undercount hiring volume.
Do job data APIs include salary data?
Some do, but never on every posting, because most compensation information lives in free text and a large share of postings do not state pay at all. The New York Fed found that the share of US online job postings carrying pay information rose from roughly 15% before 2018 to about 53% since January 2024, and that even among ads covered by pay transparency laws about 24% still did not comply as of January 2025. A global index that includes non-US markets lands lower still, so treat any claim of near-complete salary coverage as a prompt to ask whether the provider counts text mentions as coverage or estimates the value, and if it estimates, whether estimated values are flagged in the response.