Skip to main content

Webhook events

Ha Tang sends one HTTP POST per event to each webhook endpoint subscribed to it. The body is always the same envelope; data depends on the event. Each event below links to its full payload schema and an example.

Envelope​

{
"type": "email.delivered",
"created_at": "2026-10-23T08:15:00.000Z",
"data": {
"email_id": "4ef9a417-02e9-4d39-ad75-9611e0fcc33c",
"from": "Shop <[email protected]>",
"to": [
],
"subject": "Your order",
"created_at": "2026-10-23T08:14:58.000Z"
}
}

Headers​

HeaderMeaning
svix-id / webhook-idUnique id of the delivery. The same id is reused for retries and replays: de-duplicate on it.
svix-timestamp / webhook-timestampUnix seconds when the delivery was signed. Reject anything more than 5 minutes off.
svix-signature / webhook-signaturev1,<base64> signatures, space-separated (two during a secret rotation).

Answer with any 2xx within 15 seconds. Other answers and timeouts are retried after 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours and 10 hours. You can replay any delivery from the dashboard or with POST /webhooks/deliveries/{id}/replay.

Set-up, signature verification code and testing are in the Webhooks guide.

Email events​

EventWhen it fires
email.sentThe email was accepted by the sending infrastructure.
email.deliveredThe recipient's mail server accepted the email.
email.delivery_delayedDelivery is being retried (for example the recipient's server is temporarily refusing mail).
email.bouncedThe email bounced. data.bounce.type is Permanent (the address is suppressed) or Transient.
email.complainedThe recipient marked the email as spam. The address is suppressed.
email.openedThe recipient opened the email (open tracking on). Fired once per open.
email.clickedThe recipient clicked a tracked link. data.click.link is the original URL.
email.failedThe email could not be sent. data.failed.reason says why.
email.receivedAn email arrived at one of your receiving domains. Fetch the body and attachments with the Receiving API.
contact.createdA contact was added (API, dashboard, import or CRM sync).
contact.updatedA contact's name, properties or subscription changed.
contact.deletedA contact was deleted.
domain.createdA sending domain was added.
domain.updatedA domain changed, including its verification status.
domain.deletedA domain was removed.

Support events​

EventWhen it fires
chat.conversation.createdA new conversation started on any channel.
chat.conversation.assignedA conversation was assigned (or unassigned).
chat.conversation.resolvedA conversation was marked resolved.
chat.conversation.closedA conversation was closed.
chat.conversation.reopenedA resolved or closed conversation was reopened.
chat.conversation.handoffThe AI assistant handed the conversation to your team.
chat.conversation.taggedA tag was added to a conversation; one event per added tag.
chat.message.createdA public message was posted by the customer, an agent, the AI assistant or a flow. Internal notes do not fire it.
chat.visitor.identifiedA visitor was identified (identify from the widget or an SDK).
chat.order.createdAn order was created from the inbox or the API.
chat.order.updatedAn order changed (status, items, shipping).
chat.order.paidAn order was paid.
chat.flow.webhookA flow or workflow reached a Webhook step.
chat.campaign.leadA visitor submitted a lead form.
chat.ticket.createdA support ticket was created.
chat.ticket.updatedA ticket changed.
chat.ticket.resolvedA ticket was resolved.
chat.ticket.breachedA ticket missed an SLA target. clock says which one.
chat.rating.createdA customer rated a conversation (CSAT).
chat.zns.sentA Zalo ZNS message was delivered to Zalo.
chat.zns.failedA Zalo ZNS message failed. error has the reason.

Payments events​

EventWhen it fires
payment.createdA payment request was created.
payment.succeededThe full amount arrived.
payment.partially_paidLess than the full amount arrived.
payment.overpaidMore than the requested amount arrived.
payment.expiredThe payment expired before it was paid.
payment.canceledThe payment was canceled.
transaction.receivedMoney arrived in a linked bank account (matched or not).
bank_connection.activatedA bank account was linked and confirmed.
bank_connection.revokedA bank link was removed.
bank_connection.needs_reauthThe bank needs the account holder to confirm the link again.
invoice.draft_createdA draft e-invoice was created.
invoice.draft_updatedA draft e-invoice changed.
invoice.draft_deletedA draft e-invoice was deleted.
invoice.issuedAn e-invoice was issued by the provider.
invoice.tax_acceptedThe tax authority accepted the e-invoice.
invoice.tax_rejectedThe tax authority rejected the e-invoice.
invoice.canceledAn e-invoice was canceled.
invoice.replacedAn e-invoice was replaced by a new one.
invoice.adjustedAn adjustment invoice was issued.
invoice.failedIssuing an e-invoice failed.
invoice.conflictThe invoice changed on the provider's side and conflicts with Ha Tang's copy.

View this page as Markdown