# Rippling Jobs Scraper & API - Pay, Descriptions (`automation_craft/rippling-jobs-scraper`) Actor

Scrape every open job from Rippling job boards (ats.rippling.com) by board name or link, or search all 2,189 known boards. One row per job: title, department, locations, employment type, posting date, pay range, full description. Monitor new and closed jobs; misses are free.

- **URL**: https://apify.com/automation_craft/rippling-jobs-scraper.md
- **Developed by:** [Automation Craft](https://apify.com/automation_craft) (community)
- **Categories:** Jobs, Lead generation, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.45 / 1,000 jobs

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Rippling Jobs Scraper & API - Pay, Descriptions

**Rippling Jobs Scraper** reads public Rippling job boards (ats.rippling.com) and returns every open job as one clean row: title,
company, department, every location with country and workplace type, employment type, posting date, pay ranges when the
board shows them, the full description and the employer's screening questions. Give it board names or links, single job
links, or search every board of its built in directory of 2,189 Rippling job boards. No login, no API key, no proxy to set up.

- **One row per job.** Rippling lists a job once per location; this Actor delivers it once, with all its locations, and
  charges it once.
- **The whole job, every time.** Description (HTML and plain text), posting date, employment type, pay ranges per location,
  department path, company description, application questions, apply link.
- **Search all Rippling boards** by title, department, country, workplace type, employment type, posting date or pay, without
  knowing the company names.
- **Monitor** a list of companies: only jobs new since the last run are delivered and charged, and jobs that disappeared from
  a board are reported in free rows.
- **Misses are free**: an unknown board, an empty board, a closed job or a job outside your filters is a free status row.

### Quick start

1. Open the Input tab and put one or more Rippling job boards in **Job boards**: the board name (the part after
   `ats.rippling.com/` in the board's link, for example `rippling` or `carbon-health`) or the link itself.
2. Optionally add **Title keywords**, **Countries** or **Workplace types** to keep only the jobs you need.
3. Set **Maximum jobs** and click **Start**.
4. Download the results as JSON, CSV or Excel from the Output tab, or read them through the Apify API.

To search across companies instead, tick **Search every board in the directory** and add a filter, for example the title
keyword `nurse` and the country `US`.

### What you get

One row per open job (`type: "job"`). The fill rates were measured on 315 jobs from 85 boards and on 600 jobs from 383 boards
(2026-10-11); a field is empty only when the employer left it empty on Rippling.

| Field | What it holds | Filled |
|---|---|---|
| `jobId`, `title`, `company`, `boardSlug` | Rippling's job id, the job title, the company, the board name | 100% |
| `department`, `departmentPath`, `baseDepartment` | the department and its parent departments, top first | 100% |
| `locations` | every location: `name`, `city`, `state`, `stateCode`, `country`, `countryCode`, `workplaceType` (ON_SITE, HYBRID, REMOTE) | 100% |
| `locationNames`, `countryCodes`, `workplaceTypes`, `isRemote` | the same, flattened for spreadsheets | 100% |
| `locationsWithoutDetails` | how many of the job's locations carry a name only (no country or workplace type), never guessed | always (0 on jobs read from a board list) |
| `employmentType`, `employmentTypeName` | Rippling's code (SALARIED_FT, SALARIED_PT, HOURLY_FT, HOURLY_PT, CONTRACTOR, TEMP) and the company's own wording | code 88 to 94%, wording 100% |
| `postedAt`, `postedDate`, `daysSincePosted` | when the job was created on Rippling (UTC) | 100% |
| `payRanges` | pay as the board shows it, per location or for all: `currency`, `period` (HOUR, YEAR, MONTH), `min`, `max` | 23% |
| `payMin`, `payMax`, `payCurrency`, `payPeriod` | the lowest minimum and highest maximum of those ranges, for spreadsheets | 23% |
| `descriptionHtml`, `descriptionText` | the role description, as HTML and as plain text | 99% |
| `companyDescriptionText` | the company's own introduction on the job | 98% |
| `applicationQuestions`, `applicationQuestionCount` | the employer's screening questions on the application form, with type and whether required | 71% have at least one |
| `unlistedFromSearch` | whether the employer hid the job from its board's search, as Rippling reports it | 100% (true on none of 915 sampled) |
| `eeoQuestionnaire`, `aiEvaluationsEnabled` | whether the job's application asks the EEO questionnaire, and the job's AI evaluations setting as Rippling reports it (`hasAIEvaluationsEnabled`) | 100% (true on 71% and 22 to 29%) |
| `boardTitle`, `boardTagline`, `boardLogoUrl`, `boardUrl` | the board's title, tagline, logo and link | 100%, 34 to 41%, 95 to 97%, 100% |
| `language` | the job's language as the board lists it (en-US, en-GB, fr-CA, ...) | jobs read from a board list |
| `url`, `applyUrl` | the public job page and its application page | 100% |
| `source`, `input`, `monitorChange`, `scrapedAt` | how the job was reached (board, job link, directory, sample), what you typed, `new` for a monitor | always |

Example row (shortened, real data of 2026-10-11):

```json
{
  "type": "job",
  "jobId": "3d575c15-1516-477d-bb57-b9e33a49166f",
  "title": "Paraprofessional",
  "company": "AACA",
  "boardSlug": "aaca",
  "department": "Paraprofessional",
  "departmentPath": ["Special Education", "Paraprofessional"],
  "locations": [{ "name": "Lancaster, CA", "city": "Lancaster", "state": "California", "stateCode": "CA", "country": "United States", "countryCode": "US", "workplaceType": "ON_SITE" }],
  "employmentType": "HOURLY_FT",
  "employmentTypeName": "Hourly, full-time",
  "postedAt": "2026-10-03T03:09:23.399Z",
  "payRanges": [{ "location": "AACA Antelope Valley", "currency": "USD", "period": "HOUR", "min": 22, "max": 25, "isRemote": false }],
  "payMin": 22, "payMax": 25, "payCurrency": "USD", "payPeriod": "HOUR",
  "descriptionText": "AACA is a Nonpublic School (NPS) serving students ages 5 to 22 ...",
  "applicationQuestions": [{ "question": "Do you have your High School Diploma or GED?", "type": "SINGLE_SELECT_RADIO", "required": true }],
  "url": "https://ats.rippling.com/aaca/jobs/3d575c15-1516-477d-bb57-b9e33a49166f",
  "applyUrl": "https://ats.rippling.com/aaca/jobs/3d575c15-1516-477d-bb57-b9e33a49166f/apply"
}
```

Every run also writes free rows: `status` rows (an unknown or empty board, a closed job, a job outside your filters, a stop),
`closedJob` rows for a monitor, and one `summary` row at the end with the counters of the run (boards read, jobs listed,
jobs filtered, details read, requests). The board logo link is signed by Rippling and stops working after about a day.

### How much does it cost to scrape Rippling jobs?

You pay per job delivered, plus a small fee per run. Prices on the Apify plans:

| Event | Free | Bronze | Silver | Gold |
|---|---|---|---|---|
| Job (per 1,000 jobs) | $0.90 | $0.90 | $0.70 | $0.45 |
| Actor start (per run) | $0.007 | $0.007 | $0.007 | $0.007 |

Platinum and Diamond plans pay the Gold price. The Actor start fee is the same on every plan. The Store pricing card shows
the job price per 1,000 jobs: "$0.90 / 1,000" on the Job row means one job costs 0.09 cents.

Examples: one board with 10 open jobs costs $0.007 + 10 x $0.0009 = $0.016 on Free or Bronze; 1,000 jobs on Gold cost
$0.007 + $0.45 = $0.457. A job is charged once per run (and once per monitor), however many locations it has. Unknown boards,
empty boards, closed jobs, jobs outside your filters and all status, closed job and summary rows are free. You can cap any run
with the maximum charge setting of the Apify Console or API.

### Input

| Field | What it does |
|---|---|
| `boards` | Rippling job boards: names (`carbon-health`) or links (`https://ats.rippling.com/carbon-health/jobs`, locale and embed links work too). Every open job of each board is read, in the order given. |
| `jobUrls` | Single job links (`https://ats.rippling.com/<board>/jobs/<job id>`). |
| `searchAllBoards` | Read every board of the built in directory (2,189 boards that answered on 2026-10-11), largest first, after the boards above. |
| `titleKeywords`, `excludeTitleKeywords` | Keep, or leave out, jobs whose title holds these words (whole words, any case). |
| `departments` | Keep jobs whose department holds these words (the job's own department, as the board names it). |
| `countries` | Keep jobs with a location in these countries (two letter codes: US, GB, DE, IN). |
| `workplaceTypes` | ON_SITE, HYBRID, REMOTE. |
| `employmentTypes` | SALARIED_FT, SALARIED_PT, HOURLY_FT, HOURLY_PT, CONTRACTOR, TEMP. About 7% of jobs carry only the company's own wording (for example Intern) and never pass this filter. |
| `descriptionKeywords` | Keep jobs whose title or description holds these words. |
| `postedWithinDays` | Keep jobs created on Rippling within this many days before the run started. |
| `onlyWithPay` | Keep only jobs that show a pay range. |
| `maxJobs`, `maxJobsPerBoard` | Caps on delivered jobs, per run (default 100; 10 for the sample run) and per board. |
| `monitorName`, `reportClosedJobs` | A monitor: see below. |

With no board, no job link and no directory search, the Actor reads the sample board `rippling` (10 jobs). The title,
department, country and workplace filters are judged on the board's list and cost no extra request; the description,
employment type, posting date and pay filters need each job's detail first.

#### Searching every Rippling board

Rippling publishes no list of its job boards, so this Actor carries its own directory: every board that answered Rippling's
job board API on 2026-10-11 among 2,583 board names found in public web archives (1,703 boards with open jobs that day, 486
without; 17,866 jobs). The directory is read largest board first. A search that keeps finding jobs reads every board; a
search that finds nothing stops after about 900 boards (the largest, holding about 90% of all listed jobs), with a free row
saying how many boards were read: each run may do 900 units of work that delivers no paid job (one per board read, two per
job detail that fails your filters or is closed) plus 40 per job delivered. A board created after 2026-10-11 is read only when
you list it in `boards`.

#### Monitoring companies for new and closed jobs

Give a **Monitor name** and run the same input on a schedule. The monitor remembers every job it delivered (per listing and
per Apify account): the next run reads only jobs it has not delivered, so you pay once per job. A job it knows is never read
or charged again, even if it closes and comes back. With **Report closed jobs** (on by default with a monitor), a job the
monitor delivered that its board no longer lists gets a free `closedJob` row, once, for boards read completely in the run.
Two runs on one monitor name at the same time: the later one is refused with a free row, so schedule runs that do not overlap.

### What this Actor does NOT do

- It reads Rippling job boards only, not other hiring systems.
- It does not search a continuously refreshed index: the directory is a snapshot of 2,189 boards of 2026-10-11, and every
  board is read live when the run reaches it. A board created later is read only when you name it.
- It does not add derived fields (experience level, skills, visa sponsorship, salary converted to one currency): every value
  is what the employer's Rippling board states.
- It does not add company data from other sources (company size, LinkedIn pages).
- It gives Rippling's creation date of a job and no updated date or expiry date: Rippling's board shows none.
- It does not read a company's own careers site; give the company's Rippling board name or link.
- It does not apply to jobs or read anything behind a login.
- A restarted run (a platform migration) delivers what it had delivered before the restart and nothing more; run it again
  for the rest, or use a monitor so a new run delivers only what is new.

### Use it through the API

```bash
curl -X POST "https://api.apify.com/v2/acts/automation_craft~rippling-jobs-scraper/run-sync-get-dataset-items?token=<YOUR_TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{"boards": ["rippling", "carbon-health"], "countries": ["US"], "maxJobs": 50}'
```

```javascript
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('automation_craft/rippling-jobs-scraper').call({ searchAllBoards: true, titleKeywords: ['data engineer'], maxJobs: 200 });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.filter((i) => i.type === 'job').length);
```

```python
from apify_client import ApifyClient
client = ApifyClient("<YOUR_TOKEN>")
run = client.actor("automation_craft/rippling-jobs-scraper").call(run_input={"boards": ["rippling"], "monitorName": "weekly rippling"})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["type"] == "job":
        print(item["title"], item["locationNames"], item["payMin"], item["payMax"])
```

### FAQ

#### Does Rippling have a public job board API?

Rippling's job board pages load their jobs from a public JSON API at api.rippling.com, which answers without a key or a
login. This Actor reads that API: one call for a board's list of jobs, one call per job for its full detail.

#### How do I scrape jobs from a Rippling careers page?

Copy the board's link (it looks like `https://ats.rippling.com/<company>/jobs`) or just the company part into **Job boards**
and start the run. Every open job of the board comes back as one row, with its description, locations and pay when shown.

#### How do I find companies that use Rippling for hiring?

Tick **Search every board in the directory**: the Actor reads the 2,189 Rippling job boards it knows, and every delivered row
carries the company, the board name and the board link. Add filters (country, title, department) to keep the companies that
hire for what you sell or recruit for.

#### Does it return salaries?

Yes, when the employer shows pay on Rippling: about 23% of jobs carry pay ranges, with currency, period (hour, month, year),
minimum and maximum, per location. Use **Only jobs that show pay** to keep only those.

#### Why does this Actor run with limited permissions?

It needs nothing but its own storage: it writes its results to the run's dataset, and a monitor keeps its memory in a named
key-value store the Actor creates in your account. Limited permissions keep it away from everything else in your account.

### Changelog

- 0.1 (2026-10-11): first version. Boards, job links, directory search, list and detail filters, monitor with closed jobs,
  free status rows.

### More data tools by Automation Craft

- [ATS Jobs Scraper & API - Greenhouse, Lever, Ashby](https://apify.com/automation_craft/ats-jobs-scraper)
- [Greenhouse Jobs Scraper & API - Pay Once Per Job](https://apify.com/automation_craft/greenhouse-jobs-scraper)
- [Lever Jobs Scraper & API - Pay Once Per Job](https://apify.com/automation_craft/lever-jobs-scraper)
- [Ashby Jobs Scraper & API - Pay Ranges Included](https://apify.com/automation_craft/ashby-jobs-scraper)
- [Workable Jobs Scraper & API - Any Careers Page](https://apify.com/automation_craft/workable-jobs-scraper)
- [SmartRecruiters Jobs Scraper & API - Every Role](https://apify.com/automation_craft/smartrecruiters-jobs-scraper)
- [Workday Jobs Scraper & API - Whole Career Site](https://apify.com/automation_craft/workday-jobs-scraper)
- [LinkedIn Company Scraper - Details, No Login](https://apify.com/automation_craft/linkedin-company-scraper)
- [SEC Form D Scraper: Offerings & Funding Leads](https://apify.com/automation_craft/sec-form-d-scraper)

# Changelog

This Actor's version history is a separate document: https://apify.com/automation_craft/rippling-jobs-scraper/changelog.md

# Actor input Schema

## `boards` (type: `array`):

Rippling job boards to read, one per line: the board name (the part after ats.rippling.com/ in the board's link, for example rippling or carbon-health) or the board's link (https://ats.rippling.com/rippling/jobs). Every open job of each board is read, in the order given. A board that does not exist gets a free status row. Leave empty when you use job links or the directory search only.

## `jobUrls` (type: `array`):

Single Rippling jobs to read, one link per line (https://ats.rippling.com/<board>/jobs/<job id>). A job that is closed or does not exist gets a free status row.

## `searchAllBoards` (type: `boolean`):

Read every Rippling job board of the directory built into this Actor, after the boards listed above. Use the filters below to keep what you need. The directory and its date are in the README; a board created after that date is read only when you list it.

## `titleKeywords` (type: `array`):

Keep jobs whose title contains at least one of these words or phrases, as whole words, in any case (engineer matches Senior Engineer, not Engineering). Letters, digits, spaces and . , & + # / ( ) ' - only. Leave empty to keep every title.

## `excludeTitleKeywords` (type: `array`):

Leave out jobs whose title contains any of these words or phrases, as whole words, in any case. Letters, digits, spaces and . , & + # / ( ) ' - only.

## `departments` (type: `array`):

Keep jobs whose department contains one of these words or phrases, as whole words, in any case, for example Engineering or Sales (the job's own department as the board names it). Letters, digits, spaces and . , & + # / ( ) ' - only.

## `countries` (type: `array`):

Keep jobs with at least one location in these countries, as two letter ISO codes (US, GB, DE, IN; the United Kingdom is GB). A location the board shows without a country never passes this filter.

## `workplaceTypes` (type: `array`):

Keep jobs with at least one location of these types.

## `employmentTypes` (type: `array`):

Keep jobs of these employment types, as Rippling codes them (read from the job's detail). About 7 percent of jobs carry only the company's own wording (for example Intern or Per Diem) and no code: they never pass this filter.

## `descriptionKeywords` (type: `array`):

Keep jobs whose title or description contains at least one of these words or phrases, as whole words, in any case (read from the job's detail). Letters, digits, spaces and . , & + # / ( ) ' - only.

## `postedWithinDays` (type: `integer`):

Keep jobs posted within this many days before the run started (Rippling's own creation date of the job, read from its detail). Leave empty for any date.

## `onlyWithPay` (type: `boolean`):

Keep only jobs whose detail carries at least one pay range.

## `maxJobs` (type: `integer`):

The run stops after delivering this many jobs. Without a value: 100 (10 for the sample board read when no board, job link or directory search is given).

## `maxJobsPerBoard` (type: `integer`):

At most this many jobs from one board. Leave empty for no per board limit.

## `monitorName` (type: `string`):

Give a name to deliver and charge only jobs this monitor has not delivered before (a memory kept between runs, per listing and per account). Use the same name on every scheduled run. Letters, digits, spaces and . \_ , - : # ( ) only.

## `reportClosedJobs` (type: `boolean`):

With a monitor: write a free row for every job the monitor delivered earlier that its board no longer lists (only for boards read completely in the run). On by default when a monitor name is given.

## Actor input object example

```json
{
  "boards": [
    "rippling"
  ],
  "maxJobs": 10
}
```

# Actor output Schema

## `items` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "boards": [
        "rippling"
    ],
    "maxJobs": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("automation_craft/rippling-jobs-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "boards": ["rippling"],
    "maxJobs": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("automation_craft/rippling-jobs-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "boards": [
    "rippling"
  ],
  "maxJobs": 10
}' |
apify call automation_craft/rippling-jobs-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,automation_craft/rippling-jobs-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/1RCIYEgCGAL95jvit/builds/SJtmWFkxoXloEeTe2/openapi.json
