Texa DeskDevelopers

Webhooks

Texa Desk webhooks

Hear about every conversation, message, contact and ticket in Texa Desk, signed, as it happens.

Texa Desk webhooks tell your server what happens in the helpdesk: new conversations, every message (from customers, your team and Texa AI), contact changes and tickets. Use them to copy conversations into your own systems, update a CRM, or trigger your own work.

For events from Texa API conversations (replies, action requests, handovers), use the Texa API webhooks instead.

Add a webhook

In Texa Desk, Settings → Integrations → Webhooks → Add new webhook: your URL and the events you want. Each webhook has a secret (shown with an eye button, and copyable) that signs every delivery. Or use the API: Add a webhook.

Events

Event When
conversation_created a conversation starts
conversation_updated a conversation's attributes change (assignee, team, labels, custom attributes, its ticket)
conversation_status_changed it becomes open, pending, snoozed or resolved
message_created a message is added: incoming, outgoing, or a private note
message_updated a message changes (delivered, read, failed, edited)
contact_created, contact_updated a contact is added or changed (including a merge)
conversation_typing_on, conversation_typing_off someone in your team starts or stops typing
webwidget_triggered a visitor opens the live chat on your website
inbox_created, inbox_updated an inbox is added or changed
ticket_created, ticket_updated, ticket_merged a ticket is made, changed (state, type, person) or merged

What arrives

HTTP
POST https://your-server/texa-desk/webhooks
Content-Type: application/json
X-Chatwoot-Delivery: 7b0d0d6e-0f6c-4b1e-9c0e-2b0d6a3a9f11
X-Chatwoot-Timestamp: 1790000000
X-Chatwoot-Signature: sha256=<hex HMAC-SHA256 of "1790000000.<raw body>" with the webhook's secret>
JSON
{
  "event": "message_created",
  "id": 50211,
  "content": "Hello, my transfer of 80,000 has not arrived",
  "message_type": "incoming",
  "content_type": "text",
  "private": false,
  "created_at": "2026-10-19T10:00:03.112Z",
  "source_id": "wamid.HBgN...",
  "sender": {"id": 345, "name": "Ngozi Eze", "phone_number": "+2348031234567", "type": "contact"},
  "conversation": {"id": 171, "inbox_id": 12, "status": "pending", "...": "..."},
  "inbox": {"id": 12, "name": "WhatsApp"},
  "account": {"id": 1, "name": "Pilot Bank"}
}
  • Messages carry content, message_type (incoming, outgoing, activity, template), private (a note your team only), sender, conversation, inbox, account, and attachments when there are files.
  • Conversation events carry the conversation (with its meta.sender, meta.assignee, labels, custom attributes and ticket) and, for updates, changed_attributes: each changed field as [before, after].
  • Contact events carry the contact: id, name, email, phone_number, identifier, custom_attributes, additional_attributes.
  • Ticket events carry the ticket (reference, title, type, state, person, team, promise), contact, conversations, and for ticket_updated its changed_attributes, the state and type by name: "state": ["New", "Waiting on customer"].

Check the signature

The signature is HMAC-SHA256 over "<X-Chatwoot-Timestamp>.<raw body>" with the webhook's secret, written as sha256=<hex>. Compute it over the raw body, before parsing, compare in constant time, and reject a timestamp older than five minutes. The code is the same as for Texa's own signatures, with these header names.

These header names come from the open-source Chatwoot helpdesk Texa Desk is built on, and are kept so that existing integrations work unchanged.

Answer fast

  • Texa Desk waits 5 seconds for your answer and sends each event once: there are no retries. Answer 200 at once and do the work afterwards (put the event on your own queue).
  • Use X-Chatwoot-Delivery to spot a repeat.
  • If your server was down, catch up from the API: list conversations updated since then, and their messages.

Per inbox: API inboxes

An API inbox has its own webhook URL, which gets that inbox's events, signed with the inbox's secret. That's how your own channel hears your team's replies.