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

# Webhooks Overview

> Receive outbound events from Xobito for contacts, statuses, sources, and message delivery status.

Xobito can push events to a URL on your server in four categories:

* **CRUD** events — contacts, statuses, sources are created/updated/deleted
* **Message delivery status** events — `message.sent`, `message.delivered`, `message.read`, `message.failed` (live as of 2026-05-28)

All events POST to the same `webhook_url` you configure. Message delivery events use a [different, simpler payload](/developers/webhook-events#message-delivery-status-events) than CRUD events — see [Webhook Events](/developers/webhook-events).

<Warning>
  These categories still do **not** fire outbound webhooks: campaigns, template approvals, tickets, and conversations. For those, poll the relevant API endpoint.
</Warning>

## Configuring webhooks

<Steps>
  <Step title="Open Webhook Settings">
    In your dashboard go to **Settings → Webhook Management**.
  </Step>

  <Step title="Enable webhook access">
    Toggle **Enable Webhook Access** on.
  </Step>

  <Step title="Set the URL">
    Enter your `webhook_url`. Every configured event is POSTed to this URL.
  </Step>

  <Step title="Pick the events (CRUD)">
    Toggle the events you want:

    * **Contacts** — Create / Update / Delete
    * **Statuses** (contact status labels) — Create / Update / Delete
    * **Sources** (contact source labels) — Create / Update / Delete
  </Step>

  <Step title="Message delivery status events">
    These fire automatically for every send when **Enable Webhook Access** is on. No per-event toggle in the UI — you receive all four (`message.sent`, `message.delivered`, `message.read`, `message.failed`) at the same `webhook_url`. If you only want a subset, filter in your handler by `event`.
  </Step>

  <Step title="Save">
    Changes take effect immediately.
  </Step>
</Steps>

## Payload

Every webhook POST has this shape:

```json theme={null}
{
  "event": "created",
  "model": "App\\Models\\Tenant\\Contact",
  "data": {
    "id": 123,
    "attributes": {
      "firstname": "John",
      "lastname": "Doe",
      "phone": "+14155551234",
      "email": "john@example.com",
      "type": "lead",
      "status_id": 1,
      "source_id": 2
    },
    "relations": {}
  },
  "original": null,
  "timestamp": "2026-04-16T12:34:56+00:00"
}
```

| Field             | Meaning                                                                     |
| ----------------- | --------------------------------------------------------------------------- |
| `event`           | One of `"created"`, `"updated"`, `"deleted"`.                               |
| `model`           | Fully qualified model class — use this to tell contact/status/source apart. |
| `data.id`         | Primary key of the record.                                                  |
| `data.attributes` | Full attribute set of the record at the time of the event.                  |
| `data.relations`  | Reserved for eager-loaded relations (usually empty).                        |
| `original`        | Usually `null`.                                                             |
| `timestamp`       | ISO-8601 time the event was dispatched.                                     |

See [Webhook Events](/developers/webhook-events) for every event and an example payload of each.

## Delivery guarantees

| Property  | Value                                                                                        |
| --------- | -------------------------------------------------------------------------------------------- |
| Delivery  | HTTP POST, JSON body                                                                         |
| Attempts  | Up to **3 total**                                                                            |
| Backoff   | `1s` before attempt 2, `2s` before attempt 3 (exponential — first attempt fires immediately) |
| Execution | **Synchronous** — not queued                                                                 |
| Timeout   | `30` seconds per attempt                                                                     |
| Logging   | Every attempt is written to the internal `webhook_logs` table, purged after 30 days          |

<Note>
  Xobito issues a unique signing secret per workspace. If you do not yet have your secret, contact Xobito support to have one issued and rotated.
</Note>

<Note>
  Because webhooks are executed synchronously, your endpoint latency directly affects Xobito dashboard responsiveness. Return `2xx` quickly (ideally under 1 second) and do the heavy work asynchronously on your side.
</Note>

## Verifying requests

Every webhook request carries an HMAC-SHA256 signature in the `X-Webhook-Signature` header. See [Webhook Security](/developers/webhook-security) for how to verify.

## Testing

There is no "Send test event" button in the current version. To test your endpoint, trigger a real event — for example, create a contact in the dashboard and watch your server for the `created` POST.

## Incoming (Meta → Xobito) webhooks

Separate from outbound webhooks above, Xobito also receives inbound events from the Meta Cloud API (incoming messages, delivery receipts, template status changes). These are **not customer configurable** — they are set up automatically when you connect your Meta Business account. Do not confuse the two systems.

## Next steps

<CardGroup cols={2}>
  <Card title="Webhook Events" icon="bolt" href="/developers/webhook-events">
    The 9 events Xobito actually sends, with example payloads.
  </Card>

  <Card title="Webhook Security" icon="shield" href="/developers/webhook-security">
    HMAC signature verification.
  </Card>
</CardGroup>
