Outbound Webhooks
Push Wexio events to external systems in real time
Outbound webhooks let Wexio push data into external systems whenever something meaningful happens - a contact is created, a message is delivered, a flow reaches a checkpoint you care about. Wexio can sign each delivery, retries on failure, and logs every attempt for 7 days.

Delivery Flow
Something happens in Wexio
│
▼
Find active outbound connections subscribed to the event
│
▼
Queue one delivery per connection
│
▼
POST the envelope to your URL, with retries
│
▼
Write a delivery log row (SUCCESS, RETRYING, FAILED or DEAD_LETTER)Emission is fire-and-forget - Wexio never waits for the delivery to complete before continuing, and a failed POST never blocks whatever produced the event.
Creating an Outbound Connection
From Settings → Webhooks and API → Webhooks, click New connection and set Direction to Outbound.

| Field | Description |
|---|---|
| Connection name | Display name |
| Target URL | Where Wexio should POST events. It must be a public https:// address: localhost, private IP addresses and URLs with a username or password are rejected. Optional at creation: you can set it later on the connection page |
| Authentication | None, Basic, Bearer token or HMAC signature |
| Credential | The token, username:password, or the shared secret that signs requests |
| Event subscriptions | Which events trigger a delivery to this connection. Optional at creation: you can change them at any time |
Click Create connection. With no event selected, the section shows Select at least one event to enable outbound delivery.
Authentication
Choose what headers Wexio attaches to every POST.

| Authentication | Header | Typical use |
|---|---|---|
| None | - | Endpoints that don't require auth (internal, IP-allowlisted) |
| Bearer token | Authorization: Bearer <token> | Most SaaS APIs, your own backend |
| Basic | Authorization: Basic <base64(user:pass)> | Legacy systems |
| HMAC signature | X-Wexio-Signature: t=<unix>,v1=<hex> | Receivers that want to verify the payload came from Wexio |
See Envelope & Delivery for the exact headers, signing scheme, retry policy, and verification pseudo-code.
Credentials are encrypted at rest and never returned to clients.
Event Catalogue
Subscribe to any combination of these in the connection's Event subscriptions section, then click Save subscriptions. The toast says Event subscriptions updated. The picker groups events under Chats, Messages, Contacts, Flows, Conversations, Comments and Posts, and shows the dotted name under each label.

type on the wire is the dotted lowercase name; the subscription picker and the API's events argument use the SCREAMING_SNAKE enum form of the same name.
| Event | In the picker | Reference |
|---|---|---|
conversation.created | Conversation created | conversation.created |
conversation.updated | Conversation updated | conversation.updated |
chat.created | Chat created | Chat Created |
chat.updated | Chat updated | Chat Updated |
chat.deleted | Chat deleted | Chat Deleted |
message.inbound.created | Inbound message received | Message Inbound Created |
message.inbound.updated | Inbound message updated | Message Inbound Updated |
message.inbound.deleted | Inbound message deleted | Message Inbound Deleted |
message.outbound.created | Outbound message sent | Message Outbound Created |
message.outbound.updated | Outbound message edited | Message Outbound Updated |
message.outbound.deleted | Outbound message deleted | Message Outbound Deleted |
message.outbound.status | Outbound message delivery status | message.outbound.status - opt-in, delivery-status changes |
contact.created | Contact created | Contact Created |
contact.updated | Contact updated | Contact Updated |
contact.deleted | Contact deleted | Contact Deleted |
contact.merged | Contacts merged | contact.merged |
contact.split | Contact split apart | contact.split |
post.created | Post published | post.created |
post.deleted | Post deleted | post.deleted |
comment.created | Comment received | comment.created |
comment.updated | Comment updated | comment.updated |
comment.deleted | Comment deleted | comment.deleted |
organisation.deleted | - | organisation.deleted - partners only |
flow.<suffix> / flow | Custom flow events (flow.*) | Flow Custom Events |
Shared payload shapes (ConversationPayload, ChatPayload, MessagePayload, ContactPayload, CommentPayload, PostPayload, enums) are documented once in Shared Types.
Conversations, Chats and Messages
The inbox is three levels, and there is an event family for each:
| Level | What it is | Events |
|---|---|---|
| Conversation | The inbox row for a contact. Groups the contact's channel threads. | conversation.* |
| Chat (thread) | One channel thread inside a conversation. Carries the messages. | chat.* |
| Message | A single message in a thread. | message.* |
A contact who writes on WhatsApp and Telegram has one conversation with two chats.
One inbound message can produce several events, such as message.inbound.created and conversation.updated. Subscribe to the narrowest level that answers your question:
- Mirroring messages?
message.*alone. Thechatpayload rides along with each one. - Reacting to thread-level changes (assignment, status)? Add
chat.*. - Tracking the inbox row across channels? Add
conversation.*.
Deduplicate on meta.eventId and reconcile by the timestamps in data, never by arrival order.
Partner Fan-Out
If your organisation is a tech provider, you can register one webhook that receives events for every client org you manage, each tagged with the child org and your own externalId. Same catalogue, same signing, same retries - only the delivery scope differs. See Partner webhooks.
Custom flow.* events
Drop an Outbound Webhook Event card into any flow to emit a custom event with a payload of your choice. The card lets flow authors type a suffix like order_confirmed which Wexio delivers as flow.order_confirmed.
Pick Custom flow events (flow.*) to receive every flow.* event from your organisation. One subscription covers all custom flow events, no matter what suffixes the authors invent later.
You cannot subscribe to a single suffix. The Custom flow events (flow.*) subscription delivers every flow.* event, so filter on type (or meta.event) on your side.
Retries & Delivery Log
Every attempt is persisted for 7 days. The same eventId can appear across several rows - one per attempt - until delivery succeeds or is dead-lettered.

