Webhook events
Every event Mailyte will send to your endpoint, what it means, and whether it needs you to do anything.
Registering an endpoint, verifying signatures and surviving retries are covered in Receiving webhooks. This page is the catalogue.
The envelope
Every delivery has the same outer shape. Payload fields are snake_case throughout.
{
"id": "01JBT8XQ2M9WYC3K4F6R7S8T9V",
"event": "email.bounced",
"created_at": "2026-09-17T10:04:11.000000Z",
"account": {
"organization_id": "01JBT8XQ2M9WYC3K4F6R7S8T9W"
},
"data": {
"message_id": "<01JBT8XQ2M@yourdomain.com>",
"recipient": "ada@example.com",
"domain": "yourdomain.com",
"dsn": "5.1.1",
"reason": "Mailbox does not exist",
"provider": "Gmail"
}
}id is stable across retries — key your idempotency on it. provider names the receiving platform where we can identify it, which makes "are we only bouncing at Microsoft" a question you can answer.
Events
email.acceptedinfoFires when We have taken the message and queued it for delivery.
What to do Nothing. It is a receipt, not an outcome.
email.submittedinfoFires when The message has been handed to the sending infrastructure.
What to do Nothing.
email.sentinfoFires when The message has left our network.
What to do Nothing — wait for email.delivered.
email.deliveredinfoFires when The receiving server accepted the message.
What to do Mark as sent. Note this means accepted by the server, not read by a person, and not necessarily in the inbox rather than the spam folder.
email.deferredwarningFires when Temporarily refused — greylisting, a full mailbox, rate limiting at their end. We will retry.
What to do Nothing. Sending again yourself puts two copies in flight and makes a temporary problem a reputation one.
email.bouncederrorFires when Permanently refused. No such mailbox, or the domain does not accept mail.
What to do Stop sending to this address. It is added to your suppression list automatically.
email.rejectederrorFires when The receiving server refused the message outright, often for policy or content reasons.
What to do Read the reason. Repeated rejections from one provider point at a content or authentication problem rather than a bad address.
email.droppederrorFires when We refused to send it — almost always because the recipient is suppressed.
What to do Check your suppression list. This event exists so a refused send leaves a trace instead of vanishing.
email.complainederrorFires when The recipient marked the message as spam.
What to do Treat as a permanent opt-out from everything, immediately. Complaints damage deliverability at volumes far below what most people expect.
delivery.complaintwarningFires when A feedback loop report arrived from a receiving provider.
What to do Same as a complaint: stop sending to that address.
spam.reportedwarningFires when Our own filtering classified an inbound message as spam.
What to do Only relevant if you are receiving mail through Mailyte.
email.inboundinfoFires when A message arrived at one of your mailboxes.
What to do Process it. This is the event to build an inbound pipeline on — it is distinct from email.delivered, which is about mail you sent.
tracking.openinfoFires when A tracking pixel in an HTML message was loaded.
What to do Treat with caution — see below.
tracking.clickinfoFires when A tracked link was followed.
What to do Treat with caution — see below.
tracking.unsubscribewarningFires when The recipient used an unsubscribe link.
What to do Honour it everywhere, not just in the campaign it came from. They are suppressed automatically.
queue.message.failederrorFires when A message could not be processed at all.
What to do Investigate. This is our side failing, not a recipient refusing.
storage.quota.warningwarningFires when A mailbox is approaching its quota.
What to do Raise the quota or prompt the holder to clear space, before mail starts bouncing.
storage.quota.exceedederrorFires when A mailbox is full and is refusing new mail.
What to do Raise the quota. Incoming mail is being rejected right now.
Inbound mail is its own event
Mail arriving at your mailboxes fires email.inbound. Mail you sent reaching its destination fires email.delivered.
They were once conflated, and inbound mail was emitted as email.delivered — which made a "received" count that sat at zero for ever while mail was plainly arriving. If you integrated against the old behaviour, this is the change to check.
Opens and clicks are unreliable
Not a limitation of our implementation — a limitation of the technique. Open tracking needs a remote image to load, and:
- privacy proxies fetch it on the recipient's behalf, sometimes for mail they never open;
- many clients block remote images, so a real open records nothing;
- security scanners follow links, producing clicks nobody made.
We have measured this here: a 30-day window once contained 499 opens and 36 clicks that were, on inspection, entirely our own infrastructure and no human at all.
Use them as a weak signal about a population. Never as evidence about a person.