> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryrisotto.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Rippling

> Connect Rippling as your HRIS to power employee self-service

Connect Rippling as your HRIS so Risotto can answer employee HR questions directly in Slack instead of routing them to your People team. Once connected, an employee can ask for their PTO balance, submit a time off request, check their job details, or look up the home address on file.

In the dashboard, Rippling appears as a row under **Settings > People > Connect** with the description "Allows Risotto to manage HR operations like employee data and time off" and an **Install** button on the right.

## Why connect Rippling

<CardGroup cols={2}>
  <Card title="Deflect repetitive HR tickets" icon="ticket">
    "How much PTO do I have left?" and "can I take next Friday off?" are among
    the most common requests People teams receive. Risotto answers them from
    live Rippling data.
  </Card>

  <Card title="Keep your roster current" icon="users">
    Risotto syncs your employee roster from Rippling, so it knows who works
    there without you maintaining a separate user list.
  </Card>

  <Card title="Stop serving former employees" icon="user-slash">
    When someone is terminated in Rippling, Risotto stops acting on their
    requests.
  </Card>

  <Card title="No new surface for employees" icon="slack">
    Employees stay in Slack. They don't need to remember where Rippling lives or
    how to navigate it.
  </Card>
</CardGroup>

## Prerequisites

Have these in place before you start:

* **A Rippling admin account.** Only Rippling admins can install App Shop apps.
* **A Risotto admin account.** Installing, syncing, and disconnecting all require permission to manage the org.
* **Account provisioning configured for Risotto in Rippling.** Rippling's provisioning rules determine which employees are in scope for Risotto. These rules populate the `PROVISIONING` group that Risotto's roster sync reads; without it, the sync has nothing to reconcile and reports a failure.
* **The Rippling company is not connected to another Risotto org.** One Rippling company maps to exactly one Risotto org.

## Install from the Rippling App Shop

Risotto connects to Rippling through the Rippling App Shop. The App Shop handles authentication and Risotto persists OAuth tokens automatically.

