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.
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 — it moves, and this
sentence doesn't.
Try it#
curl -G https://api.hyperjobs.io/v1/jobs \
-H "Authorization: Bearer $HYPERJOBS_KEY" \
--data-urlencode "source=trinet" \
--data-urlencode "limit=2"{
"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:
# 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#
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.
There is no posting date anywhere on the platform. Checked across eight postings on five tenants; nothing matches a date field on either level.
What that means for `posted_at`
posted_at falls back 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.
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'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 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 — which on this platform is the whole
problem, since the board itself will only ever tell you 324552.
Same schema as every other source, same filters, one API key. Refresh cadence varies by source; see coverage.
Query it with ?source=trinet.
Quickstart · Pricing
Every source above normalises onto the same schema, with the hiring company already joined onto each posting.
Get an API key