# TriNet Hire Jobs API

> Query jobs from TriNet Hire boards through one API with ?source=trinet — plus how its embed endpoint behaves, and why the boards never name their employer.

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

TriNet Hire is the ATS attached to TriNet's PEO business — the co-employment
service US small and mid-size companies outsource HR to. Boards live at
`app.trinethire.com/companies/<cid>`, addressed by a bare number.

This is a **small source**: 122 postings in this dataset, from a small pool of
boards. It's worth saying that up front rather than at the bottom, because it
changes whether this page is useful to you. If you need TriNet coverage, it's
here and it's real. If you're sizing a market, 122 is the whole of it today. Read
the live figure from [`/v1/meta`](/docs/api-reference/meta) — it moves, and this
sentence doesn't.

## Try it

```bash
curl -G https://api.hyperjobs.io/v1/jobs \
  -H "Authorization: Bearer $HYPERJOBS_KEY" \
  --data-urlencode "source=trinet" \
  --data-urlencode "limit=2"
```

```json title="Illustrative — the shape, not a live response"
{
  "data": [
    {
      "id": "trinet:324552_18841",
      "title": "Field Operations Manager",
      "company": {
        "slug": "ridgeline-energy",
        "name": "Ridgeline Energy",
        "domain": "ridgelineenergy.com",
        "website": "https://ridgelineenergy.com",
        "logo": "https://media.licdn.com/dms/image/…",
        "industry": "Renewable Energy",
        "employee_count": 240
      },
      "location": {
        "remote": false,
        "countries": ["United States"],
        "cities": ["Raleigh"],
        "regions": ["North Carolina"],
        "raw": ["Raleigh-Durham"]
      },
      "employment_type": ["FULL_TIME"],
      "work_arrangement": null,
      "seniority": null,
      "salary": {
        "min": null,
        "max": null,
        "currency": null,
        "unit": null,
        "annual_min": null,
        "annual_max": null,
        "summary": "$66,300"
      },
      "skills": ["operations", "field service"],
      "taxonomies": ["Operations"],
      "apply_url": "https://app.trinethire.com/companies/324552/jobs/18841",
      "url": "https://app.trinethire.com/companies/324552/jobs/18841",
      "source": "trinet",
      "posted_at": "2026-07-11T07:15:33.000Z",
      "expires_at": null,
      "updated_at": "2026-07-14T07:15:33.000Z"
    }
  ],
  "total": 2,
  "limit": 2,
  "offset": 0
}
```

Two things in there are the platform rather than us: the `salary` object with a
string and no numbers, and `posted_at`. Both below.

## How TriNet Hire boards actually work

Two GETs, no auth, no JSON:

```bash
# 1. List — the embed variant: identical jobs, a third of the bytes
curl "https://app.trinethire.com/companies/<cid>/jobs/embed"

# 2. Detail — one per posting; the body only exists here
curl "https://app.trinethire.com/companies/<cid>/jobs/<jid>-<slug>"
```

`/jobs/embed` returns the same job set as `/jobs` at about 5.2KB against 14KB,
because it drops the page chrome. There's no JSON API and **no JSON-LD** — zero
blocks, confirmed — so it's HTML at both levels.

`?page=2` is silently ignored: the id list came back identical on all five tenants
tested, and there's no pagination UI. So the single response is the board. The
largest board sampled held 16 postings, which means a cap above 16 is **unproven**
rather than ruled out — flagging that is more honest than asserting there's no
cap.

`boardToken` is the numeric `cid`. The slug in the URL is decorative:
`/companies/324552/jobs` and `/companies/324552-zzz-wrong/jobs` return the same
content.

## What bites you

<Warning title="A TriNet board never names its employer">
  The board is addressed by a bare number and the source carries **no employer
  name at all** — not on the list, not on the detail. There's no slug to
  title-case into something plausible, the way `jobs.lever.co/northwind` gives you
  "Northwind" for free.

  So on this platform a scraped job cannot reach a company from the board alone.
  It takes an external join, and without one you have a posting attributed to
  `324552`. That's the real cost of TriNet, and it isn't parsing.
</Warning>

**There is no posting date anywhere on the platform.** Checked across eight
postings on five tenants; nothing matches a date field on either level.

<Note title="What that means for `posted_at`">
  [`posted_at` falls back](/docs/objects/job#timestamps) to **our first sight of
  the posting** rather than going null. It's a sound ordering key and a sound
  "newer than X" filter, and it is not a claim about the employer's own timeline.
  On this source it never can be.
</Note>

**The `job-meta` list is optional and variable.** Category and Salary appear on
some postings and not others, so an index-based read silently returns the wrong
field on any posting missing an earlier one — the same failure as
[Jobvite](/ats/jobvite)'s meta line. Key off the `<strong>` label.

**The list's location line is `" - "`-joined, and office names contain hyphens.**
`IONNA LLC-HQ - Raleigh-Durham - Full-time` does not split into three fields; it
splits into a mess. The detail's `job-meta` separates location and type cleanly,
which is why the location comes from there.

**Salary is free text and it's rarely a number.** `$66,300`, `$20.00 per hour`,
`$65,000 - $68,000` — no structured field, no period, sometimes no amount. Where
there's no stated period we keep the text and emit no number, which is why
[`salary`](/docs/objects/job#salary) on this source is frequently a non-null
object whose only populated field is `summary`. A non-null salary is not a usable
number here.

## Or use ours

The honest pitch on a source this size isn't "you couldn't build this". You
could — it's two GETs and some careful HTML. It's that you'd build it, and the
next one, and the one after, and TriNet would be 122 rows of it.

What you get is the cheap embed endpoint rather than the fat one, the meta fields
read by label so a posting without a Category doesn't report its type as one, the
location taken from the detail instead of a hyphen-split that mangles it, salary
left as text rather than annualised from a bare figure, and the
[company join](/docs/objects/company) — which on this platform is the whole
problem, since the board itself will only ever tell you `324552`.

Same schema as every other [source](/docs/reference/sources), same filters, one
API key. Refresh cadence varies by source; see
[coverage](/docs/reference/coverage).

Query it with `?source=trinet`.
[Quickstart](/docs/quickstart) · [Pricing](/pricing)
