# Overview

> Signed HTTP callbacks the moment something happens, instead of polling the API.

Source: https://www.hey.support/docs/webhooks

---

Webhooks push events to your own endpoint as they happen. Anything you would otherwise poll the [API](/docs/api) for — a new lead, a booking, a visitor asking for a human — arrives instead within a second or so.

## Set one up

Go to **Settings → Developer** (owner only) and add an endpoint. You give us:

* **A URL.** Must be `https` in production, and must not resolve to a private or link-local address — we check on every delivery, not just at creation.
* **The events** you want. Subscribe to what you handle; unsubscribed events are never sent.
* **A scope.** An endpoint is either workspace-wide or scoped to a single agent.

You get back a **signing secret**, which is how you prove a delivery came from us. See [Verifying signatures](/docs/webhooks/signature).

## The envelope

Every delivery is a JSON `POST` with the same outer shape. Only `data` varies by event.

```json
{
  "id": "3f1c…",
  "event_id": "b47e…",
  "event": "lead.created",
  "api_version": "2026-04-27",
  "created_at": "2026-08-26T10:00:00.000Z",
  "workspace_id": 42,
  "chatbot_id": 17,
  "data": {}
}
```

| Field         | Meaning                                                                                   |
| ------------- | ----------------------------------------------------------------------------------------- |
| `id`          | This delivery attempt. Stable across retries of the same attempt.                         |
| `event_id`    | The logical event. **Dedupe on this.** Shared across endpoints, different across resends. |
| `event`       | The event name, e.g. `lead.created`.                                                      |
| `api_version` | Payload contract version. Currently `2026-04-27`.                                         |
| `chatbot_id`  | Present when the event belongs to one agent.                                              |
| `data`        | The event-specific body.                                                                  |

## Headers

| Header                     | Purpose                                           |
| -------------------------- | ------------------------------------------------- |
| `X-HeySupport-Signature`   | HMAC-SHA256 of the raw body, as `sha256=<hex>`.   |
| `X-HeySupport-Delivery-Id` | Matches `id`. Unique per delivery attempt.        |
| `X-HeySupport-Event-Id`    | Matches `event_id`. Use it to dedupe.             |
| `X-HeySupport-Event`       | The event name, so you can route without parsing. |

## Events

<Cards>
  <Card title="Conversation events" href="/docs/webhooks/events/conversation" description="conversation.started, conversation.ended, message.sent" />

  <Card title="Lead events" href="/docs/webhooks/events/lead" description="lead.created" />

  <Card title="Booking events" href="/docs/webhooks/events/booking" description="booking.created, booking.rescheduled, booking.canceled" />

  <Card title="Handoff events" href="/docs/webhooks/events/handoff" description="handoff.requested, handoff.resolved" />

  <Card title="Action events" href="/docs/webhooks/events/action" description="action.requires_approval" />
</Cards>

<Callout>
  Delivery is **at-least-once**. The same event can arrive more than once, so make your handler idempotent on `event_id`. See [Delivery and retries](/docs/webhooks/delivery).
</Callout>
