# HireHive Jobs API

> Query jobs from HireHive boards through one API with ?source=hirehive — plus how HireHive's cross-tenant aggregator really behaves.

Source: https://hyperjobs.io/ats/hirehive

HireHive is recruiting software for small and mid-sized employers and the
agencies that staff them, with boards at `<tenant>.hirehive.com`. It's a small
platform, and it does one thing almost no ATS does.

## It has a public cross-tenant aggregator

Most ATS give you a per-tenant endpoint and nothing else, which means the board
list is your problem and the board list is the hard part. HireHive inverts that.
There is **no per-tenant API at all** (`/v1/{slug}/jobboard` returns 404), and
instead there is one public endpoint that returns everyone:

```bash
curl "https://api.hirehive.com/v1/hirehive/jobboard?top=2000"
```

**1,562 jobs across 256 tenants, in one unauthenticated call.** The `hirehive` in
that path is not a tenant slug — it's a public aggregator key. Discovery and
listing are the same request, which is the same trick
[WeRecruit](/ats/werecruit)'s sitemap pulls and one of only a handful of
cross-tenant routes anywhere in this pool.

So this platform reverses the usual work: there's no discovery to do, and the
whole difficulty is in the two ways the aggregator lies to you.

## `skip` is silently ignored

The endpoint takes `top`. It appears to take `skip`. It does not.

Proven with `top=10`: `skip=0` and `skip=10` return the **identical 10 ids**. So
do `offset`, `page`, `limit` and `$skip`. Every one of them returns HTTP 200 with
a perfectly plausible page of results, which happens to be page one again.

<Warning title="What that costs you">
  An adapter that loops on `skip` fetches page one **fifty-two times** and stores
  **100 of 1,562** jobs. Nothing errors. Nothing 400s. Every request is a 200,
  the run completes, and you are missing 94% of the platform with no signal that
  anything went wrong.

  `data.pages` doesn't save you either: it's computed client-side from the `top`
  **you** sent, so it will happily report a page count for a thing that only ever
  serves one page. Don't loop on it.
</Warning>

The fix is to stop paginating. Ask for `top=2000`, take the whole platform in one
call, and filter per board in memory.

## The detail's date is a rolling SEO date

The aggregator rows carry no body, so the description comes from the job's own
page (`hosted_url`), which does carry schema.org JSON-LD. Read the whole JSON-LD
and you inherit a quiet corruption: **`datePosted` is synthetic**.

A job whose list `published_date` is 2026-01-15 reports `datePosted` of
2026-07-01. Six months out. Every old job on the platform reports that same
rolling date, because it's tuned for search engines rather than for you. A feed
built on it says the entire back catalogue was posted this week.

The list's `published_date` is the truth. It's unix **seconds**, not
milliseconds. So `postedAt` comes from the list and only the description comes
from the detail — the JSON-LD is right about the body and wrong about the date,
and you have to want fields from it selectively rather than trust it whole.

## Two smaller ones

**`/rss` and `/feed` return 200 with the board's HTML**, not a feed. That's an
HTTP 200 and a `Content-Type` you can't lean on, so a feed parser gets a document
and finds no items.

**The aggregator is a near-complete subset, not a mirror.** `patagonia` shows 18
jobs through the aggregator and 19 on its own board. Small, consistent, and worth
knowing before you reconcile counts against a customer's careers page.

Where the aggregator is generous: each row carries `company_name` — the real
employer, not a slug — plus a logo, a structured `country` that the free-text
location label often omits, an experience band and a category. Descriptions came
back at 100% on the boards tested (`cornmarket` 13/13, `patagonia` 18/18).

## Where this stands

`?source=hirehive` is served today. At 1,562 jobs, HireHive is a small source and
it will never be a big one. It's covered because the cost of covering it is one
request, and because a platform that hands you every tenant for free deserves to
be taken up on it.

The keys of [`/v1/meta`](/docs/api-reference/meta)`.sources` are the live
vocabulary — the values `?source=` actually accepts, with counts, and the only
thing worth coding against. [Sources & coverage](/docs/reference/sources) says the
same thing in prose.

See [all platforms](/ats) · [quickstart](/docs/quickstart).
