# Rippling Jobs Monitor & Scraper (`cliqtomedia/rippling-jobs-monitor-scraper`) Actor

Collect jobs from public Rippling boards with dates, pay and optional descriptions. Track new, changed and closed listings. Export jobs and read clear scan status.

- **URL**: https://apify.com/cliqtomedia/rippling-jobs-monitor-scraper.md
- **Developed by:** [Cliqto Media](https://apify.com/cliqtomedia) (community)
- **Stats:** 2 total users, 1 monthly users, 83.3% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 saved job rows

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

Read public Rippling job boards and build a clear record of hiring activity. This Actor returns job titles, locations, dates, pay ranges and optional full descriptions. It can also save new, changed and closed listings from repeat scans.

Start with `{"boards":["utility"]}`. A run costs **$0.035 plus $0.0016 per saved job row**. The start fee also applies when there are no matching jobs or no changes. A stopped scan is marked `partial`.

![Public Rippling jobs and listing changes](https://api.apify.com/v2/key-value-stores/sBXw1jOxVSCQYep1Y/records/hero.png)

### Table of contents

- [What it does](#what-it-does)
- [Data you get](#data-you-get)
- [Quick start](#quick-start)
- [Input fields](#input-fields)
- [Input examples](#input-examples)
- [Output example](#output-example)
- [Output fields](#output-fields)
- [Price and examples](#price-and-examples)
- [Use cases](#use-cases)
- [Schedules and monitoring](#schedules-and-monitoring)
- [API, MCP and integrations](#api-mcp-and-integrations)
- [Limits and partial results](#limits-and-partial-results)
- [Troubleshooting](#troubleshooting)
- [FAQ](#faq)
- [Related Actors](#related-actors)
- [Support](#support)

### What it does

Add Rippling board names or links. The Actor reads each public board, joins rows for the same job and applies your filters. It reads one detail record for each current job it saves. This gives the company name, posting date, stated pay and employment type.

The Actor uses public HTTP data. You do not need a Rippling login, API key or proxy. It reads company job postings. It does not read private recruiting data or send job applications.

In monitor mode, it compares the title, department and all listing locations with the last complete scan. A change only to pay or description is not detected. See [Schedules and monitoring](#schedules-and-monitoring).

### Data you get

| Data | Example | When it can be empty |
| --- | --- | --- |
| Job title and apply link | Director of AI | Required for each saved current job |
| Company | UTILITY | Board name is used if details cannot be read |
| All locations | Remote (United States) | The board may give no location |
| Work arrangement | hybrid | Source may omit the type; several types give `mixed` |
| Posting date | 2025-08-28T14:44:37.790Z | Missing or failed detail record |
| Stated pay | USD, yearly minimum and maximum | Company gives no pay |
| Full description | Plain text of company and role sections | Off by default |
| Listing change | NEW, UPDATED, EXPIRED | Monitor mode is off |
| Scan and row status | complete, partial | Always read the summary for board errors |

Unknown data stays `null`. Dates are not guessed. Text descriptions remove email addresses, phone numbers and personal profile URLs. The Actor returns no contact fields. All locations are sorted, so the first location can differ from the order on the company's page.

### Quick start

1. Open **Input**. The form has `utility` in **Rippling job boards** as a prefill.
2. Keep **Maximum saved jobs** at `100`. Leave monitor mode off for your first run.
3. Use `256 MB` memory and a timeout of `180 seconds`. Set a maximum charge such as `$0.30`.
4. Click **Start**.
5. Open **Output → Jobs**. Check `title`, `company.name`, `postedAt` and `url`.
6. Open **Scan summary**. Check `status`, `rowCount` and the board statuses.

The checked Utility board returned 10 unique jobs. Live jobs can change. To use another company, follow an apply link on its careers page. In `https://ats.rippling.com/utility/jobs`, the board name is `utility`.

### Input fields

`boards` is required. An empty object fails before any source request. The form prefill is a starting example, not a runtime default. Unknown input keys are rejected.

| Key | Type | Default | Allowed values | Effect | Recommendation |
| --- | --- | --- | --- | --- | --- |
| `boards` | string\[] | Required; form prefill `["utility"]` | 1–10 entries; board name up to 100 characters, or HTTPS ats.rippling.com link up to 250 characters | Selects company boards. Exact duplicate boards are read once. Names keep their case. | Copy the name from a real apply link. |
| `keywords` | string\[] | `[]` | Up to 20 phrases, 1–100 characters each | Title contains all words of any one phrase, in any order, without case matching. | Use `"backend engineer"`, not a whole job description. |
| `locations` | string\[] | `[]` | Up to 20 texts, 1–100 characters each | Any location name, city, state, country, country code or workplace type contains the text. | Use `"US"`, `"London"` or `"Remote"`; type is based on source fields. |
| `departments` | string\[] | `[]` | Up to 20 texts, 1–100 characters each | Top-level department contains any text. | Copy a board department, such as `"Engineering"`. |
| `maxResults` | integer | `100` | 1–300 | Limits all saved rows, including expired rows. | Choose enough room for a whole monitor scan. |
| `includeDescription` | boolean | `false` | true / false | Adds plain description text. It adds no detail requests: each saved current job already needs one. | Turn on when you need the text. |
| `incremental` | boolean | `false` | true / false | Saves listing changes and remembers complete scans. | Turn on for repeat monitoring. |
| `stateKey` | string | `""` | 0–60 letters, numbers, `_` or `-` | Names monitor memory. Empty derives a name from boards and filters. | Use a new name when you change boards or filters. |
| `emitExpired` | boolean | `true` | true / false | In monitor mode, saves rows for jobs missing from a complete scan. | Keep on for closure alerts. |
| `emitUnchanged` | boolean | `false` | true / false | In monitor mode, also saves and charges for unchanged jobs. | Keep off for a change-only feed. |
| `maxRequests` | integer | `320` | 1–320 | Limits source attempts, including list pages, details and retries. | Keep the default for full boards. |
| `maxSeconds` | integer | `120` | 10–120 | Limits source work time. The Actor then saves its summary. | Keep the Actor timeout longer than this value. |

Filters within one array use **OR**. `keywords`, `locations` and `departments` use **AND** with each other. Empty filter arrays keep all jobs.

A link with a locale, such as `/en-US/utility/jobs`, is accepted. A link to one posting reads the whole board. URLs must have the exact HTTPS host `ats.rippling.com` and no credentials, port, query or fragment. Remove tracking text such as `?utm_source=...` first. Company domains such as `utility.agency` are not board names.

A small `maxResults` can reduce detail requests. Filters still require reading complete board lists, even when no title matches. A scan with more matches than the result cap is `partial` and does not update monitor memory.

### Input examples

#### Read one board with descriptions

```json
{"boards":["utility"],"maxResults":100,"includeDescription":true}
```

The checked run returned 10 jobs. Each had a company name, posting date and description. Pay can be null.

#### Read selected roles

```json
{"boards":["rippling"],"keywords":["Business Operations"],"maxResults":100}
```

The checked run returned two roles. A title filter can return zero rows after a full list scan. The start fee still applies.

#### Watch listing changes

```json
{"boards":["utility"],"maxResults":100,"incremental":true,"stateKey":"utility-watch"}
```

The first complete run saves each job as `NEW`. A repeat scan with no listing changes returns zero rows. Both runs have a start fee.

### Output example

This is a real row from the checked Utility run, with descriptions off.

```json
{
  "schemaVersion": "job.v1",
  "id": "rippling:global:71035fd3-bff0-4450-b213-281637a07e6c",
  "source": "rippling",
  "market": "global",
  "sourceJobId": "71035fd3-bff0-4450-b213-281637a07e6c",
  "url": "https://ats.rippling.com/utility/jobs/71035fd3-bff0-4450-b213-281637a07e6c",
  "title": "Director of AI",
  "company": {
    "name": "UTILITY",
    "sourceCompanyId": "utility",
    "url": "https://ats.rippling.com/utility/jobs"
  },
  "advertiser": {
    "name": "UTILITY",
    "sourceAdvertiserId": "utility"
  },
  "location": {
    "raw": "Remote (United States)",
    "suburb": null,
    "city": "New York",
    "region": "New York",
    "postcode": null,
    "country": "US"
  },
  "locations": [
    {
      "name": "Remote (United States)",
      "city": "New York",
      "state": "New York",
      "country": "United States",
      "countryCode": "US",
      "workplaceType": "HYBRID"
    }
  ],
  "workArrangement": "hybrid",
  "employmentTypes": [
    "full_time"
  ],
  "salary": {
    "raw": null,
    "min": null,
    "max": null,
    "currency": null,
    "period": null,
    "includesSuper": null
  },
  "classifications": [
    {
      "category": "Engineering",
      "subcategory": null
    }
  ],
  "teaser": null,
  "bulletPoints": [],
  "postedAt": "2025-08-28T14:44:37.790Z",
  "updatedAt": null,
  "expiresAt": null,
  "isPromoted": false,
  "description": null,
  "changeType": null,
  "firstSeenAt": null,
  "contentHash": "18bcb2c8eb4159484287e81d13d8a07d468c3faa35747f9411f647fa7e539c9d",
  "scrapedAt": "2026-10-04T05:12:02.460Z",
  "boardSlug": "utility",
  "status": "complete",
  "errors": []
}
```

### Output fields

Each saved job has every top-level key below. Extra locations are kept in `locations`.

| Field | Type / can be null | Example | Meaning |
| --- | --- | --- | --- |
| `schemaVersion` | string; no | job.v1 | Core job field version |
| `id` | string; no | rippling:global:71035fd3-bff0-4450-b213-281637a07e6c | Stable Rippling job key |
| `source` | string; no | rippling | Data source |
| `market` | string; no | global | Company board scope |
| `sourceJobId` | string; no | 71035fd3-bff0-4450-b213-281637a07e6c | Rippling UUID |
| `url` | string; no | https://ats.rippling.com/utility/jobs/71035fd3-bff0-4450-b213-281637a07e6c | Canonical posting / apply page |
| `title` | string; no | Director of AI | Trimmed job title |
| `company.name` | string; no | UTILITY | Detail company name; board name if unavailable |
| `company.sourceCompanyId` | string; no | utility | Board name |
| `company.url` | string; no | https://ats.rippling.com/utility/jobs | Public company board |
| `advertiser.name` | string; no | UTILITY | Same company name |
| `advertiser.sourceAdvertiserId` | string; no | utility | Same board name |
| `location.raw` | string or null | Remote (United States) | All stated location names, joined with a vertical bar |
| `location.city` | string or null | New York | City in the first sorted location |
| `location.region` | string or null | New York | State or region in that location |
| `location.country` | string or null | US | Source country code |
| `location.suburb`, `location.postcode` | string or null; currently null | null | Not supplied by this route |
| `locations` | object\[]; no | `[{"name":"Remote","countryCode":"US"}]` | All distinct source locations; each includes `name`, `city`, `state`, `country`, `countryCode`, `workplaceType`, each string or null |
| `workArrangement` | string or null | hybrid | remote, hybrid, on_site, mixed, or null; source type, not a guess from title |
| `employmentTypes` | string\[]; no | `["full_time"]` | Known full_time, part_time, contract, internship or temporary types; unknown gives `[]` |
| `salary.raw` | string or null | 170,000 - 250,000 USD per year (US) | Stated ranges in all currencies |
| `salary.min`, `salary.max` | number or null | 170000, 250000 | Bounds for the first location's currency, or first pay range if no match; currencies are not mixed |
| `salary.currency`, `salary.period` | string or null | USD, year | Currency as stated; source frequency in lower case |
| `salary.includesSuper` | boolean or null; currently null | null | Not supplied |
| `classifications` | object\[]; no | `[{"category":"Engineering","subcategory":null}]` | Top-level department; `category` is string, `subcategory` is string or null |
| `teaser` | string or null; currently null | null | Not supplied |
| `bulletPoints` | string\[]; no | `[]` | Separate bullet field is not extracted |
| `postedAt` | UTC date string or null | 2025-08-28T14:44:37.790Z | Posting creation date in Rippling |
| `updatedAt`, `expiresAt` | date string or null; currently null | null | No source update/expiry date is returned |
| `isPromoted` | boolean; no | false | No promotion field is extracted |
| `description` | object or null | null | Null when off or details unavailable; otherwise text, html and contactsRedacted keys |
| `description.text` | string; no when object exists | Join the Utility Team! | Plain company and role text, up to 40,000 characters; empty if source text is empty |
| `description.html` | string or null; always null | null | HTML is not returned |
| `description.contactsRedacted` | boolean; no | true | Contact redaction is always enabled |
| `changeType` | string or null | NEW | NEW, UPDATED, EXPIRED, REAPPEARED, UNCHANGED; null outside monitor mode |
| `firstSeenAt` | UTC date string or null | 2026-10-04T05:00:00Z | First monitor observation; stored after a complete scan; null outside monitor mode |
| `contentHash` | string; no | SHA-256 hex value | Hash of title, department and sorted locations |
| `scrapedAt` | UTC date string; no | 2026-10-04T05:00:00Z | Time this scan produced the row |
| `boardSlug` | string; no | utility | Board used for this row |
| `status` | string; no | complete | complete or partial for this row; not the whole run |
| `errors` | string\[]; no | `[]` | Safe error codes, such as DETAIL_NOT_FOUND or DESCRIPTION_TRUNCATED |

#### Dataset and key-value store

| Surface | Fields | Meaning |
| --- | --- | --- |
| Default Dataset | Job rows above | Current jobs and optional monitor change rows. Export JSON, CSV or Excel. |
| `OUTPUT` | status, rowCount, summaryRecord, datasetId | Links scan status to the Dataset and RUN_SUMMARY. Invalid input may omit datasetId. |
| `RUN_SUMMARY` | status, reason, rowCount, boards, uniqueJobs, matched, requests, retries, responseBytes, outputBytes, elapsedSeconds, limits, stateCommitted, changes, startedAt, finishedAt, sourceCommit, buildId, datasetId | Scan counters, bounds, board outcomes and release identity. An early runtime failure may have only status and reason. |
| `CHANGES` | Change type → count | Saved change rows by type; `{}` outside monitor mode or with no rows. |

`boards` in the summary has board, status, sourceRows, uniqueJobs, matched and errors. Counts are integers. `stateCommitted` is boolean. `limits` gives maxResults, maxRequests, maxSeconds and maxResponseBytes. Times are UTC strings; elapsedSeconds is a number. `reason` is null or a safe code. IDs and version fields are strings. Errors are arrays of codes, not source payloads.

### Price and examples

Pay per event: **$0.035 per run start + $0.0016 per saved Dataset row** ($1.60 per 1,000 rows). These are flat prices across plans. Platform usage is included in the event price for customers. A private run by the owner can show platform costs instead of a customer payment.

| Saved rows | Runs | Event price |
| --- | ---: | ---: |
| 0 | 1 | $0.035 |
| 1 | 1 | $0.0366 |
| 10 | 1 | $0.051 |
| 100 | 1 | $0.195 |
| 300 | 1 | $0.515 |
| 1,000 | At least 4 | $1.74 with exactly 4 starts |

The row limit is 300 per run. The 1,000-row example is a price calculation across separate boards or scopes. It is not a 1,000-row single-run capacity claim. Splitting one board by a result cap does not give pagination; repeat runs use the same stable order.

The start fee is paid with an empty board, filters with no matches or a monitor with no changes. A partial run charges for rows already saved. Error and cancelled runs may also have a start fee and saved-row fees. Rows that were not saved are not result events. No manual result charge is added on top of the Dataset event.

A maximum charge can stop output before your result cap. Use at least $0.035 to start and leave room for rows. For example, $0.04 leaves room for three rows. The Actor marks a charge stop `partial` and keeps prior monitor memory. Storage and charging are separate platform services; an interrupted write is not a guarantee of exactly-once delivery.

### Use cases

- Build a job feed from a known list of employers. Use `sourceJobId` and `boardSlug` to join rows across scans.
- Track company hiring activity. Read titles, departments, country codes and stated pay.
- Watch new roles and closed listings. Use incremental mode and act on `changeType`.
- Review role text. Turn on `includeDescription` and keep null values for missing facts.

### Schedules and monitoring

Choose `incremental:true` for repeat runs. Keep boards and filters fixed. An empty `stateKey` is derived from this scope. A named key with a different scope fails with STATE_SCOPE_OR_STORAGE_ERROR; use a new key instead.

| Change | Meaning |
| --- | --- |
| NEW | No previous record in this monitor |
| UPDATED | Title, department or listing locations changed |
| EXPIRED | Missing from a complete scan; saved once while its tombstone stays in memory |
| REAPPEARED | Returns after being marked expired |
| UNCHANGED | Same listing; saved only if emitUnchanged is true |

The first complete scan creates memory. Unchanged jobs need no detail request when `emitUnchanged:false`. Changes only to description, pay, employment type or posting date are not checked. A partial scan does not change memory and never reports expired jobs. Its saved rows can appear and be charged again when you retry.

Memory holds up to 300 entries and 1 MiB, including recent expired records. Old expired records may be dropped to make room; a later return then appears as NEW. Each row is at most 64 KiB and total saved output is at most 8 MiB. These bounds can make a scan partial before the result count limit.

Run one scan at a time for a monitor key. Overlapping runs, manual memory edits and migration/resurrection are not supported for change delivery. In Apify, you can set your own [schedule](https://docs.apify.com/platform/schedules). This Actor does not create one for you. Leave enough time between runs for the previous scan to finish.

### API, MCP and integrations

Use the [Apify JavaScript client](https://docs.apify.com/api/client/js/docs). Keep your token in an environment variable.

```js
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('cliqtomedia/rippling-jobs-monitor-scraper').call(
  { boards: ['utility'], maxResults: 100 },
  { build: 'latest', memory: 256, timeout: 180, maxTotalChargeUsd: 0.30 }
);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
const summary = await client.keyValueStore(run.defaultKeyValueStoreId).getRecord('RUN_SUMMARY');
console.log(items.length, summary?.value.status);
```

AI tools can call a published Actor through [Apify's MCP server](https://docs.apify.com/platform/integrations/mcp). Use the same input keys and spending cap. Access depends on your Apify account and the Actor's visibility.

Read Dataset rows through the API or connect your own Make, Zapier or n8n flow. Use the summary before acting on closed-job alerts. Export nested fields as JSON when you need all locations and pay details. This release checks the Apify API and storage surfaces; individual external integrations are not part of the acceptance test.

### Limits and partial results

The live acceptance scan read 10 boards and saved 300 unique jobs. The source had more matches, so the result was correctly marked partial. The highest live test with full descriptions is 10 jobs. Larger runs with descriptions can meet byte or time limits sooner. These are measured samples, not a promise of fixed time for every board.

Hard limits: 10 input entries, 300 saved rows, 320 source attempts, 120 seconds of source work, 12 MiB of response bodies, 64 KiB per row and 8 MiB total output. Lists have a separate limit of 20 pages and 20,000 location rows per board. A run uses at most five source requests per second. It retries 429 and server/network failures up to twice, with backoff and Retry-After. Requests time out after at most 15 seconds. Use 256 MB memory and an Actor timeout up to 240 seconds; larger settings fail before source work.

| Summary status | Meaning | What to do |
| --- | --- | --- |
| complete | Every requested board and needed detail completed; zero matches is valid | Use rows and change events |
| partial | A board/detail failed, a posting disappeared, or a count/time/byte/charge limit stopped output | Use saved rows, read reasons, retry with a smaller scope |
| not_found | Every board returned not found | Check spelling and case |
| error | No usable board, invalid input/state/runtime settings, or a storage failure | Read the summary; the Actor run fails |

A description can be trimmed at 40,000 characters; that row and scan are partial. Detail failure keeps listing fields in a partial row, with missing detail fields null. Board failures are listed in the summary, not sold as job rows. Public endpoint changes can require a parser update. The Actor is an independent tool, not endorsed by Rippling.

### Troubleshooting

| Symptom | Likely reason | Check and action |
| --- | --- | --- |
| Zero jobs, complete | Filters found no matches, board is empty, or monitor saw no changes | Check matched/uniqueJobs and CHANGES; try without filters |
| Zero jobs, not_found | Board name or case is wrong, or board closed | Copy a current apply link |
| partial | A cap or source problem | Read reason and boards/errors; reduce boards or raise a cap within its allowed range |
| STATE_SCOPE_OR_STORAGE_ERROR | Same monitor name with different boards/filters, or storage unavailable | Use a new stateKey for a new scope |
| RUNTIME_LIMITS | More than 256 MB memory or no finite positive timeout | Use 256 MB and 180 seconds |
| INVALID_INPUT | Unknown key, wrong type or out-of-range value | Use an example above and check the field table |
| Description is null | Setting off or details unavailable | Turn on includeDescription and read row errors |
| Date or salary is null | Source has no fact or detail failed | Keep null; check the public job page |

### FAQ

**Can I enter a company website?** Use its Rippling board name or ats.rippling.com link. This Actor does not discover boards from company domains.

**Are descriptions extra?** There is no extra description event or extra detail request. Large text still uses time and byte limits.

**Can I detect a pay-only edit?** No. Monitoring compares listing fields. To read current pay, run a normal scan.

**Is an unchanged monitor run free?** The start fee applies. No saved rows means no row events.

**Does partial mean the jobs are false?** Saved rows can still be useful. It means the whole requested scan did not finish. Check each row's status as well.

**Can I use the same monitor key in two schedules?** Run them at different times, with the same scope. Overlapping runs are not supported.

**What is the stable key?** `sourceJobId` is the UUID; use `boardSlug + ':' + sourceJobId` when joining several boards.

### Related Actors

- [Greenhouse Jobs Scraper & Monitor](https://apify.com/cliqtomedia/greenhouse-jobs-monitor-scraper)
- [Lever Job Scraper](https://apify.com/cliqtomedia/lever-jobs-scraper)
- [Ashby Jobs Scraper](https://apify.com/cliqtomedia/ashby-jobs-scraper)

### Support

Open the Actor's **Issues** tab. Include the run ID, the public board name and the result you expected. Do not send tokens, private recruiting data or candidate details.

# Actor input Schema

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

Add 1–10 board names or HTTPS ats.rippling.com links. A job link reads its whole board. Board names are case sensitive.

## `keywords` (type: `array`):

A title must contain all words in at least one phrase. Empty keeps all titles. Use up to 20 values of up to 100 characters.

## `locations` (type: `array`):

Match any location name, city, state, country, country code or workplace type. Empty keeps all places. Use up to 20 values of up to 100 characters.

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

Match part of a top-level department name. Empty keeps all departments. Use up to 20 values of up to 100 characters.

## `maxResults` (type: `integer`):

Save up to this many unique rows, including expired jobs. Lower caps give partial scans; partial scans do not update monitor memory.

## `includeDescription` (type: `boolean`):

Add the company and role text. Email, phone and personal profile text are redacted. Adds no requests: every emitted current job needs one detail request.

## `incremental` (type: `boolean`):

Save new, updated, reappeared and expired jobs. Unchanged listings need no detail request. Changes only to description or pay are not detected.

## `stateKey` (type: `string`):

Use letters, numbers, hyphens or underscores, up to 60 characters. Keep boards and filters fixed for this name. Empty derives a name from that scope.

## `emitExpired` (type: `boolean`):

In monitor mode, save jobs removed from a complete scan. Partial scans never report expired jobs.

## `emitUnchanged` (type: `boolean`):

In monitor mode, also save and charge for unchanged jobs. Leave off for alerts.

## `maxRequests` (type: `integer`):

Stop after this many source attempts, including retries. Full lists are read before filters and details. A stop gives partial.

## `maxSeconds` (type: `integer`):

Stop source work after this time. Allow a longer Actor timeout for saving the summary. A stop gives partial.

## Actor input object example

```json
{
  "boards": [
    "utility"
  ],
  "keywords": [],
  "locations": [],
  "departments": [],
  "maxResults": 100,
  "includeDescription": false,
  "incremental": false,
  "stateKey": "",
  "emitExpired": true,
  "emitUnchanged": false,
  "maxRequests": 320,
  "maxSeconds": 120
}
```

# Actor output Schema

## `jobs` (type: `string`):

No description

## `output` (type: `string`):

No description

## `summary` (type: `string`):

No description

## `changes` (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": [
        "utility"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cliqtomedia/rippling-jobs-monitor-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": ["utility"] }

# Run the Actor and wait for it to finish
run = client.actor("cliqtomedia/rippling-jobs-monitor-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": [
    "utility"
  ]
}' |
apify call cliqtomedia/rippling-jobs-monitor-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,cliqtomedia/rippling-jobs-monitor-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/tS5gG8kOSyEuAMoGo/builds/mSpIfvPMAMK1ZBepk/openapi.json
