integrations webhooks
H

Hisham

Last updated on Oct 12, 2026

A webhook is a URL you own. You tell Lynomia Chat which events you care about, and each time one happens we POST a JSON body to that URL. It is the way to make something outside the product react to what happens inside it.

When to use it

When another system needs to know. A ticketing tool that should open a case when a conversation is created, a dashboard that counts incoming messages, an automation tool that starts a workflow when a contact is added.

When not to use it

  • To send messages or change anything. Webhooks are outbound only. Use the API for writes.
  • To answer a conversation in line. Whatever your endpoint returns is discarded. Nothing it sends back enters the conversation.
  • For one specific rule. If you only want a POST when a particular condition is met, the webhook action in an automation rule or a flow is narrower and cheaper than subscribing to every message in the account.

What you need first

An administrator account, and an endpoint that is reachable from the public internet over HTTP or HTTPS and answers within a few seconds. On some plans, Webhooks shows an upgrade notice instead of the list.

Steps

  1. Go to Settings → Integrations → Webhooks and choose Add new webhook.
  2. Enter the URL, give it a name, and tick the events you want. At least one event is required.
  3. Save. The secret is shown once on the confirmation screen; copy it then. You can also reveal it later in the webhook's edit form.

The events

Ten events are offered in the form. An eleventh, inbox_updated, appears only if your installation has inbox events switched on.

Event Fires when
conversation_created a conversation is opened
conversation_updated any attribute of a conversation changes
conversation_status_changed its status changes
message_created a message is added
message_updated a message changes
contact_created a contact is added
contact_updated a contact's attributes change
webwidget_triggered a visitor opens the live chat widget
conversation_typing_on / conversation_typing_off someone starts or stops typing
inbox_updated an inbox's settings change

Two things to expect. conversation_updated is noisy — it fires on changes you would not call an update, so filter on changed_attributes rather than treating every one as news. And only incoming, outgoing and template messages are sent; private notes and activity lines are not.

The payload

Every body is a JSON object with an event key naming the event, plus the object the event is about.

Event group Body carries
Message events the message — id, content, content_type, message_type, private, source_id, attachments when present — plus its conversation, inbox, sender and account
Conversation events the conversation — id, status, priority, labels, inbox_id, meta with sender, assignee and team, custom_attributes, timestamps — its newest message, and account
Contact events the contact — id, name, email, phone_number, identifier, avatar, custom_attributes, additional_attributes, blocked — and account

The three "changed" events — conversation_updated, conversation_status_changed and contact_updated — add a changed_attributes array describing what moved. contact_updated and inbox_updated are not sent at all when nothing changed.

Verifying a delivery

Each webhook has its own secret, and signed deliveries carry three request headers: a delivery id, a timestamp, and a signature. The signature's value is sha256= followed by the HMAC-SHA256 of the timestamp, a full stop, and the raw request body, keyed with the secret:

sha256=HMAC_SHA256(secret, "<timestamp>.<raw body>")

Compute it over the bytes you received, not over a re-serialised copy, and compare in constant time. Reject anything that does not match, and treat the delivery id as the key for ignoring a repeat.

The three headers are named exactly:

Header Carries
X-Chatwoot-Signature sha256= followed by the HMAC above
X-Chatwoot-Timestamp the timestamp the signature was computed over
X-Chatwoot-Delivery the delivery id, when one is available

Those names are part of the wire format and do not change with the installation's branding.

When a delivery fails

This is the part worth reading twice. A webhook delivery is attempted once.

What happens
Your endpoint is slow the request is abandoned after the installation's webhook timeout, five seconds by default
Your endpoint answers 4xx or 5xx the delivery is counted as failed
Your endpoint is down the delivery is counted as failed
Any of the above the failure is written to the server log. Nothing is retried, nothing is queued, and nothing is shown to you

So events that occur while your endpoint is unavailable are gone. If you cannot afford to lose them, accept the POST into a queue of your own, answer immediately, and process it afterwards.

Who can do this

Administrators only. The custom role permission list has no entry for webhooks, so it cannot be delegated — see roles and permissions.

Limits

  • No retries, no delivery history, no replay, and no test button. You verify a webhook by triggering a real event.
  • One webhook per URL per account. To get the same events twice, use two URLs.
  • Private and internal addresses are refused. A URL resolving to localhost or a private network is not delivered to. Your endpoint has to be publicly reachable.
  • inbox_created cannot be subscribed to in the form. It exists in the API's event list only.
  • The response body is never read, and the response's content type is not checked.
  • The payload is not configurable. You cannot add fields, remove fields or choose a format.
  • Subscriptions are account-wide. You cannot subscribe to one inbox's messages only; filter by inbox in your own code.

Other things that POST to a URL

Webhooks are one of several. They are not interchangeable, and only some are signed.

Sent by event in the body Signed
A webhook subscription the event you subscribed to yes, with the webhook's secret
The webhook action in an automation rule automation_event.<trigger>, with a commerce block on a Commerce trigger no
The webhook action in a macro macro.executed no
The webhook node in a flow flow_webhook, with the flow, session and the values the flow collected yes, with the flow bot's secret

Related

If it does not work

Nothing arrives. Check in this order: the endpoint is publicly reachable, it answers within five seconds, and the event you expect is actually ticked. A URL on a private network never receives anything.

Some events arrive and others do not. Private notes and activity lines are not sent as messages, and contact_updated is suppressed when nothing changed.

My signature check fails. You are almost certainly hashing a re-serialised body. Hash the raw bytes, and include the timestamp and the full stop before them.

I lost events during an outage. There is no backfill. Read the API for the period you missed.

The Webhooks page shows an upgrade notice. API and webhooks are not included on your plan.