Endpoints / Dataset metadata

Dataset metadata

Live counts, per-field coverage, the freshness timestamp, and the exact source vocabulary.

GET/v1/meta
GEThttps://api.hyperjobs.io/v1/meta

Live dataset statistics: how many jobs, how many companies, how fresh, the breakdown by source — and coverage_pct, the measured fill rate of every enriched field. One cheap request, no parameters.

curl -H "Authorization: Bearer $HYPERJOBS_KEY" https://api.hyperjobs.io/v1/meta

Query parameters#

None. The endpoint takes no input; anything you send is ignored.

It does require a key, unlike /v1/health, and it counts against your rate limit and monthly quota like any other authenticated call.

Response#

jobs
integer

Live postings — non-duplicate and non-expired. This is the population /v1/jobs searches, and it's the same number /v1/health reports.

companies
integer

Companies with an enriched profile. See the Company object.

newest
string

ISO 8601 timestamp of the most recent posting — the freshness signal. The index refreshes hourly.

sources
object

Map of public source slug to posting count, sorted descending by count. The keys are the exact valid values for ?source=lever, not the stored lever.co.

coverage_pct
object

Live per-field fill rates, as percentages of the searchable pool: country, skills, work_arrangement, seniority, taxonomies, salary, education, language. Remeasured roughly every 15 minutes — see below.

full_text_search
boolean

Whether Google-style and advanced text search (title, description, title_advanced, description_advanced) is active on this deployment.

version
string

API version, e.g. "1.0.0".

Response
{
  "jobs": 596768,
  "companies": 158545,
  "newest": "2026-07-16T09:48:15.000Z",
  "sources": {
    "smartrecruiters": 216791,
    "linkedin": 87462,
    "lever": 74374
  },
  "coverage_pct": {
    "country": 96.8,
    "skills": 83.7,
    "work_arrangement": 91.2,
    "seniority": 88.7,
    "taxonomies": 63.9,
    "salary": 36.0,
    "education": 71.5,
    "language": 94.2
  },
  "full_text_search": true,
  "version": "1.0.0"
}

That's the entire shape — there are no other keys.

The sources keys are the ?source= vocabulary#

The keys are public slugslever, not the stored value lever.co that an early draft of this API exposed — and they are exactly what ?source= on /v1/jobs accepts and what the source field on every Job payload carries: one vocabulary everywhere. (?source=lever.co still works as input for backward compatibility, but you'll never see it in a response.)

So /v1/meta remains the authoritative answer to "what can I pass to ?source=" — read the keys rather than guessing:

JS
const { sources } = await (await fetch(url, { headers })).json();
if (!(userInput in sources)) {
  throw new Error(`Unknown source. Valid: ${Object.keys(sources).join(", ")}`);
}

That check is still worth writing: source is an open vocabulary rather than a fixed enum, so an unrecognized value returns an empty result instead of a 400. The sources reference has the prose version, including which ATS each slug corresponds to.

Published coverage#

coverage_pct is the honesty feature: we publish the fill rate of every enriched field, measured live against the searchable pool, refreshed about every 15 minutes. When salary coverage is 36.6%, the API says 36.6 — you can size a has_salary=true result set before you query, and you never have to wonder whether a low fill rate is your filter or our data.

Read it before building on any enriched field, and see dataset coverage for what drives each number.

`jobs` matches /v1/health

In a pre-release draft, /v1/health counted every row — duplicates and expired included — and reported a higher number than /v1/meta. Both endpoints report the same live (non-duplicate, non-expired) count. Quote it from either.

Use it instead of hardcoding numbers#

The dataset grows hourly. Anything that states a count — a dashboard, a landing page, a "we track N jobs" line — should read it from here at build or request time rather than baking in a number that starts rotting immediately.

newest is the freshness check: if it drifts more than a couple of hours from now, ingestion is behind, and that's more diagnostic than any count.

Errors#

StatusCause
401Missing, unknown, or revoked key.
429Rate limit exceeded, or monthly quota spent.
500Server error. Retry with backoff.

No 400 — there's nothing to send that could be malformed.

Was this page helpful?