Message webhooks
Subscribe to Bow Chat message events, verify webhook signatures, deduplicate deliveries, and update downstream delivery state.
OpenAPI contractSubscribe
Create one HTTPS webhook for the integration and subscribe to message_created and message_updated:
curl --request POST \
--url https://app.bow.chat/api/v1/accounts/ACCOUNT_ID/webhooks \
--header 'api_access_token: BOW_CHAT_TOKEN' \
--header 'content-type: application/json' \
--data '{"webhook":{"name":"Delivery events","url":"https://example.com/webhooks/bow-chat","subscriptions":["message_created","message_updated"]}}'
Save the secret returned for that webhook in a server-side secret store.
Verify every request
Bow Chat sends these headers for account webhooks:
| Header | Use |
|---|---|
X-Chatwoot-Delivery | Unique delivery ID for deduplication |
X-Chatwoot-Timestamp | Unix timestamp used in the signature |
X-Chatwoot-Signature | sha256=<hex HMAC> |
Compute HMAC-SHA256 with the webhook secret over:
<timestamp>.<exact raw request body>
Compare the result with X-Chatwoot-Signature using a constant-time comparison. Reject a timestamp outside your replay window, and record X-Chatwoot-Delivery before processing so a retry cannot produce a duplicate action. Parse JSON only after signature verification.
Process message states
For outgoing messages, keep the latest state by message.id:
sent: accepted by the channel path; keep waiting.delivered: delivered when the provider reports it.read: read when the provider reports it.failed: terminal for that attempt; inspect the error before deciding any fallback.
Events can be retried or arrive after your own timeout. Make processing idempotent and never let a late event send the same business notification twice.