| Status | Meaning |
|---|---|
PENDING | Enqueued, not yet attempted |
SUCCESS | 2xx response from your endpoint |
RETRYING | A 5xx response or network error; Wexio retries with exponential backoff, up to 6 attempts |
FAILED | A final failure with no retry, such as a 4xx response or a redirect |
DEAD_LETTER | Retries exhausted; no further automatic attempts |
Failed and dead-lettered events stay in the log, so you can inspect the response. See Envelope & Delivery for the full retry rules.
Emit Custom Events from Flows
Add the Outbound Webhook Event card anywhere in a flow. The card:
- Resolves flow variables in the event name suffix (so
flow.order_{{webhook.order.id}}becomesflow.order_abc123at runtime). - Parses a raw JSON payload (authored in a Monaco editor) with variable interpolation applied before
JSON.parse. - Emits the event without waiting, and advances to the next card immediately.
The card needs the Pro plan or higher. See the card reference for full config details.
Rules and Caveats
- Fire-and-forget - emission never blocks flows or core operations. A broken subscriber URL has no effect on Wexio performance.
- Retries use exponential backoff, up to 6 attempts. Return 2xx as soon as you've accepted the payload - do the heavy work asynchronously on your side.
- Idempotency is on you. The same event can arrive multiple times (retries, network partitions). Dedupe by
X-Wexio-Event-Id(equivalent tometa.eventId). - Envelope data root is always an object. Arrays and primitives emitted from the custom card are wrapped under
{ "value": ... }for stability. - Preview chats are real. A chat from a Signed in web widget preview is a real contact, so it reaches your webhooks like any other.
- Per-connection scope. Each connection subscribes independently - deleting or pausing one does not affect the others.
- No cross-org leaking. Outbound deliveries are tenant-scoped; a connection only ever receives events from the organisation that owns it.
Pause & Resume
Click Pause in the header of an outbound connection to stop new deliveries without deleting history. Click Resume to start again. The toast says Status changed to the new status. Logs opens the delivery log.
Change the HMAC Secret
For HMAC signature, you choose the shared secret. To change it, click Open (or Edit details in the row menu), paste a new Credential and click Save changes. The new secret applies to the next delivery, so update your verifier first or accept both values while you switch.
Related
- Envelope & Delivery - headers, signing, retry policy
- Shared Types -
ChatPayload,ContactPayload,MessagePayload, enums - Webhook History - delivery logs and live-tail subscription