# Webhooks

> Receive signed events when email delivery, contact activity, and WhatsApp messages change.

## Connect an endpoint

Create a webhook in your project's dashboard, choose the events you need, and supply a publicly reachable HTTPS URL. Save the signing secret securely when it is shown.

Your endpoint receives an HTTP `POST` with a JSON body. Verify its signature before parsing or processing the event.

## Event envelope

Every event includes a stable `id`, its `type`, a `schema_version`, event-specific `data`, and a `created_at` timestamp. Example identifiers are illustrative.

```json
{
  "id": "00000000-0000-4000-8000-000000000001",
  "type": "email.delivered",
  "schema_version": 1,
  "data": {
    "id": "delivery_example",
    "message_id": "message_example",
    "recipient": "reader@example.com",
    "occurred_at": "2026-10-02T10:00:00.000Z"
  },
  "created_at": "2026-10-02T10:00:00.000Z"
}
```

## Delivery headers

| Header | Purpose |
| --- | --- |
| `x-nexiom-webhook-id` | The subscribed endpoint. |
| `x-nexiom-webhook-call-id` | This delivery; a replay gets a new call ID. |
| `x-nexiom-event-id` | The event ID. |
| `x-nexiom-event-type` | Event type. |
| `x-nexiom-timestamp` | Attempt timestamp in Unix seconds. |
| `x-nexiom-signature` | Hex-encoded HMAC-SHA256 signature. |

## Build your receiver

1. [Verify the request](/docs/webhooks/verify-webhooks-requests) with the Node.js or PHP SDK, using the exact body bytes.
2. [Accept the event durably](/docs/webhooks/ingester) before responding with a `2xx` status.
3. Process it idempotently and prepare for [retries and replays](/docs/webhooks/retries-and-replays).

Browse [Event Types](/docs/webhooks/event-types) to choose your subscriptions.

---

Source: https://connect.nxiom.com/docs/webhooks
