POST, with metadata (event type, delivery id, signature) in headers. See Overview for the delivery shape and Signing for verification.
Webhook payloads use
camelCase field names. This differs from the REST
API’s snake_case responses — historical and not worth breaking compatibility
over. Within each side, the convention is consistent.Chatbots
chatbot.created
Fires when a chatbot is created via dashboard or POST /chatbots.
chatbot.updated
Fires on any mutation of a chatbot’s configuration — name, status, system prompt, attached pages, etc.
chatbot.deleted
Fires when a chatbot is hard-deleted.
Conversations
conversation.created
Fires when an end-user starts a new conversation with a chatbot. The bot has been provisioned but no user messages have been sent yet.
qrCodeId / productId / objectId reflect the entry surface — null if the conversation didn’t originate from a scan.
conversation.updated
Fires when any conversation field changes: status, priority, title, contact info, assignment. Payload includes the new state and a changes object describing the diff.
message.created
Fires for every new message in a conversation — user, assistant, system. System messages include an event field describing what triggered them (status change, human takeover, conversation reopen).
role is one of user, assistant, system. For assistant messages, source is "bot", "human", or "api" (when delivered via POST /conversations/{id}/messages). For user messages, source is "email" when the message arrived via inbound email reply, otherwise absent.
Messages with attachments
When the message carries image attachments,message.attachments is included. The field is omitted entirely when there are none — don’t expect an empty array.
string (uuid)
required
Stable identifier for the underlying bytes in the org’s asset library.
Re-attaching the same image to a different message returns the same
assetId.
Treat as opaque.string
required
Public URL to fetch the image. Long-lived — content-addressed paths never
expire and are immutable.
string
required
MIME type as detected by Awardee’s pipeline. May differ from the original
upload if the asset was re-encoded by the compression step (e.g.
image/png →
image/webp).string
required
Human-readable filename, used as
<img alt> text. May fall back to a generic name (upload, image.png) when the source had no filename (paste from clipboard, inline email image).URLs are content-addressed within an organization. Attaching the same
image bytes to two different messages — even in different conversations —
produces the same
url and assetId. Don’t dedupe webhook events by
attachment URL; use message.id for message-level idempotency.Submissions
page.submission.created
Fires when an end-user submits a form attached to a page.
submission.updated
Fires on any mutation of a submission — status, priority, flag, assignment, notes.
QR codes
qr_code.scanned
Fires on every scan of a tracked QR code, including from misconfigured codes and scans that resolve to “not found”.
qr_code.updated
Fires on any mutation — destination changes, name, description, properties, URL params, status.
Payloads include article_ids and category_ids (the QR code’s linked knowledge). A PATCH that changes only those still fires qr_code.updated.
QR groups
qr_group.created / qr_group.updated
qr_group.updated also fires when the group’s properties are replaced (PUT /qr-groups/{id}/properties), so you can resync without polling.
Payloads include article_ids and category_ids (the group’s linked knowledge). A PATCH that changes only those still fires qr_group.updated.
qr_group.deleted
Products
product.scanned
Fires when a GS1 Digital Link URL resolves to one of your products.
product.created / product.updated
Payloads include article_ids and category_ids (the product’s linked knowledge). A PATCH that changes only those still fires product.updated.
product.deleted
Objects
Programmable scan URLs that aren’t QR codes or products — custom-typed entities you mint and resolve under/o/<slug>.
object.scanned
object.created / object.updated
Payloads include article_ids and category_ids (the object’s linked knowledge). A PATCH that changes only those still fires object.updated.
object.deleted
The slug stays permanently reserved so analytics rows keep their references — it will never be reassigned to a new object.
Articles
article.created / article.updated
article.published
Fires when an article transitions from draft to published (and on first publish of a translation).
article.unpublished
Fires when an article transitions back to draft / unpublished / archived.
article.deleted
article.indexed
Fires when the embedding pipeline finishes writing chunks for an article (primary language + every translation). The article is now retrievable via chatbot search.
language is the article’s primary language; languages lists every language that was embedded in this run (primary + each translation that had content).
article.indexing_failed
Fires when the embedding pipeline errors out for an article. indexing_status on the article is set to failed and the error string travels in this payload (it isn’t exposed via the public API).
Article categories
article_category.created / article_category.updated
article_category.deleted
A cascade delete of a non-empty category also emits one article.deleted per child article.
Members
member.invited
Fires when an org owner sends an invite.
member.joined
Fires when an invited user accepts and is added to the org.
member.removed
Fires when a member is removed from the org, or when the org is deleted (one event per remaining member).
reason is one of "removed", "org_deleted", "left".
Customers
customer.created
Fires when a new identified customer is created — one carrying a strong key (email, phone, or external_id). Anonymous visitors (resolved by visitor hash only) and name-only leads do not trigger this event, so you only hear about real people. Created via the identify/upsert endpoint, a human attaching a contact in the inbox, or a form submission that supplies an email.
customer.updated
Fires when an identified customer’s editable fields change — name, email, phone, external id, or custom attributes — whether edited from the dashboard, the conversation inbox, or PATCH /customers/{id}. The payload is the full current customer in the same shape as customer.created.

