Twelve applicant tracking systems publish an open JSON endpoint that their customers' careers pages read. They do not publish the same fields, and the gaps are not documented anywhere. This page is the measurement.
Every percentage below was measured across every live board we track for that
platform — not a sample. Between 17,000 and 179,000 postings per platform,
1,549,353 in total, on 2026-08-20. yes means 99.5% or more;
no means the endpoint carries no such field at all.
| Platform | Posting date | Description | Pay | Marked remote | Postings measured |
|---|---|---|---|---|---|
| Workday | 78.2% | no | no | no | 41,683 |
| SmartRecruiters | yes | no | no | 7.7% | 86,464 |
| Greenhouse | yes | yes | no | no | 179,303 |
| Workable | yes | yes | no | 36.3% | 68,849 |
| BambooHR | no | no | no | no | 50,616 |
| Lever | yes | 94.7% | no | 4.8% | 46,005 |
| Breezy HR | yes | no | 45.7% | 15.7% | 47,085 |
| Personio | no | no | no | 8.8% | 41,608 |
| Ashby | yes | yes | 38.9% | 54.2% | 32,407 |
| Recruitee | yes | yes | 26.9% | 9.9% | 21,621 |
| Rippling | no | no | no | 17.4% | 18,701 |
| Pinpoint | no | yes | 42.5% | 8.8% | 17,302 |
title, company, location and an apply URL come back from every one of them.
Four, and none of them fills it most of the time. They also disagree on form, which matters more than the fill rate if you are benchmarking:
"$28 – $100 / hour",
"$211.4K – $290.6K • Offers Equity". Parsing those into numbers is guesswork about
currency, period and whether equity is included.
Recruitee keeps the salary object present with zeros when the employer skipped the field, so a
naive reader ships "0 USD hour" as a pay range. Treat
min <= 0 && max <= 0 as absent.
Seven date effectively everything. Personio, Rippling, Pinpoint and BambooHR publish no
date at all, and Workday dates only 78.2% of rows because it ships prose
— "Posted Today", "Posted 30+ Days Ago" — instead of a timestamp. An
exact age can be converted; 30+ genuinely is unknown.
If you are building a "posted in the last 7 days" filter, that is a design decision, not a detail: you either drop undated rows and silently lose a third of the market, or keep them and let the filter mean less than it says. Saying which one you did is the honest option.
Five publish a work-arrangement field the employer filled in: Ashby, Recruitee, Workable,
Pinpoint and SmartRecruiters. The other seven do not, so the only option there is pattern-matching
the location string — which misses "Anywhere" and misfires on
"Remote Support Engineer, London office".
The spread between platforms says more about their customers than about the job market. 54.2% of Ashby postings are marked remote; Lever, where the flag has to be inferred, resolves to 4.8%.
BambooHR is the trap. It has an isRemote field, so a reader assumes it works.
Across 50,616 postings measured, not one had it set.
Each of these goes deeper on one API — the exact request shape, what it returns measured across every live board, the mistakes that cost us time, and how its boards are actually found:
Greenhouse · Lever · Ashby · Workday · SmartRecruiters · Workable · Breezy HR · Personio · Recruitee · BambooHR · Pinpoint · Rippling
All of these answer without a key. Replace {company} with the board slug.
| Platform | Endpoint |
|---|---|
| Greenhouse | https://boards-api.greenhouse.io/v1/boards/{company}/jobs?content=true |
| Lever | https://api.lever.co/v0/postings/{company}?mode=json |
| Ashby | https://api.ashbyhq.com/posting-api/job-board/{company}?includeCompensation=true |
| SmartRecruiters | https://api.smartrecruiters.com/v1/companies/{company}/postings?limit=100&offset=0 |
| Workable | https://apply.workable.com/api/v1/widget/accounts/{company}?details=true |
| Breezy HR | https://{company}.breezy.hr/json |
| Personio | https://{company}.jobs.personio.de/search.json |
| Recruitee | https://{company}.recruitee.com/api/offers/ |
| BambooHR | https://{company}.bamboohr.com/careers/list |
| Pinpoint | https://{company}.pinpointhq.com/postings.json |
| Rippling | https://api.rippling.com/platform/api/ats/v1/board/{company}/jobs |
| Workday | POST https://{tenant}.{cluster}.myworkdayjobs.com/wday/cxs/{tenant}/{site}/jobs |
limit you pass. Page with offset, and take the real count from
totalFound rather than counting rows.403, not 404, for a subdomain with
no board on it. Treating that as rate limiting will make you back off from boards that simply
do not exist.total at 2000 and keeps serving rows past the
end of the list, so probing offsets until a page comes back empty never terminates. The
facets counts are the real total. Site names are case-insensitive, so the same
board arrives twice unless you lowercase the key./careers/list has no date,
description or compensation; those live on /careers/{id}/detail, one request per
posting.urlkey, so a domain's own pages
fill the first pages and customer subdomains sit deep in the index. Reading only the first few
pages is how you conclude a platform "has no public boards" when it has thousands.The code behind these measurements is open: github.com/HwangByeongSeon/ats-job-feed-recipes. If you would rather not maintain twelve clients and a board registry, the same engine runs as a hosted Actor that emits one row shape across every platform above — Career Site Job Feed, or New Job Alerts if you only want what changed since your last run.
Single-platform Actors, if you only need one: Greenhouse · Lever · Ashby · Workday · Workable · SmartRecruiters · Breezy HR · Personio · Recruitee · Rippling · Pinpoint
Each platform's board registry was walked in full and every live board's listing endpoint was read once. A field counts as present when the parsed row carries a non-null value for it, using the same normalizer across all twelve platforms so the columns are comparable. Boards that answered with an error or returned no postings were excluded rather than counted as zeros.
The numbers move. Boards close at roughly 0.6% every day and a half, and employers fill fields differently over time. The date on this page is the date it was measured.