<Steps>
  <Step title="Start the install">
    Find the Risotto app in the [Rippling App Shop](https://app.rippling.com/apps) and click **Install**, or start from the Risotto dashboard at **Settings → People → Connect** and click **Install** next to Rippling.
  </Step>

  <Step title="Approve the install in Rippling">
    Sign in to Rippling as an admin if prompted, then approve the requested
    permissions for the Risotto app. Rippling redirects you back to the Risotto
    dashboard once approval is complete.
  </Step>

  <Step title="Confirm the connection">
    Back in the Risotto dashboard, sign in if prompted and you'll land on
    **Settings → People → Connect**, where the install finishes automatically. The
    Rippling row updates to show the integration is connected and begins its first
    employee sync.
  </Step>

  <Step title="Enable the actions you want">
    Installing the integration does not by itself let Risotto do anything. Go to **Settings → People → Actions** and enable each [People Action](/dashboard/settings/people/actions) you want available. To let the agent look up the employee record, turn on **Agent access** on the **People** tab of [Support agent > Context](/dashboard/settings/support-agent/context). Every action is off until you turn it on.
  </Step>
</Steps>

<Note>
  Only Rippling admins can install App Shop apps. If the **Install** button
  redirects you to Rippling without an approval screen, ask an admin in your
  workspace to complete the install.
</Note>

<Warning>
  A Rippling company can only be connected to one Risotto org at a time. If the
  same Rippling company is already connected to another Risotto org, the install
  fails with "Please disconnect Rippling from your other Risotto org."
  Disconnect from the other org first, then retry the install.
</Warning>

## Requested Permissions

During install, Risotto requests access to the following Rippling data through the App Shop integration:

| Access | Purpose |
| - | - |
| Employee profile | Look up name, work email, job title, department, work location, and start date |
| Home address | Read the home address on file for the requesting employee |
| Leave balances | Read PTO policy types and balances for each plan the employee is assigned to |
| Leave requests | Read existing time off requests and submit new ones on the employee's behalf |
| Groups | Read the provisioning group that defines which employees are in scope |

<Note>
  Rippling negotiates the exact permission scopes through the App Shop
  integration during approval. Risotto reads only the fields it needs to fulfill
  an active request.
</Note>

## Data Flows

The integration runs four distinct flows. Two keep your roster current in the background; two run only when an employee asks for something.

| Flow | Direction | Trigger |
| - | - | - |
| Employee roster sync | Rippling → Risotto | On install, daily, or on demand |
| Provisioning webhooks | Rippling → Risotto | Rippling sends the event (\~5 minute delay) |
| Employee data lookup | Rippling → Risotto | An employee asks; read live, nothing stored |
| Time off request | Risotto → Rippling | An employee asks and confirms |

### Employee roster sync

Risotto reads the `PROVISIONING` group from Rippling and reconciles its own roster against it. Employees in the group are added or updated; Rippling-sourced identities no longer in the group are marked inactive with an audit entry.

This flow runs at three moments:

* **Once on install**, so a new connection is populated immediately.
* **Once a day**, in an overnight sweep (around 08:20 UTC).
* **On demand**, when an admin clicks **Sync now**.

The sync is idempotent. Re-running it with no upstream change writes nothing. It's also locked per org, so overlapping triggers collapse into the single run already in flight rather than stacking up.

<Note>
  The sync deliberately skips deactivating employees when the picture from
  Rippling looks incomplete such as an empty provisioning group, or a roster too large
  to read in one pass. A misconfigured group won't silently deactivate your
  whole company.
</Note>

### Provisioning webhooks

Rippling notifies Risotto of employee lifecycle changes as they happen, so terminations don't wait for the overnight sync:

| Event | Effect in Risotto |
| - | - |
| `employee.created` | Adds the employee to the roster |
| `employee.updated` | Refreshes the stored details for a tracked employee |
| `employee.terminated` | Marks the employee inactive; People Actions stop |
| `employee.deleted` | Marks the employee inactive; People Actions stop |
| `company.deleted` | Removes the connection and tears down the roster |

Webhooks are configured on the Risotto app itself, and your Rippling provisioning rules control which employees generate events.

<Note>
  Rippling delivers webhooks with a delay of roughly five minutes.
</Note>

### Employee data lookup

When an employee asks Risotto for their own HR data, Risotto calls Rippling live and reads only the fields that request needs.

To find the employee, Risotto matches their email against Rippling's `work_email`. The resolved Rippling worker ID is stored on the employee's Risotto identity so later requests skip the lookup.

### Time off request

The only flow that writes to Rippling. When an employee asks for time off, Risotto confirms the details with them first, then creates the request in Rippling with status `pending`, where it enters your normal approval flow. Risotto never approves anything.

### Trigger a sync manually

To force an immediate roster sync without waiting for the overnight run, go to **Settings → People → Connect**, open the menu on the Rippling row, and click **Sync now**.

The Rippling row reports the result inline:

| Status line | Meaning |
| - | - |
| `Employee sync in progress...` | A sync is running now |
| `Employees last synced <time>` | The last sync succeeded |
| `Last employee sync failed (<cause>)` | The last sync failed; the cause is in parentheses |

<Note>
  The other three flows can't be triggered by hand, and don't need to be.
  Webhooks are sent by Rippling, and employee lookups and time off requests only
  ever run in response to an employee asking.
</Note>

## Data Fields That Sync

Risotto resolves the requesting employee's Rippling worker record by matching their work email, then reads only the fields required to answer that request.

### Employee profile (read)

Pulled from the Rippling `workers` endpoint:

| Rippling field | Used for |
| - | - |
| `work_email` | Primary identifier matched against the requester's email |
| `personal_email` | Fallback key when a synced worker has no work email on file |
| `display_name` | Preferred display name in Risotto responses |
| `title` | Employee profile lookups |
| `department` | Employee profile lookups |
| `location` | Work location lookups |
| `start_date` | Start date lookups |
| `status` | Detecting terminated workers |
| `user.number` | Rehire-stable employee number used to re-link a returning employee |

<Note>
  Live lookups match on `work_email` only. `personal_email` is used as a
  fallback when the roster sync encounters a worker with no work email — so an
  employee whose Slack email matches neither field won't resolve.
</Note>

### Home address (read only)

Read from the worker's `HOME`-typed address record:

| Rippling field | Used for |
| - | - |
| `street_address` | Street address lines |
| `locality` | City |
| `region` | State or province |
| `postal_code` | Postal / ZIP code |
| `country` | Country |

### Time off (read and write)

Rippling stores leave amounts in minutes; Risotto surfaces them in hours.

| Rippling endpoint | Used for |
| - | - |
| `leave-balances` | Current balance and policy type for each plan the employee is assigned to |
| `leave-requests` | Read recent and upcoming time off requests, and submit a new request with status `pending` |

<Note>
  Unlimited PTO policies don't track a running balance, so Risotto surfaces
  those as unlimited rather than a literal number.
</Note>

## Supported Actions

Rippling supports the following [People Actions](/dashboard/settings/people/actions):

<CardGroup cols={2}>
  <Card title="Get Employee Info" icon="id-card">
    Look up the requesting employee's profile, title, department, work location,
    and start date. Turn it on in [Support agent >
    Context](/dashboard/settings/support-agent/context).
  </Card>

  <Card title="Get Home Address" icon="house">
    View the home address on file for the requesting employee.
  </Card>

  <Card title="Get PTO Balance" icon="calendar-check">
    Retrieve balances for each policy type the employee is assigned to.
  </Card>

  <Card title="Request PTO" icon="calendar-plus">
    Submit a time off request for the requesting employee. Requests are created
    with status `pending` and follow your Rippling approval flow.
  </Card>
</CardGroup>

<Warning>
  **Update Home Address** is not supported for Rippling. The Rippling API does
  not expose address writes, so employee addresses can only be edited in
  Rippling by the employee or an HR admin.
</Warning>

## Terminated employees and rehires

When Rippling marks an employee as terminated or deleted, Risotto receives a webhook and immediately stops [People Actions](/dashboard/settings/people/actions) from running for that employee. Requests from former employees are escalated, even if their Slack account is still active. The daily roster sync catches anyone a missed webhook left behind.

Rehires are handled automatically. Rippling issues a new worker ID when someone returns, so Risotto re-resolves them on their next request or on the next roster sync and reactivates their record.

## Disconnecting

Rippling stays installed on your org until an admin removes it in Rippling. To start, click **Connected** on the Rippling row, then click **Disconnect...**. In the **Disconnect from Rippling?** dialog, click **Continue to Rippling** to uninstall Risotto in the Rippling App Shop.

Uninstalling in Rippling triggers a `company.deleted` webhook, and Risotto then deletes its stored access and refresh tokens and marks every Rippling-sourced employee record inactive.

<Warning>
  Removing the app only in the Risotto dashboard is not enough. Until it's
  uninstalled in Rippling, the connection remains live on Rippling's side.
</Warning>

## FAQs

<AccordionGroup>
  <Accordion title="Can employees look up other people's information?">
    No. Every People Action is scoped to the person making the request. An
    employee can retrieve their own PTO balance or home address, but cannot ask
    Risotto for a colleague's. There is no manager or admin lookup path through
    this integration.
  </Accordion>

  <Accordion title="Can a new hire in Rippling open a ticket in Risotto?">
    Not by itself. A Rippling event updates the roster, but it does not create a
    ticket or start an automation. The Rippling events in the automation trigger
    picker are marked **Soon** and do not run today. To open a ticket for each new
    hire now, create an automation with a [Webhook
    trigger](/dashboard/automations#webhook-trigger). Then call its URL from a
    step in your Rippling onboarding workflow, and let the automation create the
    ticket.
  </Accordion>

  <Accordion title="Can Risotto approve time off, or change anything else in Rippling?">
    No. The only write this integration performs is creating a time off request
    with status `pending`, which then follows your existing Rippling approval
    flow. Risotto cannot approve requests, edit profiles, change addresses, or
    modify payroll.
  </Accordion>

  <Accordion title="Does the employee get asked before Risotto submits a PTO request?">
    Yes. Submitting time off requires an explicit confirmation from the employee
    that is separate from their original message, so a casual mention of time
    off never creates a request on its own.
  </Accordion>

  <Accordion title="Should we enable Get Home Address?">
    That's a judgment call about PII. The action only ever returns the requesting
    employee's own address, and it's read-only. It does mean home addresses
    flow through your ticket source and any external ticket sync. If your policy
    restricts where address data may appear, leave it disabled. Every action is
    independently toggleable, so you can enable PTO features without it.
  </Accordion>

  <Accordion title="How fresh is the data Risotto reports?">
    PTO balances, job details, and addresses are read live from Rippling at the
    moment of the request.
  </Accordion>

  <Accordion title="How long after a termination does Risotto stop responding?">
    Rippling sends the termination webhook with a delay of roughly five minutes.
    For an immediate cutoff, click **Sync now**.
  </Accordion>

  <Accordion title="Can we connect Rippling to more than one Risotto org?">
    No. A Rippling company maps to exactly one Risotto org, so that webhooks
    route unambiguously. To move the connection, disconnect from the first org
    before installing in the second.
  </Accordion>

  <Accordion title="What about contractors and international workers?">
    Scope is set by your Rippling provisioning rules, not by worker type. Anyone
    those rules place in the provisioning group is in scope; anyone they exclude
    is not. If contractors should be able to self-serve, confirm your Rippling
    provisioning rules include them.
  </Accordion>

  <Accordion title="Are half-days and part-time schedules supported?">
    Yes. Risotto sends the hours per day with the request when they differ from
    a standard eight-hour day, so part-day requests and part-time schedules are
    submitted correctly.
  </Accordion>

  <Accordion title="Is there an audit trail?">
    Yes. Risotto records org events for manual sync triggers, employee
    provisioning and deactivation, and the app uninstall.
  </Accordion>
</AccordionGroup>

## Troubleshooting

<AccordionGroup>
  <Accordion title="Install fails: “Please disconnect Rippling from your other Risotto org”">
    This Rippling company is already connected to a different Risotto org.
    Disconnect it there first, then retry.
  </Accordion>

  <Accordion title="Install fails: “The Rippling install session expired”">
    The install is time-limited, and a slow sign-in during the handoff can let
    it lapse. Retry the install from the Risotto app page in Rippling.
  </Accordion>

  <Accordion title="Install fails: “Could not complete the Rippling install”">
    Rippling rejected the credential exchange. Retry the install. If it keeps
    failing, confirm you're signed in as a Rippling admin and contact Risotto
    support.
  </Accordion>

  <Accordion title="Sync failed: no PROVISIONING supergroup found in Rippling">
    Rippling has no provisioning group for Risotto to read, which almost always
    means account provisioning hasn't been configured for the Risotto app yet.
    Set up provisioning rules in Rippling, then click **Sync now**.
  </Accordion>

  <Accordion title="Sync failed: Rippling connection needs to be reconnected">
    Risotto's stored credentials can no longer be refreshed and Rippling data is
    unavailable until an admin reconnects. Risotto notifies org admins when this
    happens. Reinstall from **Settings → People → Connect**; syncing is blocked
    until you do.
  </Accordion>

  <Accordion title="Sync failed: Rippling API request failed, or timed out">
    A transient Rippling API problem — a rate limit, a temporary outage, or a
    roster large enough to exceed the time limit. The next daily sync retries
    automatically; **Sync now** retries immediately.
  </Accordion>

  <Accordion title="An employee is told they aren't found in the HR system">
    Risotto couldn't match them to a Rippling worker. Check, in order:

    1. Their Slack email matches their Rippling `work_email`.
    2. Rippling's provisioning rules include them, so they're in the group Risotto reads.
    3. They aren't marked terminated in Rippling.
    4. A roster sync has run since they were added — click **Sync now**.
  </Accordion>

  <Accordion title="Risotto isn't taking any HR actions at all">
    Confirm the actions are actually enabled. Installing the integration does
    not enable anything on its own — each action must be turned on under
    **Settings → People → Actions**.
  </Accordion>

  <Accordion title="An employee's PTO request was rejected by Rippling">
    Rippling validates requests against its own rules such as insufficient balance,
    blackout dates, policy restrictions, or overlapping requests. Risotto relays
    the reason Rippling gives. The employee can submit in Rippling directly if
    the rule needs an exception.
  </Accordion>
</AccordionGroup>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.