# Events and webhooks

> How data moves in and out of Kustomer as events. Outbound webhooks push changes to your systems, inbound hooks accept data from anywhere, and every change carries a before-and-after diff.

Source: https://developer.kustomer.com/docs/events

Every create and update in Kustomer produces an **event**: a JSON envelope with the full resource and a diff of what changed. Workflows react to events internally. Outbound webhooks deliver a subset of them to your servers. Inbound hooks turn data you send into events that start workflows.

```mermaid
flowchart LR
  subgraph In["Into Kustomer"]
    API[REST API]
    Hooks[Inbound hooks<br/>form · web · email]
  end
  subgraph K["Kustomer"]
    Store[(Records)]
    Bus{{Events}}
    WF[Workflows]
  end
  subgraph Out["Out of Kustomer"]
    OWH[Outbound webhooks]
    REST[Workflow REST API steps]
  end
  API --> Store --> Bus
  Hooks --> Bus
  Bus --> WF
  WF --> Store
  Bus --> OWH --> You[(Your service)]
  WF --> REST --> You
```

_A live feed of simulated outbound webhook deliveries. Each row shows an event name such as conversation.update and its delivery status. Selecting a row shows the HTTP request with X-Kustomer-Webhook-Event and X-Kustomer-Webhook-Signature headers, the JSON body, and a timeline of delivery attempts on the 1, 1, 2, 5, 10, 15 and 30 minute retry schedule. A toggle switches the receiver between healthy, flaky and down._

## Choose a mechanism

| You want to                                                     | Use                                                                                                                                        | Notes                                              |
| --------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------- |
| Mirror customers, conversations or messages into another system | [Outbound webhooks](https://developer.kustomer.com/docs/events/outbound-webhooks)                                                          | 12 event types, signed, retried for about an hour  |
| Call your API only when certain conditions are true             | [Workflow](https://developer.kustomer.com/docs/workflows) with a [REST API step](https://developer.kustomer.com/docs/workflows/code-steps) | Filter first, shape the payload, use any trigger   |
| React to custom objects, notes or companies                     | A [workflow](https://developer.kustomer.com/docs/workflows/triggers-and-actions)                                                           | These events aren't available to outbound webhooks |
| Send data into Kustomer from a form, script or partner          | [Inbound hooks](https://developer.kustomer.com/docs/events/inbound-webhooks)                                                               | Each hook triggers a workflow                      |
| Write records directly                                          | The [REST API](https://developer.kustomer.com/docs/get-started/making-requests)                                                            | Writes produce events like any other change        |
| Backfill or reconcile                                           | [Search](https://developer.kustomer.com/docs/guides/search-recipes#incremental-sync)                                                       | Webhooks don't replay history                      |

## The event envelope

Outbound webhooks and workflows see the same envelope. `data` is the full resource as of the change, in the same [JSON:API shape](https://developer.kustomer.com/docs/concepts/json-api-format) the REST API returns. `changes` lists only the attributes and relationships that changed.

```json title="kustomer.conversation.update"
{
  "id": "6717c2a4e5b1f00012ab34cd",
  "name": "kustomer.conversation.update",
  "org": "5f8481c6a22ab5b9d5f2dd8a",
  "partition": "5f8481c6a22ab5b9d5f2dd8a",
  "orgName": "acme",
  "data": {
    "type": "conversation",
    "id": "6717c29fe5b1f00012ab34c1",
    "attributes": {
      "name": "Where is my order?",
      "status": "done",
      "priority": 3,
      "channels": ["email"],
      "tags": ["5f9a1c2e8b3d4e0012345678"],
      "updatedAt": "2026-10-21T15:02:11.482Z"
    },
    "relationships": {
      "customer": { "data": { "type": "customer", "id": "6717c29de5b1f00012ab34b9" } }
    },
    "links": { "self": "/v1/conversations/6717c29fe5b1f00012ab34c1" }
  },
  "createdAt": "2026-10-21T15:02:11.511Z",
  "changes": {
    "attributes": {
      "status": { "op": "replace", "before": "open", "after": "done" }
    },
    "relationships": {}
  }
}
```

**Envelope fields**

> **Snapshots, not commands:** Treat each event as "this is what the record looks like now." Apply `data` idempotently, and use `changes` only to decide _whether_ to act. If two events for the same record arrive out of order, keep the one with the later `data.attributes.updatedAt`.

## What's in this section

- [Outbound webhooks](https://developer.kustomer.com/docs/events/outbound-webhooks): Subscribe an HTTPS endpoint to Kustomer events through the API, the UI or an app definition.
- [Event catalog](https://developer.kustomer.com/docs/events/event-catalog): Every event you can subscribe to, with payloads, plus the extra events available to workflows.
- [Delivery and security](https://developer.kustomer.com/docs/events/delivery-and-retries): Verify signatures, handle retries and duplicates, and keep your webhook from being disabled.
- [Inbound webhooks](https://developer.kustomer.com/docs/events/inbound-webhooks): Form, web and email hooks that bring outside data into workflows.
