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

# Webhooks

> Learn how Bindbee pushes connector and data changes to your endpoint.

Webhooks let Bindbee push changes to you instead of you polling for them. When a connector links, syncs, fails or needs relinking, and when a sync creates or updates records, Bindbee sends a signed `POST` to a URL you control.

Every webhook is pinned to a **version**, which fixes the events it can subscribe to and the shape of every payload it receives. Two versions exist today.

| | Version 2 | Version 1 |
| - | - | - |
| Version string | `2026.10.06` | `2025.01.01` |
| Status | Current, recommended | Will be deprecated on December 31, 2026 |
| Events | 6 connector events, plus a created and an updated event for every data model | 5 events, two of them aggregates across all models |
| Environments per webhook | Production, Development, or both | One |
| Signatures | Standard Webhooks, plus the legacy header | Legacy header only |
| Event ID and sequence | On every event | None |

<Warning>
  Version 1 will be deprecated on December 31, 2026. Move each version 1 webhook
  to version 2 before then - see [Migrate from version
  1](/guides/webhooks/migrate-from-v1).
</Warning>

## What changed in version 2

| You need to | Version 1 | Version 2 |
| - | - | - |
| Know which records changed, and how | `connector_data_modified` lists IDs for every model at once, with created and updated mixed together | `hris.employee.created`, `hris.employee.updated` and one pair per model, so you subscribe to exactly the models you use |
| Process each event once | No event ID, so a retried delivery looks new | `id` is identical on every retry and every endpoint, so it's your deduplication key |
| Put events in order | Nothing to order by | `sequence` increases per connector |
| Know when a customer's connection breaks or recovers | Infer it from `connector_sync_error` on every failed sync | `connector.relink_needed` fires once when the connection breaks, and `connector.linked` and `connector.relinked` when it works |
| Cover both environments | One webhook per environment | One webhook for both, with `connector.environment` on every event |
| Reject a replayed request | The signature covers the body only, so a captured request verifies forever | `webhook-signature` covers a timestamp too, and works with any Standard Webhooks library |

## How a sync becomes events

A sync sends `connector.sync.started` when it begins. After it finishes, it sends one event per model that changed, then `connector.sync.completed`. Every event carries the next `sequence` number for that connector - see [Order within a sync](/guides/webhooks/events#order-within-a-sync).

```mermaid theme={null}
sequenceDiagram
    participant B as Bindbee
    participant Y as Your endpoint
    B->>Y: connector.sync.started (sequence 41)
    B->>Y: hris.employee.created (sequence 42)
    B->>Y: hris.employee.updated (sequence 43)
    B->>Y: connector.sync.completed (sequence 44)
```

## Why it works this way

**Pinning a version lets the payload improve without breaking you.** Version 1 bodies are frozen as they were. Everything version 2 adds lives behind a version string you chose, so no handler starts receiving a shape it has never seen.

**Data events carry record IDs, not records.** The IDs are enough to read exactly what changed with the [`ids` filter](/guides/reading-writing/reading-data/filters), the payload stays small enough to acknowledge quickly, and no record data sits in your webhook logs or ours.

**One event per model per sync replaces the aggregates.** A handler that only cares about employees subscribes to two events and never parses the rest. Created and updated arrive separately, because onboarding a new hire and syncing an edit are different jobs in most products.

**Signatures follow the [Standard Webhooks](https://www.standardwebhooks.com/) specification**, so you can verify them with a maintained library instead of hand-rolled code. The legacy header is still sent on version 2, so existing verification code keeps working while you switch.

## What this means for you

* Create new webhooks on version 2. The dashboard still offers version 1, marked with its deprecation date, until it is retired.
* Deduplicate on the event `id`. A retried delivery carries the same one - see [Delivery and retries](/guides/webhooks/delivery).
* Read the records an event names with the `ids` filter, rather than expecting them in the payload.
* Subscribe to `connector.relink_needed`. It is the one event that means your customer has to act.
* Verify `webhook-signature` on every request - see [Verify webhook signatures](/guides/webhooks/verify-signatures).

## Related

* [Create a webhook](/guides/webhooks/create-a-webhook) - set one up in the dashboard
* [Webhook events](/guides/webhooks/events) - every event, and when it fires
* [Webhook payload](/guides/webhooks/payload) - the headers and body of every delivery
* [Migrate from version 1](/guides/webhooks/migrate-from-v1) - move an existing webhook before the deadline


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