Product that suits modern B2B Tech companies

Book Demo
B
Book demo call-to-action illustration
BACK
B

Rippling Webhooks vs. Polling: Why Change Detection Needs Both

Platform APIs
September 30, 2026
Summarise the blog with AI
Open in ChatGPT
Ask questions about this page
Open in Claude
Ask questions about this page

Key takeaways

  • Rippling's App Shop partner requirements call for a webhook listener and a scheduled sync at least every 24 hours, plus a manual sync button, not one mechanism instead of the other.
  • Rippling webhook events arrive with a roughly five-minute lag, and a single change can produce more than one event.
  • The REST API's updated_at filter lets you poll for only what changed since your last read, on endpoints like List workers that document the field.
  • Rippling's webhook guide says webhooks are only supported for App Shop partner apps; an integration running on a customer API token should plan on polling.
  • Each Rippling webhook is a form-encoded POST carrying only the event name and IDs, so treat it as a trigger to fetch, not as the record.
  • Rippling documents no retry, ordering or signature scheme; authenticated events carry a bearer token you supply.

Ask whether a Rippling integration should detect changes with webhooks or with polling, and the useful answer isn't a choice between them. Build around webhooks alone, and a missed or duplicated event has no way to correct itself. Build around polling alone, and you're re-reading employees who haven't changed, on a schedule that's still slower than the event you didn't catch.

Rippling's own partner requirements settle the question directly: partner integrations must run a webhook listener that updates your system as events arrive, and, separately, a scheduled sync that reads and updates all employee details at least every 24 hours (Rippling's Partner Requirements). The same list also asks for a manual sync button that re-reads every employee on demand. Webhooks tell you something changed. The sync is what proves your copy is right.

This guide covers what each mechanism is responsible for in Rippling's change-detection requirement, how they behave in practice (the latency, the duplicate events, the failure modes), how to poll Rippling for only what changed between full syncs, what Rippling's webhook events API actually exposes, and how the pieces fit into one pipeline.

Why Rippling asks for both

A webhook is a notification: Rippling posts an event to your listener when something in an employee's record changes, so you know where to look. A scheduled sync is a reconciliation: your integration re-reads the full list of employees your app has access to, from scratch, and checks that your stored copy matches. Rippling's own guidance frames the second one as a backstop: the full read "can run as a scheduled sync to ensure that no webhook events were missed" (Rippling's User Management Guide).

That framing does the real work: a webhook tells you when to look, and the sync tells you the truth. In Rippling's v1 partner guide, the reconciliation read is GET /employees, the same call you'd use once during onboarding, run on a schedule instead of one time only. V2 REST API partners get the same list another way: the v2 User Management guide reads the members of the app's PROVISIONING supergroup, then List workers for the details. Treat the webhook as the trigger and the sync as the source of truth, and the "why both" question mostly answers itself: one is fast and incomplete, the other is slow and authoritative.

What's less obvious is how differently the two behave once you're relying on them in production.

Webhooks vs the scheduled sync, side by side

Side by side, across the dimensions that decide a design, the two diverge sharply, starting with Rippling's ~5-minute lag on webhook delivery:

Dimension Webhook listener Scheduled sync
Trigger An event in Rippling, such as employee.updated or employee.terminated Runs on a schedule, independent of any single event
Latency Arrives roughly five minutes after the change, per Rippling's Webhooks Guide Only as fresh as the last completed run
Completeness Tells you something changed, but not that you've received every change reliably Reads every active record, so it catches anything a webhook missed
Duplicates Rippling says you can receive one event or several for the same change Not applicable; each run is an independent full read
If it's missed or fails The record silently drifts until the next scheduled sync catches it Your whole dataset is stale until the next run completes
Cadence Configured once, fires as events occur At least every 24 hours, and Rippling allows it to run more often

The pattern across every row is the same: the webhook is cheap and fast but can't be trusted alone, and the sync is expensive and slow but doesn't lie. Between those two extremes, though, there's a cheaper way to stay current than a full 24-hour read, which is where polling for only what changed comes in.

Polling Rippling for only what changed

The REST API's query parameters support filter, expand, and order_by, and filters accept date comparison operators such as updated_at ge 2026-09-01T00:00:00 (Rippling's REST API query-parameter docs). On endpoints that document updated_at as a filterable field, such as List workers, that means you can request only the records Rippling has touched since your last poll, instead of re-reading everyone:

Request
curl -G 'https://rest.ripplingapis.com/workers' \
  --data-urlencode "filter=updated_at ge 2026-09-01T00:00:00" \
  --data-urlencode "limit=100" \
  -H 'accept: application/json' \
  -H 'Authorization: Bearer '

Rippling requires the quotes and spaces in a filter to be URL-encoded, which --data-urlencode handles. Store the timestamp of each successful poll and use it as the next run's lower bound.

That filter has real limits worth knowing before you lean on it. It only works on endpoints that document the field, so you can't assume every object in Rippling's API supports it just because List workers does. It also only returns records the endpoint still returns to your token, so a record that drops out of your app's scope won't show up as an "update" you can catch this way.

