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

# Webhooks overview

> Get notified when something changes in your workspace

A webhook is an HTTPS `POST` ReachHunt sends to your server when something changes: a lead replies, a campaign finishes, a tag is added.

## Add a webhook

**1. Open webhooks**

In ReachHunt, open [**Settings → Webhooks**](https://app.reachhunt.ai/settings/webhooks) and select **Add webhook**.

**2. Set it up**

Enter a name and your `https://` URL, and pick the events it receives. Add a secret header so your server can [check each request](https://docs.reachhunt.ai/webhooks/receiving.md#check-that-a-request-came-from-reachhunt).

**3. Test it**

Open the webhook's menu and select **Send test event**.

A workspace can have up to 10 webhooks, and you need full access to every section of the workspace to manage them.

## The event

Every event has the same envelope:

```json theme={"system"}
{
  "id": "evt_9f1c3b7a-2d4e-4c6a-8b1f-0e3d5c7a9b21",
  "type": "tag.created",
  "apiVersion": "1",
  "createdAt": "2026-10-19T10:32:00.000Z",
  "workspaceId": "c2a9e1f4-7b3d-4e8a-9f1c-5d6e7a8b9c01",
  "data": {
    "tag": {
      "id": "0c9e7a52-4d1b-4f3e-8a6c-2b5d9e1f7a30",
      "name": "Hot lead",
      "color": "#f97316"
    }
  }
}
```

| Field | Notes |
| - | - |
| `id` | Unique per event. Every webhook that gets it sees the same `id`, and retries keep it. Deduplicate on it |
| `type` | `resource.action`, such as `message.received` |
| `apiVersion` | The payload version, now `1` |
| `createdAt` | When it happened |
| `workspaceId` | Your workspace |
| `data` | What happened. Each event type has its own fields |

### Headers

| Header | Value |
| - | - |
| `Content-Type` | `application/json` |
| `User-Agent` | `ReachHunt-Webhooks/1.0` |
| `X-ReachHunt-Event` | The event type |
| `X-ReachHunt-Delivery` | The delivery ID. Retries keep it |

Every request also carries the headers you added to the webhook.

> [!NOTE]
>
> ReachHunt does not sign requests. Add a secret header to the webhook and reject any request without it, see [Receiving webhooks](https://docs.reachhunt.ai/webhooks/receiving.md#check-that-a-request-came-from-reachhunt).

## Event types

| Resource | Events | `data` |
| - | - | - |
| Message | [`message.received`](https://docs.reachhunt.ai/webhooks/events/message-received), [`message.sent`](https://docs.reachhunt.ai/webhooks/events/message-sent) | `{ account, contact, message, sentBy }` |
| | [`message.seen`](https://docs.reachhunt.ai/webhooks/events/message-seen) | `{ account, contact, message, sentBy, seenAt }` |
| | [`message.edited`](https://docs.reachhunt.ai/webhooks/events/message-edited) | `{ account, contact, message, previousText }` |
| | [`message.deleted`](https://docs.reachhunt.ai/webhooks/events/message-deleted) | `{ account, contact, message }` |
| | [`message.reaction_added`](https://docs.reachhunt.ai/webhooks/events/message-reaction-added), [`message.reaction_removed`](https://docs.reachhunt.ai/webhooks/events/message-reaction-removed) | `{ account, contact, message, reaction }` |
| Conversation | [`conversation.created`](https://docs.reachhunt.ai/webhooks/events/conversation-created), [`conversation.deleted`](https://docs.reachhunt.ai/webhooks/events/conversation-deleted), [`conversation.archived`](https://docs.reachhunt.ai/webhooks/events/conversation-archived), [`conversation.unarchived`](https://docs.reachhunt.ai/webhooks/events/conversation-unarchived) | `{ account, conversation, contact }` |
| Lead | [`lead.added_to_list`](https://docs.reachhunt.ai/webhooks/events/lead-added-to-list) | `{ list, lead }` |
| | [`lead.status_changed`](https://docs.reachhunt.ai/webhooks/events/lead-status-changed) | `{ lead, previousStatus, status }` |
| | [`lead.tag_added`](https://docs.reachhunt.ai/webhooks/events/lead-tag-added), [`lead.tag_removed`](https://docs.reachhunt.ai/webhooks/events/lead-tag-removed) | `{ lead, tag }` |
| | [`lead.note_changed`](https://docs.reachhunt.ai/webhooks/events/lead-note-changed) | `{ lead, note }` |
| | [`lead.valuation_changed`](https://docs.reachhunt.ai/webhooks/events/lead-valuation-changed) | `{ lead, previousValuation, valuation }` |
| | [`lead.assignee_changed`](https://docs.reachhunt.ai/webhooks/events/lead-assignee-changed) | `{ lead, previousAssignee, assignee }` |
| Campaign | [`campaign.created`](https://docs.reachhunt.ai/webhooks/events/campaign-created), [`campaign.started`](https://docs.reachhunt.ai/webhooks/events/campaign-started), [`campaign.paused`](https://docs.reachhunt.ai/webhooks/events/campaign-paused), [`campaign.resumed`](https://docs.reachhunt.ai/webhooks/events/campaign-resumed), [`campaign.completed`](https://docs.reachhunt.ai/webhooks/events/campaign-completed), [`campaign.stopped`](https://docs.reachhunt.ai/webhooks/events/campaign-stopped) | `{ campaign }` |
| Campaign lead | [`campaign.lead_contacted`](https://docs.reachhunt.ai/webhooks/events/campaign-lead-contacted), [`campaign.follow_up_sent`](https://docs.reachhunt.ai/webhooks/events/campaign-follow-up-sent) | `{ campaign, account, lead, messagesSent, stepType }` |
| | [`campaign.lead_replied`](https://docs.reachhunt.ai/webhooks/events/campaign-lead-replied) | `{ campaign, account, lead, repliedAt }` |
| | [`campaign.lead_failed`](https://docs.reachhunt.ai/webhooks/events/campaign-lead-failed) | `{ campaign, account, lead, stepType, error }` |
| | [`connection_request.sent`](https://docs.reachhunt.ai/webhooks/events/connection-request-sent) | `{ campaign, account, lead, withNote }` |
| | [`connection_request.accepted`](https://docs.reachhunt.ai/webhooks/events/connection-request-accepted), [`connection_request.withdrawn`](https://docs.reachhunt.ai/webhooks/events/connection-request-withdrawn) | `{ campaign, account, lead }` |
| Account | [`account.connected`](https://docs.reachhunt.ai/webhooks/events/account-connected) | `{ account }` |
| | [`account.disconnected`](https://docs.reachhunt.ai/webhooks/events/account-disconnected) | `{ account, reason, detail }` |
| Import | [`import.completed`](https://docs.reachhunt.ai/webhooks/events/import-completed), [`import.paused`](https://docs.reachhunt.ai/webhooks/events/import-paused), [`import.failed`](https://docs.reachhunt.ai/webhooks/events/import-failed) | `{ import }` |
| Tag | [`tag.created`](https://docs.reachhunt.ai/webhooks/events/tag-created), [`tag.updated`](https://docs.reachhunt.ai/webhooks/events/tag-updated), [`tag.deleted`](https://docs.reachhunt.ai/webhooks/events/tag-deleted) | `{ tag }` |
| Status | [`status.created`](https://docs.reachhunt.ai/webhooks/events/status-created), [`status.updated`](https://docs.reachhunt.ai/webhooks/events/status-updated), [`status.deleted`](https://docs.reachhunt.ai/webhooks/events/status-deleted) | `{ status }` |

Each event type has its own page under **Event types** with its full schema.

* New event types are not added to existing webhooks. Edit a webhook to start receiving them.
* Payloads follow the API's [conventions](https://docs.reachhunt.ai/developer-api/response-format.md#conventions): camelCase names, timestamps in ISO 8601 UTC, and `null` for a value that does not apply.
* New event types and `data` fields can be added within version `1`. Ignore what you don't know.

## Limits

* Up to 10 webhooks in a workspace.
* Up to 5 custom headers on a webhook.
* The URL must start with `https://`, point to a public address, and be at most 2048 characters.
* Your server has 10 seconds to answer.

> **[Receiving webhooks](https://docs.reachhunt.ai/webhooks/receiving.md)**
>
> Answer deliveries, check they came from ReachHunt, and handle retries.


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