# Sources & ATS coverage

> What the source field means, the exact values it can take, and which ATS platforms are covered.

Source: https://hyperjobs.io/docs/reference/sources

Every posting carries a [`source`](/docs/objects/job#identity) naming the board
it was ingested from, and every [`id`](/docs/objects/job#identity) is prefixed
with it:

```json
{ "id": "ashby:7c1f2a94-…", "source": "ashby" }
```

`source` is also a filter on [`/v1/jobs`](/docs/api-reference/jobs-list) — an
**exact, case-sensitive** match, comma = OR — and `exclude_source` takes the
same values to filter platforms out. The filter takes the **public
slug**, which matches the keys of
[`/v1/meta`](/docs/api-reference/meta)`.sources` exactly.

## The live values

<Note title="`lever`, not `lever.co` — one vocabulary everywhere">
  In a pre-release draft of this API, Lever postings could only be filtered
  with the stored value `lever.co`. The public slug is the value everywhere —
  the filter, the `/v1/meta` keys, **and** the `source` field on every Job
  payload — and the stored value is still accepted as input for compatibility:

  ```bash
  curl "…/v1/jobs?source=lever"      # ✓ — the slug; payloads read "source": "lever" too
  curl "…/v1/jobs?source=lever.co"   # ✓ — stored value, still accepted as input
  curl "…/v1/jobs?source=Greenhouse" # ✗ — 0 rows, case-sensitive
  ```

  A `source` you read in a response can always be fed straight back as a
  filter. (Job **ids** keep their stored prefix — a Lever id still starts
  `lever.co:` — since ids are stable identifiers, not vocabulary.)
</Note>

These are every value `source` takes, and every one of them returns rows. There
is no second tier: a platform we can read is in this list, and a platform that
stops returning rows leaves it rather than lingering as a value that matches
nothing. Each has a page under [/ats](/ats) describing what its boards look like
and what the adapter reads.

`adp` · `amazon` · `apple` · `applicantpro` · `applitrack` · `ashby` · `bamboohr` ·
`breezy` · `careerplug` · `comeet` · `cornerstone` · `dayforce` · `deel` · `dover` ·
`eightfold` · `firststage` · `freshteam` · `gem` · `gohire` · `google` ·
`greenhouse` · `hibob` · `hirebridge` · `hirehive` · `hireology` · `hiringthing` ·
`homerun` · `ibm` · `icims` · `isolved` · `jazzhr` · `jobscore` · `jobvite` ·
`join_com` · `kula` · `lever` · `linkedin` · `manatal` · `microsoft` · `oracle` ·
`pageup` · `paycom` · `paycor` · `paylocity` · `peopleadmin` · `personio` ·
`phenom` · `pinpoint` · `polymer` · `recruitee` · `recruiterbox` · `rippling` ·
`rival` · `smartrecruiters` · `successfactors` · `taleo` · `teamtailor` · `tiktok` ·
`trinet` · `uber` · `ultipro` · `werecruit` · `workable` · `workday` ·
`ycombinator` · `zohorecruit`

<Warning title="An empty result is not a bug">
  `source` is a csv filter, not an enum — an unknown value isn't a `400`, it
  simply matches nothing. So a typo fails **silently**: `?source=Greenhouse`
  (case) and `?source=lever.com` (spelling) both return an empty array that looks
  identical to "no jobs match your other filters".

  If you are branching on a source, check it against the keys of
  [`/v1/meta`](/docs/api-reference/meta)`.sources` rather than hardcoding the list
  above — that is the only list that is true at the moment you read it.
</Warning>

## Volume by source

Counts are a snapshot and move hourly, and they are wildly uneven. The largest
sources:

| `source` | Platform | Postings |
| --- | --- | --- |
| `smartrecruiters` | SmartRecruiters | 276,430 |
| `workday` | Workday | 148,812 |
| `oracle` | Oracle | 146,650 |
| `linkedin` | LinkedIn | 87,462 |
| `successfactors` | SuccessFactors | 82,140 |
| `lever` | Lever | 77,275 |
| `greenhouse` | Greenhouse | 58,723 |
| `bamboohr` | BambooHR | 55,752 |
| `ashby` | Ashby | 55,626 |
| `manatal` | Manatal | 48,926 |
| `ultipro` | UKG Pro | 47,180 |
| `join_com` | Join.com | 44,225 |
| `applitrack` | AppliTrack | 41,110 |
| `teamtailor` | Teamtailor | 39,050 |
| `jazzhr` | JazzHR | 36,391 |
| `workable` | Workable | 36,234 |
| `breezy` | Breezy HR | 32,061 |
| `recruitee` | Recruitee | 29,378 |
| `dayforce` | Dayforce | 28,727 |
| `hireology` | Hireology | 23,905 |

The shape worth knowing is that it is **heavily skewed**: the top five sources are
more than half the dataset, and the tail runs down to three figures — `trinet`,
`applicantpro` and `taleo` are hundreds of postings each, not tens of thousands.

That skew is not a quality signal. A source's size reflects how many companies use
that ATS and how reachable its boards are — nothing else. SmartRecruiters being
five times Y Combinator says nothing about which produces better data for you, and
in one measurable respect it says the opposite: `ycombinator` carries a salary on
80% of its postings against a dataset-wide 36%.

<Note title="Don't rank on the count alone">
  If you are choosing sources to ingest, read
  [coverage](/docs/reference/coverage) next to the volume. The fields you need may
  be better filled on a small source than a large one.
</Note>

## Where postings come from

Postings are read from **employers' own job boards** — the Greenhouse or Ashby
instance a company runs for itself — rather than bought from an aggregator. 65
board adapters cover the platforms those boards run on, plus LinkedIn, which is
search-based rather than a board adapter.

That "rather than bought from an aggregator" is a deliberate exclusion, not a gap
in coverage. Adapters exist for the big remote boards and government feeds, and
they work — they're switched off because an aggregator is many employers in one
undifferentiated pool, and pooling them back together is the problem this API
exists to solve. What you get instead is the employer's own board, which is where
[`apply_url`](#attribution-and-provenance) becomes worth something.

### Multi-tenant ATS

Platforms hosting boards for many companies. These are the bulk of coverage: one
adapter reaches thousands of employers.

`adp` · `applicantpro` · `applitrack` · `ashby` · `bamboohr` · `breezy` ·
`careerplug` · `comeet` · `cornerstone` · `dayforce` · `deel` · `dover` ·
`eightfold` · `firststage` · `freshteam` · `gem` · `gohire` · `greenhouse` ·
`hibob` · `hirebridge` · `hirehive` · `hireology` · `hiringthing` · `homerun` ·
`icims` · `isolved` · `jazzhr` · `jobscore` · `jobvite` · `join_com` ·
`kula` · `lever` · `manatal` · `oracle` · `pageup` · `paycom` ·
`paycor` · `paylocity` · `peopleadmin` · `personio` · `phenom` · `pinpoint` ·
`polymer` · `recruitee` · `recruiterbox` · `rippling` · `rival` ·
`smartrecruiters` · `successfactors` · `taleo` · `teamtailor` · `trinet` · `ultipro` ·
`werecruit` · `workable` · `workday` · `zohorecruit`

### Single-company

Employers large enough to run bespoke career sites that need their own adapter.
There is no "many boards" problem here — there is one site, and it breaks on its
own schedule:

`amazon` · `apple` · `google` · `ibm` · `microsoft` · `tiktok` · `uber`

### Job boards

A posting here was published to a board or collected by one, **not** to a
company's own careers page — which changes what
[`apply_url`](#attribution-and-provenance) points at. There are two, and they earn
the exception for opposite reasons:

`ycombinator` · `linkedin`

Y Combinator's Work at a Startup is a board per company rather than one pooled
feed, which makes it behave like an ATS even though it isn't one.

### LinkedIn

Search-based rather than a board adapter, and refreshed as an hourly delta of the
last hour's postings. It's the fourth-largest source and the largest that isn't an
employer's own board — which is worth knowing when you read
[`apply_url`](#attribution-and-provenance) on a `linkedin` posting.

## Boards tracked per provider

The ingestion queue tracks **108,389** individual company boards. The twenty
largest queues:

| Provider | Boards tracked |
| --- | --- |
| `join_com` | 23,664 |
| `bamboohr` | 15,184 |
| `greenhouse` | 10,023 |
| `workday` | 9,014 |
| `workable` | 5,794 |
| `lever` | 4,816 |
| `ashby` | 4,295 |
| `personio` | 2,962 |
| `smartrecruiters` | 2,835 |
| `jazzhr` | 2,754 |
| `paylocity` | 2,653 |
| `adp` | 2,611 |
| `hireology` | 2,508 |
| `rippling` | 1,967 |
| `icims` | 1,598 |
| `recruitee` | 1,546 |
| `ycombinator` | 1,497 |
| `applitrack` | 1,486 |
| `breezy` | 1,435 |
| `successfactors` | 1,313 |

Boards, not postings — one board is one company's careers page, holding anywhere
from zero to several thousand open roles.

### A tracked board is not a guarantee of postings

Tracking a board means knowing it exists and attempting it on a schedule. Postings
appear only if the board is reachable, still live, and currently advertising
something — and boards go quiet: a company freezes hiring, migrates ATS, or takes
its board down. [Boards that fail five consecutive times are disabled
automatically](/docs/reference/coverage#refresh-cadence). So a provider's board
count is an upper bound on where its postings could come from, never a promise of
how many you'll get.

The reverse holds too, and it is the more useful lesson: `bamboohr` leads on boards
tracked while `smartrecruiters` has a fraction of the boards and an order of
magnitude more postings. Board count and posting count measure different things —
BambooHR is popular with small companies that have few open roles at a time.

The practical rule: **[`/v1/meta`](/docs/api-reference/meta) is the only authority
on what you can filter on.** This page explains what the values mean; `/v1/meta`
says which exist right now.

## Attribution and provenance

Because postings come from employers' own boards,
[`apply_url`](/docs/objects/job#identity) is the employer's real application
form — the same URL a candidate would reach from the company's careers page. It
isn't a redirect, a tracking wrapper, or an aggregator's mirror.

Two consequences:

- **Applications land in the employer's ATS.** Sending a candidate to `apply_url`
  puts them in the real pipeline, not a queue that forwards later.
- **`apply_url` falls back to `url`.** When a board publishes no distinct apply
  link, the two fields are identical. See
  [derivations](/docs/objects/job#apply_url-falls-back-to-url).

<Note>
  `linkedin` is the exception worth flagging: it's search-based rather than an
  employer's own board, so a `linkedin` posting's `apply_url` points wherever
  LinkedIn points. When a posting matters enough to verify, check `source` before
  assuming the URL is the employer's own form.
</Note>

That distinction is queryable: every posting carries a `source_type` —
`ats` (a board the employer authors and manages applicants on), `jobboard`
(third-party boards like LinkedIn or Wellfound), or `aggregator` (re-listing
sites) — and `?source_type=` filters on it, comma = OR. Some providers sell
this split as two separate products: an "ATS jobs" endpoint and a "job board
jobs" endpoint, each with its own schema, because their pipelines never merge
the populations. Ours do merge — cross-source mirrors are
[folded by dedup](/docs/guides/deduplication) — so provenance is one filter on
one schema rather than two endpoints. One classification worth knowing:
**join.com counts as `ats`** — the employer authors the posting and manages
applicants there, which is the property `source_type` measures. (Dedup priority
is a different question with a different answer: a join.com copy still loses to
the employer's Greenhouse board when both exist.)

The same job posted to several boards is [collapsed to one
row](/docs/guides/deduplication) rather than returned five times, so `source`
tells you which copy survived deduplication — not the only board the job ever
appeared on.

## Related

<CardGroup cols={2}>
  <Card title="Dataset metadata" icon="Activity" href="/docs/api-reference/meta">
    Live source counts, and the authoritative `?source=` vocabulary.
  </Card>
  <Card title="Enums & vocabularies" icon="ListChecks" href="/docs/reference/enums">
    Every other exact-match filter value.
  </Card>
  <Card title="Dataset coverage" icon="Database" href="/docs/reference/coverage">
    How often boards refresh and how fresh the data is.
  </Card>
  <Card title="Duplicates & collapsing" icon="Copy" href="/docs/guides/deduplication">
    What happens when one job is posted to several boards.
  </Card>
</CardGroup>
