X-MyAIChatbot-Event header or the body’s event field — they always match.
Every payload carries
api_version (currently "2026-07-01") and a true/false test.
message.created
The main event. A visitor, member, or operator said something.widget, public_page, or internal.bot or taken_over. Once it is taken_over, you cannot post into this conversation.Answers the visitor gave before the chat started, keyed by field name. Empty if you collect none.
A per-conversation counter that only goes up. Sort by this, not by arrival time.
visitor, member, bot, operator, or system.The blocks flattened into plain text. Handy, and usually all you need.
Where to POST your reply.
null if the platform is set up wrong.interaction.button_clicked
A flat payload withaction_id, value, and label at the top level. See Interactions for the full details.
event and type carry the same dotted name. type is there for tools that cannot map nested fields.interaction.form_submitted
form_id is the form’s id — the one you set, or the one we made if you left it out. See Interactions for how values are typed.conversation.handoff
An operator took over and pressed Send transcript to backend. It exists so your CRM can catch up. There is noresponse_url — on purpose, because the bot cannot speak in a conversation a human now owns.
Every message from
slice_from on — the human era only, flattened to plain text.event_id, so compare slice_from and slice_to.
webhook.verify
Sent when you press Verify. Send thechallenge back. Never retried, and has no response_url. See Webhooks.
webhook.test
Sent by the Test webhook button. Shaped just likemessage.created so your real handler runs, but with a fake conversation, test: true, and no response_url.

