The HyperJobs API is live
A read-only jobs API with the hiring company attached to every posting. What shipped, who it is for, and where the rough edges are.
HyperJobs is a read-only HTTP API over a continuously refreshed dataset of job postings, scraped directly from company ATS boards — Greenhouse, Lever, Ashby, Workday, SmartRecruiters and 60-odd others — enriched with skills, seniority, salary and location, and joined to firmographics for the company doing the hiring.
It is available now. There is a free tier, and you can be making requests in about two minutes.
Revised 2026-07-16: the v1 that launched is a redesign of the surface this post originally announced — strict validation, comma = OR, cursor pagination, salary range-overlap filters, and four more endpoints shipped before any production consumer existed. The "rough edges" section below originally listed the draft's traps; it now lists the real ones.
The defining property is the join#
Every job carries its company inline:
{
"id": "ashby:0f2c…",
"title": "Senior C++ Engineer",
"company": {
"slug": "stripe",
"name": "Stripe",
"domain": "stripe.com",
"industry": "Financial Services",
"employee_count": 8000,
"hq": { "country": "US", "locality": "South San Francisco" }
},
"location": { "remote": false, "countries": ["United States"], "cities": ["New York"] },
"salary": { "annual_min": 180000, "annual_max": 240000, "currency": "USD" },
"skills": ["cpp", "cuda", "distributed systems"]
}Most jobs APIs hand you an employer name and leave you to resolve it. Here the company object is already attached, so a query like "remote Rust jobs at Series-B fintechs with more than 200 employees" is one request instead of a search plus N lookups. Why every job carries its company is the long version of that argument.
The data is scraped from employers' own boards, not resold from an aggregator.
That is why apply_url points at the real application form, and why postings
disappear when the employer takes them down.
Who it is for#
Four shapes of user, roughly:
- Job boards and aggregators that need postings with real apply URLs and enough enrichment to build facets over.
- Recruiting and sourcing tools that need "who is hiring for X, and what kind of company are they".
- Market and talent intelligence — demand by skill, by geography, by employer, over time.
- Agents and internal tools that need a jobs corpus behind a single key rather than a scraping project.
If you are considering building the scraping yourself: the hard part is not the first board. It is the sixty-fifth, plus expiry detection, plus the company resolution, forever.
What shipped#
All read-only, all GET. There are no POST/PUT/DELETE routes, no
webhooks and no streaming.
| Endpoint | Purpose |
|---|---|
/v1/jobs | The search. ~50 filters, cursor paging, newest-first. |
/v1/jobs/count | The same filters, count only. |
/v1/jobs/feed | Newly indexed postings, cursor-paged, for incremental sync. |
/v1/jobs/expired | Ids that died — the purge feed for mirrors. |
/v1/jobs/modified | Postings whose tracked fields changed, with what changed. |
/v1/jobs/{id} | One posting. |
/v1/companies | Firmographic search — industry, size, country, has_jobs. |
/v1/meta | Counts, freshness, source vocabulary, live per-field coverage. |
Plus /v1/health and /openapi.json, both
unauthenticated, free and unmetered — use the first for liveness rather than a
limit=1 job query, and the second to generate a client.
Alongside the API:
- The documentation — every endpoint, parameter and response field, plus guides for filtering, feed sync, salary, companies and duplicates.
- An OpenAPI document at
/openapi.json— generated from the same spec module the server validates against, so it cannot drift from the wire. /llms.txt, because a fair number of you will point a model at this before you read a word of it.- A changelog with the compatibility policy.
/v1is stable; breaking changes ship as/v2and/v1keeps working.
Plans#
| Plan | Price | Requests / month | Requests / minute |
|---|---|---|---|
| Free | $0 | 500 | 10 |
| Starter | $49/mo | 50,000 | 60 |
| Growth | $199/mo | 500,000 | 300 |
| Scale | $499/mo | 5,000,000 | 1,000 |
Annual billing is 10× the monthly price — two months free. Every plan gets the full dataset and every filter. Plans differ only in volume; nothing is gated behind a tier, and there is no "contact us to see the data". Above Scale, or for flat-file delivery, talk to us.
The free tier's 500 requests are meant to be enough to answer "is this dataset what I need" without a card. Limits are per account, not per key — ten keys on a Growth plan share one pool. See rate limits.
The rough edges#
The docs are unusually direct about what this API gets wrong, and that is deliberate. Docs that describe intent produce clients broken in exactly the ways that cost the most time. So the reference describes actual behaviour — and where the draft's behaviour was a trap, we fixed the API before launch rather than documenting around it. What's left is real:
- Validation is strict. An unknown parameter or bad value is a
400naming it — never a silent drop. That's a feature, but it means requests that "worked" against sloppier APIs will fail loudly here. skillis the one AND. Commas mean OR on every multi-value filter exceptskill, where every listed token is required.skill=python,awsmeans both.- Open vocabularies can still return silent zeroes.
sourceandskillaren't checked enums, and displayed skills don't always round-trip —skill=Machine Learningis storedmachinelearning. See skills & taxonomies. salary_gteis range-overlap — "the band reaches N", not "pays at least N" — and postings with no upper bound don't match it. Salary data explains the honest floor filter.- Coverage is partial by construction. Enriched fields are classifier
outputs;
/v1/metapublishes live per-field fill rates (coverage_pct) so you can see exactly how partial. No competitor tells you this; it's the number your aggregate rests on. - Descriptions are omitted unless you ask.
description_format=textorhtml. They are multi-kilobyte, and fetching 200 you do not read is the most common way to make this API feel slow.
Known gaps lists what's genuinely missing: no webhooks, no bulk export, no geo/radius search, no configurable sort. Each has a documented workaround. If one of them blocks you, say so — knowing what people actually hit is how that list gets shorter.
Start here#
Get a key
Register and create one from the dashboard. It is shown exactly once, so copy it immediately — only a hash is stored.
Run the quickstart
Two minutes, one authenticated request, one enriched payload.
Read the filtering guide
Filtering is where the real query surface is, and it has two behaviours that will otherwise cost you an afternoon.
Pricing is on the plans page. Questions, bugs, and wrong data go to support — a job id and the request URL is the most useful report we get.
Keep reading
Reading salary data honestly
What the salary fields mean, why coverage is partial by construction, and what salary_gte's range-overlap semantics do and don't promise.
8 min read
How to measure remote hiring share
The query that answers it, and the ways it still lies to you: two remote fields, sparse classifiers, provenance mix, and the archive tail.
7 min read
The same role posted twice is one job
A role mirrored to Greenhouse and LinkedIn is one posting, not two. What deduplication has to decide, and what the API lets you see.
7 min read