Rippling requires partner integrations to support pagination on top of that filtering, since any real result set won't fit in one page (our guide to keyset pagination covers the pattern for paging through both full and delta reads). And every poll still spends API calls against a rate limit. Rippling's REST API allows 300 requests per IP address in a sliding 10-second window; go past it and Rippling returns 429s and rejects every request from that IP for ten seconds (Rippling's API limits).

None of this replaces the full sync, and it isn't meant to. An incremental poll is a way to stay fresher between reconciliations, not a substitute for one. What it does assume, though, is that you can even receive webhooks in the first place, which for a lot of Rippling integrations isn't a given.

Rippling's webhook events API: what's documented, and who gets access

Webhooks in Rippling's public docs are a feature of App Shop partner applications. All partner integrations are built through the Rippling App Shop, require the customer to have Rippling's Identity & Access Management package, and Rippling states plainly that it doesn't support partners integrating through third-party integration services (Rippling's Partner Requirements). The webhook guide itself is blunter: webhooks are only supported for App Shop app integrations, built by partners serving many Rippling customers. If your integration authenticates as a single customer through a customer-issued API token, plan your architecture around polling.

Rippling's Webhooks guide documents more than most engineers expect, and stops short in one place that matters:

Publicly documented Not in the public docs
Where to configure the Webhook URL Rippling posts events to Retry behavior when your listener is down or returns an error
The event list, including employee.created, employee.updated, employee.terminated, group.updated, company.deleted, 401_deductions.updated and three leave_request events Delivery ordering
The payload: a form-encoded POST with event_name, company_id, company_primary_email and id Any delivery guarantee beyond "one or multiple" events
That authenticated events carry a bearer token, with basic auth unsupported Any signature over the payload
A delivery lag of about five minutes

Two rows on the left shape the listener. Rippling supports both unauthenticated and authenticated events, and for authenticated ones it sends a bearer token you gave it up front in the Authorization header, with no signature over the body. And the payload is thin by design: an event name and IDs, no field values, so the listener always has to fetch the record to learn what changed. The right column is what happens when delivery fails, and Rippling's public guide doesn't say.

Once you know whether webhooks are reachable for your integration type, and that nothing documents a retry, the sync stops looking like a formality and starts looking like the part of the design you can rely on.

Building the combined pipeline

With the mechanisms, the polling option, and the access question settled, the pipeline itself is six steps:

  1. Register and secure the listener: configure the Webhook URL Rippling posts events to, and check incoming calls for the bearer token Rippling sends on authenticated events, since that token, not a signature, is the only verification Rippling's public docs describe.
  2. Treat every event as a trigger, not a record: use the webhook to decide what to go fetch, since the payload carries only the event name and IDs, never the changed values.
  3. Dedupe before you act: Rippling says you can receive one event or several for the same underlying change, so key incoming events on an identifier you control, and make reapplying the same update a no-op.
  4. Run an incremental poll between full syncs, if you need fresher data: filter endpoints like List workers on updated_at since your last successful poll, paginate through the results, and apply the same fetch-then-write handling as a webhook-triggered update.
  5. Run the full reconcile on Rippling's required cadence: read every employee your app has access to at least every 24 hours, more often if your product needs it, and put the same full read behind the manual sync button Rippling's requirements ask for. Treat this run as the one that's allowed to be authoritative.
  6. Diff and correct: compare the full-reconcile read against what you've stored, apply corrections for anything the webhook and the poll both missed, and log the discrepancy so you know how often your faster paths are actually catching things.

Step one is worth a caveat: a bearer-token check is authentication, not payload verification, and it's a different security model from platforms that sign each webhook body. If you're used to verifying a signature, our guide to HMAC-based webhook verification covers how that works in general, though Rippling's own webhook contract, per its own docs, is bearer-token only.

None of this is unique to Rippling. The same notify-then-reconcile split shows up anywhere an HRIS or benefits platform exposes both a webhook and a full read, including PrismHR, just with different specifics for the lag, the event catalogue, and what's gated behind partner access. What changes per platform is the fine print. What doesn't change is the shape of the design.

The same split, one layer up

Design that pipeline once for Rippling, and the next question is what happens when your product syncs five HRIS platforms instead of one, each with its own version of the same webhook-plus-sync split, its own lag, its own gaps in what's public. An integration layer that sits between your product and each HRIS is one way to keep that pattern from being rebuilt from scratch per platform.

Bindbee runs the two layers in the opposite order. A sync reads each connected system every 24 hours by default, adjustable per connection, and Bindbee's webhooks fire off that sync: connector_synced when it finishes, connector_sync_error when it fails, and connector_data_modified or employee_data_changed when the run created or updated records. Every payload names the sync job behind it, so the notification and the reconciled data arrive together, and a modified_after read returns only what that run touched. The trade-off is timing: a change reaches you after the next sync, not five minutes after it happens.

Those are the two questions worth asking of any integration layer: what's the default sync cadence, and what exactly do the webhooks notify on. The principle underneath doesn't change: something has to tell you when to look, and something else has to prove you're right. Rippling requires both from its partners because one alone was never going to be enough.

If you're weighing that same question across more than one HRIS, Bindbee's product is built around it.

Frequently asked questions

Does Rippling support webhooks?

Only for App Shop partner apps, per Rippling's webhook guide. An integration that runs on a single customer's API token should plan on polling.

How fast are Rippling webhooks?

Events arrive with a lag of roughly five minutes, and a single change can produce more than one event, so dedupe before you act.

What does a Rippling webhook payload contain?

A form-encoded POST with the event name and IDs, and no field values. Treat it as a trigger to fetch the record, not as the record itself.

How do I poll Rippling for only what changed?

On endpoints that document updated_at as filterable, such as List workers, filter with updated_at ge and the timestamp of your last successful poll, URL-encode the filter, and paginate through the results.

How often does a Rippling partner integration need a full sync?

Rippling's partner requirements call for a scheduled sync of all employee details at least every 24 hours, alongside the webhook listener, plus a manual sync button that re-reads every employee on demand.

Kunal Tyagi
CTO
Bindbee
VIEW AUTHOR
BLOG_

Related blogs