Rippling Jobs API
Query jobs from Rippling ATS boards through one API — and how Rippling's board endpoint, repeated uuids and location-label arrangements work.
Rippling bundles HR, IT and finance, and its ATS ships career boards at
ats.rippling.com/<slug>. The public API is clean JSON, no auth, no proxy needed,
and the data model has one genuinely unusual property: Rippling publishes
structured pay ranges per location, but encodes the work arrangement as a prefix
in a location label. So the platform gives you good salary and makes you parse
a string to find out whether the job is remote.
Try it#
curl -G https://api.hyperjobs.io/v1/jobs \
-H "Authorization: Bearer $HYPERJOBS_KEY" \
--data-urlencode "source=rippling" \
--data-urlencode "time_frame=7d" \
--data-urlencode "limit=2"{
"data": [
{
"id": "rippling:3f9a12c8-77d4-4e02-b6a1-9e5c0d3b8a71",
"title": "Implementation Consultant",
"company": {
"slug": "quill-systems",
"name": "Quill Systems",
"domain": "quillsystems.com",
"website": "https://quillsystems.com",
"logo": "https://media.licdn.com/dms/image/…",
"industry": "Software Development",
"employee_count": 310
},
"location": {
"remote": true,
"countries": ["United States"],
"cities": null,
"regions": null,
"raw": ["Remote (US)"]
},
"employment_type": ["FULL_TIME"],
"work_arrangement": "Remote",
"salary": {
"min": 95000,
"max": 130000,
"currency": "USD",
"unit": "YEAR",
"annual_min": 95000,
"annual_max": 130000,
"summary": null
},
"skills": ["implementation", "saas onboarding"],
"taxonomies": ["Customer Service"],
"apply_url": "https://ats.rippling.com/quill-systems/jobs/3f9a12c8-77d4-4e02-b6a1-9e5c0d3b8a71",
"url": "https://ats.rippling.com/quill-systems/jobs/3f9a12c8-77d4-4e02-b6a1-9e5c0d3b8a71",
"source": "rippling",
"posted_at": "2026-07-10T17:05:00.000Z",
"expires_at": null,
"updated_at": "2026-07-14T01:11:29.000Z"
}
],
"total": 2,
"limit": 2,
"offset": 0
}How Rippling boards actually work#
Two steps. The list has no description and no date, so the detail is mandatory:
# 1. List
curl "https://api.rippling.com/platform/api/ats/v1/board/<slug>/jobs"
# 2. Detail — description, dates, employment type, pay
curl "https://api.rippling.com/platform/api/ats/v1/board/<slug>/jobs/<uuid>"<slug> is the board segment from ats.rippling.com/<slug>. Note that every
board shares the one api.rippling.com host — unlike
Workday, where each tenant has its own. That's convenient for
discovery and a reason to keep fan-out modest, since concurrency across boards all
lands on the same host.
The list gives you uuid, name, url, department and workLocation. The
detail adds description, workLocations[], employmentType, createdOn,
payRangeDetails[] and a board object with the company's logo and URL.
The description is two fields#
description is an object: { company, role }. role is the actual job body;
company is the about-us blurb. Both are HTML. Keep both, role first — or keep
just role if you don't want every posting to end with the same paragraph. What
you shouldn't do is read description as a string, because it isn't one.
Pay is per location#
payRangeDetails[] is an array of { currency, frequency, rangeStart, rangeEnd, isRemote }
— one entry per location the job is posted in. The posted band is the outer
envelope: the minimum of the starts, the maximum of the ends. Same shape as
Ashby's geo tiers, same reasoning.
What bites you#
The list repeats a uuid once per work location
A job posted in three cities appears three times in the list, same uuid, one
location each. Build documents straight from the list array and three rows share
one deterministic id — each overwrites the last, and you keep one location out
of three with no error anywhere.
Collapse by uuid first and collect every location as you go.
The work arrangement is a prefix in the location label. There's no arrangement
field. What there is: Remote (US), Hybrid (Austin), or a plain city meaning
on-site. Roughly 22% of postings carry a parseable arrangement in the label,
including hybrid, which would otherwise be lost entirely. The structured
payRangeDetails[].isRemote boolean is a weaker fallback — it can't express
hybrid, and it only exists when pay does.
This is the same technique Personio needs for the same reason: the platform has no field for it, so employers type it where the location goes.
employmentType has two useful halves. label is a stable enum —
SALARIED_FT, HOURLY_PT, CONTRACTOR, TEMP. id is the human string,
Salaried, full-time. The enum is what you normalise; the string is what you
show. And TEMP is the live value on roughly 1.4% of jobs — miss it from your
mapping and those rows lose their employment type silently.
department and workLocation are sometimes objects, sometimes strings. Both
shapes occur. Code that assumes .label throws on the string form; code that
assumes a string stores [object Object].
There's no posted date on the list. createdOn is detail-only, so a
list-only pass gives you jobs with no dates at all.
Or use ours#
Rippling's API is pleasant and its traps are structural rather than adversarial — nothing here blocks you, it just quietly gives you less than you think you got.
You get the repeated uuids collapsed with their locations unioned, the arrangement recovered from the label prefix, the outer pay band across every location, the role and company description assembled, both field shapes handled, and the detail N+1 paid only for postings we haven't already seen. We track 1,923 Rippling boards.
Plus dedup against the same role on other boards, expiry by board diffing, and the company join — though Rippling is one of the few that hands you a logo and a company URL directly.
Rippling is in the fast refresh tier, attempted every cycle — see coverage.
Every source above normalises onto the same schema, with the hiring company already joined onto each posting.
Get an API key