Rippling — Integration Setup
Connecting Rippling gives CMDash your employee and contractor roster in one feed: who works here, when they joined, when they left, and who reports to whom. That roster is the evidence behind joiner/leaver controls, periodic access reviews, and the contractor population auditors ask about separately.
Prerequisites
- A Rippling account with API access
- Admin rights to create an API token in the Rippling admin console
- CMDash Essentials tier or above
Step 1: Create an API Token
- Log in to the Rippling admin console.
- Go to Settings → API Access (or Company Settings → API, depending on your plan).
- Create a token named
CMDash Integration. - Grant it read access to Workers only. Do not grant compensation, payroll, or benefits scopes — CMDash never requests them, and a token without them makes that guarantee enforceable by Rippling rather than by CMDash's code.
- Copy the token immediately — it is shown only once.
Step 2: Connect in CMDash
- Navigate to Integrations in your CMDash dashboard.
- Find Rippling and click Connect.
- Enter:
- API Token (stored as this connection's access token, sent as
Authorization: Bearer <token>) - Base URL (optional) — only if you are on a non-default Rippling API host. The default is
https://rest.ripplingapis.com.
- API Token (stored as this connection's access token, sent as
- Click Save & Test Connection.
What Syncs
| Data Type | Rippling API | Sync Frequency |
|---|---|---|
| Workforce roster (employees + contractors) | GET https://rest.ripplingapis.com/workers?limit=100 (cursor-paginated via next_link) | Every 4 hours by default (configurable per connection) |
Rippling keeps employees and contractors in the same /workers collection, separated by employment_type — unlike Gusto, which uses two endpoints — so one call covers both populations.
Each roster row is normalized to: external id, work email, display name, employment status, employment type, hire date, termination date, department, job title, and a manager reference. CMDash also derives a summary alongside the rows — headcount, active/terminated counts, contractor count, joiners and leavers in the last 30 days, and terminatedButActiveCount: workers whose end date has passed but whom Rippling still reports as ACTIVE.
Status mapping
Rippling reports a real, distinct leave state, so CMDash does not have to guess:
| Rippling | CMDash |
|---|---|
ACTIVE | active |
TERMINATED, INACTIVE | terminated |
ON_LEAVE, LEAVE | leave |
PENDING, HIRED, ACCEPTED | pending |
| anything else | unknown |
An unrecognized value stays unknown rather than being rounded to active — "this person is still employed" must never be inferred from silence.
What CMDash Deliberately Does Not Read
Rippling exposes personal and payroll data through expandable fields that are only returned when explicitly requested. CMDash requests none of them:
compensation— annual/hourly rate, pay period, equity. Never expanded.- National identifiers,
date_of_birth, gender, ethnicity, marital status. Never requested. personal_email,phone_number,home_address. Never read — onlywork_email, because it is the join key to your identity provider that makes offboarding evidence possible.- Benefits, dependants, and time-off balances. Endpoints never called.
If a future Rippling API version starts returning any of the above inline by default, CMDash discards it during normalization rather than storing it — the roster record is constructed field by field from a fixed list, never copied wholesale.
Turning the roster into a control
Create a continuous-compliance rule against the roster:
- Provider: Rippling
- Data type: Workforce
- Condition:
terminatedButActiveCount <= 0 - Target status: Implemented
The control reads as Implemented while every departed worker is correctly marked terminated in Rippling, and drifts to At Risk / Failing when one is not — with an auto-opened remediation task. Other useful fields on the same datum: headcount, activeCount, terminatedCount, contractorCount, joinersLast30d, leaversLast30d.
Training completion
Rippling's REST API exposes no learning/training collection, so training completion is not synced. Security-awareness training completion in CMDash comes from KnowBe4.
Troubleshooting
- 401 Unauthorized: The token was revoked or regenerated in the Rippling admin console.
- 403 Forbidden: The token lacks read access to Workers.
- Contractors are missing: Confirm your Rippling plan includes contractors in the
/workerscollection; some configurations keep them separate. - Department is blank: CMDash reads
departmentas either a bare string or a{ id, name }object. If Rippling returns only an id with no name, the field is left empty rather than showing a UUID. - Sync fails with "refusing to store a partial roster": Your roster exceeds 50,000 rows. CMDash fails rather than truncating, because a missing leaver reads as "no offboarding failure". Contact support.
Rate Limits & Sync Behavior
| Setting | Value |
|---|---|
| Sync frequency | Every 4 hours by default (syncInterval is configurable per connection) |
| Page size | 100 workers per request, walked by next_link until Rippling stops issuing one |
| Roster cap | 50,000 rows — exceeding it fails the sync rather than storing a partial roster |
| Rate limit handling | Requests are paced through CMDash's shared per-tenant token bucket |
| Circuit breaker | Repeated failures open the breaker and skip the cycle rather than hammering Rippling |
| Failed sync retry | Job queue retries 3 times with exponential backoff (starting at 30s) — see docs/developers/dead-letter.md |
CMDash follows Rippling's next_link pagination URL only when it is same-origin with your configured base URL. A link pointing anywhere else ends pagination rather than sending your API token to another host.
Credential Rotation
Rippling API tokens do not expire on a fixed schedule. Rotate quarterly.
- In Rippling: Settings → API Access, create a new token with the same Workers-read scope.
- In CMDash: Settings → Integrations → Rippling → Edit, enter the new token, Save.
- Revoke the old token in Rippling.