Webhook event format
This reference describes public events for project webhooks and application webhooks. Their JSON has the same structure. A project webhook receives selected events from its own project; an application webhook receives events from projects with an active installation of that application. Use project_id to identify the project.
Common structure
Senler sends a POST request with Content-Type: application/json. This complete segment subscription example uses Standard Webhooks; the identifiers and time are illustrative:
{
"event_id": "019e8e31-7e00-7000-8000-000000000001",
"event_type": "segment_subscribed",
"timestamp": "2026-10-15T12:00:00.000Z",
"project_id": "11111111-1111-4111-8111-111111111111",
"channel_id": "22222222-2222-4222-8222-222222222222",
"channel_type": "tg",
"lead_id": "000000000000000000000001",
"dialog_id": null,
"platform_user_id": "123456789",
"data": {
"segment_id": "000000000000000000000002",
"source": "manual",
"reason": "manual",
"occurred_at": "2026-10-15T12:00:00.000Z"
}
}
The common fields are present in every production event:
event_id— a string event ID, preserved on redelivery. Treat it as an opaque identifier: its format is not limited to UUID.event_type— a string containing one of the 12 types below. Use it to select the handler fordata.timestamp— an ISO 8601 time. Standard Webhooks preserves the original body timestamp; the current attempt time is inwebhook-timestamp. Senler Webhook Standard updatestimestampwhen sending, matchingX-Webhook-Timestamp.project_id— a string project ID.channel_id,lead_id,dialog_id— string IDs of the corresponding Senler objects, ornullwhen the context is unavailable.channel_type—vk,tg,max,discord,widget,streamvi,email,avito, ornull. Telegram usestg.platform_user_id— a string user ID on the external platform, ornull. This is a separate identifier from the Senlerlead_id.data— an object containing fields specific to the event type. Its fields and short examples are listed below.
Verify the application signature or project webhook signature before processing the JSON. The signature format is selected in the sender settings. Do not require non-null channel or dialog identifiers for an event without that context.
Messages and buttons
command_start
Sent for an incoming /start command message, and when a dialog starts with a supplied start parameter.
Required data fields: command is the string start; args is a string containing the start parameter, empty when no parameter is supplied.
{"command": "start", "args": "campaign_42"}
A /start campaign_42 message received from a lead produces both command_start and message_new. A recipient subscribed to both types receives two events with different event_id values. They are independent events; redelivery of either event preserves that event's ID.
message_new
Sent when an incoming lead message with a string content field is created. Agent and operator messages do not produce this type.
The required data.content field is a string containing the message content; it can be empty. The data object does not contain the full message record or an attachment list.
{"content": "I would like to book a consultation"}
button_clicked
Sent when a button click includes callback data. Following an ordinary URL does not by itself guarantee this event.
callback_data— a required non-empty string containing the button data.button_text— the button text, when available.callback_id— the callback identifier, when supplied by the platform.message_id— the message identifier, when available in the click event.
The last three fields are optional for processing: allow a missing value or null; an available value is a string.
{"callback_data": "confirm_order", "button_text": "Confirm", "callback_id": "callback-123", "message_id": "456"}
Message permission and leads
The following four types share the same data fields. Both fields are present and allow null:
key— a string key from the action context, when provided. This is not a lead or segment ID.error_message— a string message from the event context, when available. The presence of this field does not mean that an ordinary subscription or lead creation event failed.
A typical example without additional context:
{"key": null, "error_message": null}
message_allow
The user allowed messages, and Senler received the corresponding message subscription event. A segment subscription uses the separate segment_subscribed type.
lead_created
A lead was created in the project. Its ID is in the common lead_id field; the full lead record is not included in data.
lead_unsubscribed
The lead unsubscribed from messages. Leaving an individual segment is sent as segment_unsubscribed.
lead_blocked
The user blocking the bot was recorded. This event has the same key and error_message data fields.
Segment events
Both events represent an actual, saved membership change. A webhook receives changes for all segments in the project available to it; identify the segment by data.segment_id. A production event has a populated lead_id. Channel and dialog context can be null.
segment_subscribed
The lead became a segment member. When user consent is required, the event arrives after confirmation. Resubscribing a lead who is already in the segment does not create a new event. Subscribing after an unsubscription creates a new event with a new ID.
See the complete example in Common structure.
segment_unsubscribed
The lead stopped being a segment member. Cancelling a subscription that has not yet been confirmed does not create an unsubscription. The common structure is the same as for subscription, with event_type set to segment_unsubscribed.
Example data after VK message permission is revoked:
{
"segment_id": "000000000000000000000002",
"source": "vk_messages",
"reason": "channel_access_revoked",
"occurred_at": "2026-10-15T13:00:00.000Z"
}
data fields
All four fields are required and non-null:
segment_id— a string Senler segment ID, not its name or short public link code.source— a string indicating where the action came from, such as a Telegram bot, the cabinet, or an automation.reason— a string indicating what caused the change, such as a direct link or loss of channel access.occurred_at— the ISO 8601 time of the membership change itself. It is preserved on redelivery with either signature format.
source and reason describe different aspects of the action. For example, source: "tg_bot" and reason: "direct_link" mean a subscription through a Telegram bot using a direct link. Both fields are manual for a manual change.
source values
vk_app— a VK application.vk_messages— VK messages.tg_bot— a Telegram bot.tg_app— a Telegram application.max_bot— a MAX bot.max_app— a MAX application.web— a web page.manual— a manual action.auto_assignment— automatic segment assignment.automation— an automation.ai_agent— an AI agent action.trigger— a trigger action.
reason values
landing— subscription through a landing page.direct_link— following a direct subscription link.keyword— a keyword match.all_messages— a subscription rule based on incoming messages.manual— a manual membership change.channel_access_revoked— automatic unsubscription after VK message permission is revoked; applies to subscriptions associated with that channel.automation— a change made by an automation.ai_agent— a change made by an AI agent action.trigger— a change made by a trigger action.
Failure events
error
An agent execution failure, such as an AI timeout or insufficient balance. Its data fields are described below together with message_undelivered.
message_undelivered
Sending a message from an agent, automation, or operator failed. This describes message sending, not a failure of the HTTP request carrying the webhook itself.
For error and message_undelivered, all listed data fields are present; their values have type string | null:
key— an additional key from the action context.error_code— an error code for programmatic handling.error_message— the reason text, when available.error_message_key— a localization key for the error message.agent_id— the agent ID.sender_type,sender_id— the sender type and ID; example types includeassistant,user, andautomation.message_event_id— the outgoing message ID formessage_undelivered;nullforerror.response_id— the agent response ID.automation_id,version_id,run_id,task_id,node_id— the available automation context.
Example data for message_undelivered; the error code is illustrative:
{
"key": null,
"error_code": "delivery_failed",
"error_message": "Message could not be sent",
"error_message_key": null,
"agent_id": null,
"sender_type": "automation",
"sender_id": null,
"message_event_id": "message-event-id",
"response_id": null,
"automation_id": "000000000000000000000003",
"version_id": "000000000000000000000004",
"run_id": "000000000000000000000005",
"task_id": "000000000000000000000006",
"node_id": "send-message"
}
automation_step_failed
An automation step failed permanently: retries are exhausted or unavailable for this error. An intermediate failed attempt, a test run, or an HTTP step following a connected Error branch does not produce this event.
All listed data fields are present:
automation_id,version_id,run_id,task_id,node_id— required strings identifying the automation and execution.node_name— the captured step name, a string ornull.message_event_id— the outgoing message ID, a string ornull.error_code,error_message— required strings containing the error code and reason.occurred_at— the ISO 8601 time of the terminal failure.retryable— alwaysfalse: this is a terminal failure of the current task.
{
"automation_id": "000000000000000000000003",
"version_id": "000000000000000000000004",
"run_id": "000000000000000000000005",
"task_id": "000000000000000000000006",
"node_id": "send-message",
"node_name": "Send message",
"message_event_id": "message-event-id",
"error_code": "delivery_failed",
"error_message": "Message could not be sent",
"occurred_at": "2026-10-15T13:00:00.000Z",
"retryable": false
}
The example IDs and error code are illustrative. This type has null for the common channel_type and platform_user_id fields even when channel_id is known. See Failure events for event selection and how the events relate to each other.
Processing and test requests
Store processed event_id values and do not process an accepted event again. Different event types describing one action can have different IDs: for example, command_start and message_new, or message_undelivered and automation_step_failed. Return 2xx after reliably accepting the event, including a redelivery.
A project webhook test sends the selected event_type and test: true; lead, channel, and dialog IDs are null, and the data is synthetic. Without a selected type, it sends event_type: "test". An application webhook test uses the service type test. Test data can be shorter than the production examples above; handle it separately without taking actions on real customers.
Other call types
tool_call: HTTP tools — a separate contract with tool arguments, configuration, and results.automation_step: application steps — a separate contract for step execution and completion.- Delivery history and retries — troubleshooting event receipt by the application.
tool_call and automation_step are not selectable in the list of 12 public events; their calls are configured in the corresponding tools and steps.