# 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.

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

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

```bash
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"
```

```json title="Illustrative — the shape, not a live response"
{
  "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:

```bash
# 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](/ats/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](/ats/ashby)'s geo tiers, same reasoning.

## What bites you

<Warning title="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.
</Warning>

**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](/ats/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](/docs/objects/company) — 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](/docs/reference/coverage).

[Quickstart](/docs/quickstart) · [Pricing](/pricing)
