support.* events
Member support inbox: conversations opened, replied to, assigned and resolved.
Member support inbox: conversations opened, replied to, assigned and resolved. A member who sends your project bot something it does not recognise opens a support conversation. These events are how that traffic reaches a helpdesk, an ops channel or an on-call rota instead of sitting in the dashboard waiting to be noticed.
No
support.*payload carries the message body. That is deliberate: webhook deliveries are logged and retried, and member text does not belong in a delivery log. Fetch the body from the support conversations endpoints or with theget_support_conversationMCP tool.
Background
One conversation per member, per channel
There is exactly one conversation per (project, member, channel). It is a durable thread, not a per-session ticket, so:
support.conversation.openedfires once per member per channel, ever. Their second message and every message after it raisessupport.message.receivedonly.- Resolving does not close the thread. The next inbound message reopens it and raises
support.conversation.reopened. - A workflow that wants "every new member question" should listen to
support.message.received, notopened.
Example payload
Every support.* event uses the standard envelope and a flat data object of identifiers:
{
"id": "evt_01HX...",
"type": "support.message.received",
"created_at": "2026-08-20T10:05:00Z",
"api_version": "2026-05-01",
"project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",
"data": {
"message_id": "6c18f7a3-2e95-4d60-b47a-c093e5182b7f",
"conversation_id": "9e042b6f-5d81-4c37-a920-7b3e18cf6d45",
"project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",
"subscriber_id": "2a91c4e7-6f38-4b52-8e0d-9c1a7b3f5d80",
"type": "text",
"has_attachments": false
}
}Guarantees
- The member's message body, their platform identity and any attachment file ids are never in the payload. Resolve them over the API with
data.conversation_id. support.message.receivedandsupport.conversation.openedboth fire on a member's first message, in that order of significance: treatopenedas the "new contact" signal andreceivedas the "new question" signal.- Internal notes raise no event at all. They are private remarks for your team and never reach the member or a webhook.
- A message from a blocked member is dropped before any event fires, and cannot reopen a resolved thread.
- Rate-limited inbound messages are dropped silently. A member flooding the bot produces no event storm.
Required abilities
Tokens subscribing to support.* events must carry support-conversation:view.
Events
support.conversation.openedA member starts their first support conversation on a channel.support.conversation.assignedA support conversation is handed to a team member, or its assignment cleared.support.conversation.resolvedA support conversation is marked resolved and leaves the open queue.support.conversation.reopenedA resolved support conversation becomes active again.support.conversation.blockedA creator silences a member's support messages.support.conversation.unblockedA creator lets a silenced member's support messages through again.support.message.receivedA member sends a message into a support conversation.support.message.sentA reply to a member is recorded and queued for delivery.support.canned_reply.createdA saved reply is added to a project's support inbox.support.canned_reply.updatedA saved reply's title, body, shortcut or position changes.support.canned_reply.deletedA saved reply is removed from a project's support inbox.support.settings.updatedA project's support inbox settings change.support.conversation.opened
WEBHOOKA member starts their first support conversation on a channel.
When this fires
A member sends your project bot a message it does not recognise as a command, an access code, or an answer the bot was waiting for, and they have no conversation on that channel yet. Subscriby creates the conversation and emits this event, immediately followed by support.message.received for the message itself.
The message can be text, a photo, a document, a voice note or any other supported media. A bare photo with no caption opens a conversation just as text does.
It does not fire when:
- The member already has a conversation on that channel, even a resolved one. A resolved thread reopens and raises
support.conversation.reopenedinstead. - The message was a recognised bot command, or an answer the bot was waiting for during a guided setup step.
- The member is blocked, or has tripped the inbound rate limit.
- Support is switched off for the project.
This fires once per member, per channel, ever. It is a "new contact" signal, not a "new question" signal. For every question a member asks, listen to
support.message.received.
Caveats
- The payload carries no message body and no member name. Fetch them with the conversation messages endpoint.
- The member may be a lead rather than a subscriber. Anyone who can reach the bot can open a conversation, including someone who has never paid:
data.subscriber_idresolves to a project user whose status may belead. - Opening a conversation is not the same as the creator being notified. Notification is throttled to one bot DM per conversation per five minutes, so a burst of messages produces one ping but many events.
Related events
support.message.received: fires alongside this event, for the message itself.support.conversation.reopened: the returning-member counterpart.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
A support conversation is handed to a team member, or its assignment cleared.
When this fires
A conversation's assignee changes: it is handed to a team member from the dashboard inbox, the REST API, Zapier, or n8n, or an existing assignment is cleared.
Clearing an assignment fires this same event with
data.assigned_to_user_id: null. There is no separate "unassigned" event; branch on the null.
Caveats
assigned_to_user_idis a team member's user id, an account with dashboard access, not the member'ssubscriber_id. The two are different namespaces.- Assignment is advisory. It does not restrict who may reply; anyone on the team with
support-conversation:updatestill can. - Re-assigning to the same person fires the event again. Deduplicate on
idif you are posting notifications.
Related events
support.conversation.resolved: the usual next step once the assignee has answered.support.message.received: what typically prompts an assignment.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
A support conversation is marked resolved and leaves the open queue.
When this fires
A conversation is marked resolved from the dashboard inbox, the REST API, Zapier, n8n, or the resolve_support_conversation MCP tool.
Resolving is not closing. The thread and its full history are kept, and it reopens by itself the moment the member writes again, which raises
support.conversation.reopened.
Caveats
- Resolving does not notify the member. If you want them to know the matter is closed, send a reply before resolving.
- The event fires even if the conversation was already resolved. Deduplicate on
id. - A resolved conversation still counts toward the member's history and still appears under the Resolved tab in the inbox; it is filtered out of the open queue, not deleted.
Related events
support.conversation.reopened: what happens when the member writes back.support.message.sent: the reply that usually precedes resolving.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
A resolved support conversation becomes active again.
When this fires
A conversation that was resolved goes back to open. Two paths:
- The member writes again. Their inbound message reopens the thread automatically, raising this event alongside
support.message.received. This is the usual cause. - A creator reopens it explicitly: from the dashboard inbox, with
POST /v1/support/conversations/{id}/reopen, with thereopen_support_conversationMCP tool, or through the Reopen Support Conversation action in Zapier and n8n.
It does not fire when:
- The member writes into a thread that is already
open,pendingorsnoozed. Only a resolved thread reopens on inbound. A creator reopening a thread by hand fires the event whatever the thread's previous status was, includingopen. - The member is blocked. A blocked contact's message is dropped and cannot push their thread back into the queue.
- The member edited an older message rather than sending a new one.
The common path here is not a creator reopening a thread by hand; it is a member writing back after you resolved it. If you page an on-call rota on anything in this family, this is the event that catches the "we thought this was done" case.
Caveats
- On the member-writes-back path this event and
support.message.receivedfire for the same action. If you post to a channel on both, you will post twice; pick one as the trigger and enrich from the API. - The payload does not say which path caused the reopen. Compare the newest message's
directionover the API if it matters:inboundmeans the member came back,outboundor no new message means a creator reopened it by hand. first_response_atis not reset by a reopen. It is stamped once, for the first human reply ever in that thread, so SLA reporting across a reopen needs message timestamps rather than that field.
Related events
support.conversation.resolved: the state this event reverses.support.message.received: fires alongside on the member-writes-back path.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
support.conversation.blocked
WEBHOOKA creator silences a member's support messages.
When this fires
A creator blocks the member behind a support conversation:
- Dashboard: Block member in the thread's header menu in the support inbox.
- REST:
POST /v1/support/conversations/{conversation}/block. - MCP: the
block_support_contacttool.
It does not fire when:
- The conversation is already blocked. Blocking twice writes nothing the second time and emits nothing; the call is idempotent.
- A member is banned from the project. That is
member.banned, a different mechanism that removes access rather than silencing a thread. - The member's message is dropped because of rate limiting. Flood protection is automatic and raises no event.
A block lives on the conversation, not the member. It silences their support traffic only: the member keeps their subscription, their access and every other interaction with the bot, and they are given no indication that anything changed.
Caveats
- Blocking does not resolve the thread. Its
statusis whatever it was (open,pending,snoozedorresolved) and stays that way until someone changes it. If you keep a queue in sync, treat a blocked thread as one that will receive no new inbound messages, not as a closed one. - From this moment the member's messages are dropped at ingestion. No
support.message.receivedfires for them, and a blocked member's message cannot reopen a resolved thread, so nosupport.conversation.reopenedfires either. - The block is scoped to this thread. There is one conversation per member per channel, so a member who also writes in over another channel has a separate thread with its own block state.
- The member's history is untouched. Every message they sent before the block stays readable over the API and in the dashboard.
Related events
support.conversation.unblocked: the block is lifted.support.message.received: what stops arriving for this member while the block is in place.member.banned: removing a member's access, which is not what a block does.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
A creator lets a silenced member's support messages through again.
When this fires
A creator lifts the block on a support conversation:
- Dashboard: Unblock member in the thread's header menu in the support inbox.
- REST:
POST /v1/support/conversations/{conversation}/unblock. - MCP: the
unblock_support_contacttool.
It does not fire when:
- The conversation was not blocked. Unblocking an unblocked thread writes nothing and emits nothing; the call is idempotent.
- A banned member is unbanned. That is
member.unbanned; a ban and a support block are independent, and lifting one does not touch the other.
Unblocking restores the flow of new messages. It does not replay anything the member sent while blocked; those messages were dropped at ingestion and are gone.
Caveats
- The thread's
statusis unchanged by an unblock, exactly as it was by the block. A thread that wasresolvedwhen blocked is stillresolvednow; the member's next message will reopen it and raisesupport.conversation.reopenedas usual. - Nothing is replayed. If the member wrote in while blocked, those messages produced no
support.message.receivedand never will. - The payload does not say how long the block lasted. Pair this event's
created_atwith the matchingsupport.conversation.blockedbyconversation_idif you report on it.
Related events
support.conversation.blocked: the state this event reverses.support.conversation.reopened: what the member's next message may now trigger.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
support.message.received
WEBHOOKA member sends a message into a support conversation.
When this fires
Every time a member sends an inbound message that lands in the support inbox, including the very first one, which also raises support.conversation.opened.
This is the workhorse of the family. If you are routing member questions into a helpdesk, an ops channel or an on-call rota, this is the event to subscribe to.
It does not fire when:
- The text was a recognised bot command, or an answer the bot was waiting for mid-setup.
- The member is blocked. Their messages are dropped without a trace in the inbox.
- The member has tripped the inbound rate limit. Excess messages are dropped silently rather than queued.
- The member edited an earlier message. The stored message is updated in place and no new event fires.
The message body is not in the payload. Webhook deliveries are logged and retried, and member text does not belong in a delivery log. Fetch it with the conversation messages endpoint.
Caveats
- No body, no name, no file ids. Everything human-readable is behind the API on purpose. Platform file ids are effectively credentials for downloading the file and are never sent in a webhook.
- An album (several photos sent together) arrives as one event per part, each with its own
message_id. They share amedia_group_idvisible through the API, not in the payload. - A captioned photo has
type: "photo", and the caption is the message body; it is not a separate text message. - A caption that starts with
/is parsed as a bot command upstream and never reaches the inbox.
Related events
support.conversation.opened: fires alongside on the member's first message.support.message.sent: your side of the exchange.support.conversation.reopened: fires alongside when the message revives a resolved thread.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
support.message.sent
WEBHOOKA reply to a member is recorded and queued for delivery.
When this fires
A creator or team member replies to a member, from any surface: the dashboard inbox, the relay DM on the connector, the REST API, or the reply_support_conversation MCP tool.
It does not fire when:
- The reply was recorded as an internal note. Notes are private remarks for your team, are never delivered to the member, and raise no event.
- An automated acknowledgement goes out. The project's auto-reply is a system message, not a creator reply.
This fires when the reply is recorded and queued, not when the member receives it. Delivery happens on a queue and can still fail; a member who has blocked the bot is unreachable. Read
delivery_statusfrom the support API for the outcome.
Caveats
- The payload does not say who replied. Read
author_user_idfrom the conversation messages endpoint if you need to attribute it to a specific team member. - The member sees the reply prefixed with the project's support name, so it reads as coming from a person rather than from the bot. That prefix is added at delivery and is not part of the stored body.
- Pairing this with
support.message.receivedgives you first-response time. The conversation's ownfirst_response_atis stamped only once, on the first human reply, which is the more reliable SLA measure.
Related events
support.message.received: the member's side.support.conversation.resolved: usually the next step after a reply.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
support.canned_reply.created
WEBHOOKA saved reply is added to a project's support inbox.
When this fires
A creator saves a new reusable reply on a project:
- Dashboard: Saved Replies → Add Reply from the support inbox.
- REST:
POST /v1/projects/{project}/support/canned-replies. - MCP: the
create_canned_replytool.
It does not fire when:
- A saved reply is inserted into a conversation. Using a snippet is just composing a message; the reply that goes out raises
support.message.sentlike any other. - The save is rejected. A duplicate
shortcuton the same project, or a body outside its limits, fails validation and writes nothing.
The dashboard calls these Saved Replies; the event keeps the
canned_replyname. The snapshot carries the snippet's title, shortcut and position but never its body. Fetch that with the canned reply endpoint if you mirror the picker somewhere else.
Caveats
- The
bodyis the one thing a consumer usually wants and the one thing not sent. This matches the family rule that nosupport.*payload carries message text; read it over the API. shortcutis unique per project, so it doubles as a stable handle for the snippet in a mirror, but it is optional and editable, so key onid.sort_orderis not a dense sequence. Several snippets can share a value; the dashboard orders ties by creation.
Related events
support.canned_reply.updated: the snippet is reworded, given a new shortcut or moved.support.canned_reply.deleted: the snippet is removed from the picker.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
support.canned_reply.updated
WEBHOOKA saved reply's title, body, shortcut or position changes.
When this fires
A creator edits an existing saved reply and at least one of title, body, shortcut or sort_order is different afterwards:
- Dashboard: Saved Replies → edit → Update Reply from the support inbox.
- REST:
PATCH /v1/projects/{project}/support/canned-replies/{reply}. Fields you omit keep their stored value. - MCP: the
update_canned_replytool.
It does not fire when:
- Nothing changed. The action compares before and after and skips the event when the two match.
- The snippet is inserted into a conversation. Using a saved reply is composing a message, and the message raises
support.message.sent. - The edit is rejected (a
shortcutalready used by another snippet on the project, or a body outside its 2–4000 character limits): nothing is written.
One save is one event, and
changeslists only the fields that actually differ. A save that changes nothing (the dashboard's Update Reply with no edits, or aPATCHthat re-sends the stored values) emits nothing.
Caveats
- The snapshot never carries the body, but
changes.bodydoes when the body is what changed:fromandtohold the full old and new text. This is the creator's own template text, not a member's message, so the family's rule that member text never enters a delivery log still holds. If you would rather not receive it, it only appears on edits to the body itself. changescan reportbody, which the snapshot omits, and the snapshot carriesid, whichchangesnever does. Use both halves:canned_replyfor the current state,changesfor what to diff.- Reordering snippets in the dashboard can raise one event per snippet whose
sort_ordermoved. Expect a burst withchanges: { sort_order: … }and nothing else.
Related events
support.canned_reply.created: the snippet's first appearance.support.canned_reply.deleted: its removal.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
support.canned_reply.deleted
WEBHOOKA saved reply is removed from a project's support inbox.
When this fires
A creator removes a saved reply from a project:
- Dashboard: the delete action on a snippet under Saved Replies in the support inbox.
- REST:
DELETE /v1/projects/{project}/support/canned-replies/{reply}. - MCP: the
delete_canned_replytool.
It does not fire when:
- The snippet was already gone. A second delete writes nothing and emits nothing.
- A message composed from the snippet is deleted or edited in a conversation. The saved reply is a template; what was sent is a separate message with its own lifecycle.
- The project itself is deleted. Its snippets go with it under
project.deletedwithout a per-snippet event.
This is the final event for the given
canned_reply.id. The snapshot is taken just before the row goes, so the payload still names what disappeared even though the canned reply endpoint now returns404.
Caveats
- The body is gone with the row and was never in any event, so a mirror that wants to keep the text must have fetched it while the snippet existed.
- The freed
shortcutcan be reused by a new snippet straight away. Key a mirror onid, not on the shortcut. - Remaining snippets are not renumbered. Their
sort_ordervalues are unchanged and noupdatedevents follow a delete.
Related events
support.canned_reply.created: the snippet's first appearance.support.canned_reply.updated: edits between creation and this event.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
support.settings.updated
WEBHOOKA project's support inbox settings change.
When this fires
A creator saves the project's support settings and at least one of the five visible settings is different afterwards:
- Dashboard: Support Settings → Save from the support inbox.
- REST:
PATCH /v1/projects/{project}/support/settings. Fields you omit keep their stored value. - MCP: the
update_support_settingstool.
It does not fire when:
- Nothing changed. Saving the form untouched, or a
PATCHthat re-sends the stored values, writes nothing and emits nothing. Blank strings normalise tonullbefore the comparison, so clearing an already-emptyagent_nameis not a change. - The bot links or unlinks the relay chat. That handshake changes the relay chat id, which is not one of the five settings this event covers.
- A member's message is auto-acknowledged. Sending the
auto_replytext is a message, not a settings change, and raises nothing in this family.
The relay chat id (the chat or forum group the bot forwards member messages to) is never in this payload. It is an identifier the bot's linking handshake writes, not a setting a creator types, and no surface can change it through this path.
Caveats
- Subscribing needs
support-conversation:view, but making the change needs the project update permission (project:updateon a token), because the settings are columns on the project rather than on the inbox. A token that can read support threads can hear about settings changes it could not have made. settingsis always the full post-save state, even when only one key changed. You can overwrite a cached copy wholesale and usechangespurely for "what to announce".auto_replyis creator-authored template text and does appear in bothsettingsandchanges; it is the message members receive, not a message a member sent, so the family's rule about member text is intact.- Switching
relay_modetoforum_groupdoes not by itself link a group. The project bot links a group when the creator adds it to a supergroup with Topics enabled as an administrator, and confirms by DM; until that happens, notifications have nowhere to go and member messages reach only the dashboard inbox.
Related events
support.conversation.opened: the traffic these settings govern.project.updated: other project-level edits, which never include the support columns.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
Related
How is this guide?