Reference
Event types
Every simail event type, the thin payload shared by polling, webhooks and WebSocket, and which events wake your agent.
docs.simail.ai/event-types
Payload
Section titled “Payload”Payloads are thin and identical on every channel (polling, webhooks, WebSocket). They never include the subject, body or attachment names; fetch the message with your key when you need content (held messages stay metadata-only).
{ "event_id": "evt_…", "event_type": "message.received", "occurred_at": "2026-10-18T17:02:12Z", "organization_id": "org_…", "pod_id": "pod_…", "inbox_id": "shop-helper@simail.email", "thread_id": "thr_…", "message_id": "msg_…", "data": { "from": "ada@example.com", "labels": ["received", "unread"], "held": false, "classification": "normal", "wake": true }}| Field | Notes |
|---|---|
event_id | unique; use it to de-duplicate (webhooks send it as webhook-id) |
occurred_at | ISO 8601, UTC |
pod_id, inbox_id, thread_id, message_id | present when the event is about that object |
data | small, type-specific fields (below) |
| Type | When | data |
|---|---|---|
message.received | a message was stored | from, labels, held, classification, wake |
message.received.spam | a message classified as spam was stored | same |
message.received.blocked | a message was stored with the blocked label | same |
message.held | a message was held for human review (metadata only) | from, hold_reasons |
message.released | a human released a held message | from, wake |
message.sent | an outbound message was handed to the mail network | send_id |
message.delivered | the recipient’s server accepted it | recipient |
message.bounced | it bounced | recipient, bounce_type (hard or soft) |
message.complained | the recipient marked it as spam | recipient |
message.rejected | the sending network rejected it | recipient |
draft.submitted | a draft was submitted for sending | draft_id, send_id |
approval.requested | a send is waiting for approval | approval_id, send_id, flags |
approval.decided | an approver approved or rejected it, or it expired | approval_id, send_id, decision |
send.blocked | a send was blocked | send_id, reasons |
send.cancelled | a scheduled or pending send was cancelled | send_id |
send.deferred | a send is waiting (pause, lock or daily limit) and will be retried | send_id, reason |
thread.locked | a human took over a thread | |
thread.unlocked | the human released it | |
label.added | a label was added | label |
label.removed | a label was removed | label |
inbox.digest | daily counts of events that did not wake your agent | counts |
inbox.created | an inbox was created | |
inbox.deleted | an inbox was deleted | |
org.suspended | sending was paused for the organization | reason |
org.resumed | sending resumed |
Waking your agent
Section titled “Waking your agent”Every message.received (and message.released) event has data.wake. It is true when the
message belongs to a thread you are part of, comes from a contact of the inbox, or matches your
receive allow list. Mail from strangers wakes your agent only up to a budget per inbox per day
(inbound.wake.stranger_daily, 50 by default) and per sender per hour (inbound.wake.per_sender_hourly,
5 by default). Beyond that, events are still stored and returned by GET /v0/events, but webhooks and
WebSocket skip them unless the subscription sets include_non_wake: true. A daily inbox.digest
event reports what was skipped. Held mail never wakes.
This keeps a flood of mail from turning into a flood of model calls.