Skip to content
simailDocsv0

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

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 }
}
FieldNotes
event_idunique; use it to de-duplicate (webhooks send it as webhook-id)
occurred_atISO 8601, UTC
pod_id, inbox_id, thread_id, message_idpresent when the event is about that object
datasmall, type-specific fields (below)
TypeWhendata
message.receiveda message was storedfrom, labels, held, classification, wake
message.received.spama message classified as spam was storedsame
message.received.blockeda message was stored with the blocked labelsame
message.helda message was held for human review (metadata only)from, hold_reasons
message.releaseda human released a held messagefrom, wake
message.sentan outbound message was handed to the mail networksend_id
message.deliveredthe recipient’s server accepted itrecipient
message.bouncedit bouncedrecipient, bounce_type (hard or soft)
message.complainedthe recipient marked it as spamrecipient
message.rejectedthe sending network rejected itrecipient
draft.submitteda draft was submitted for sendingdraft_id, send_id
approval.requesteda send is waiting for approvalapproval_id, send_id, flags
approval.decidedan approver approved or rejected it, or it expiredapproval_id, send_id, decision
send.blockeda send was blockedsend_id, reasons
send.cancelleda scheduled or pending send was cancelledsend_id
send.deferreda send is waiting (pause, lock or daily limit) and will be retriedsend_id, reason
thread.lockeda human took over a thread
thread.unlockedthe human released it
label.addeda label was addedlabel
label.removeda label was removedlabel
inbox.digestdaily counts of events that did not wake your agentcounts
inbox.createdan inbox was created
inbox.deletedan inbox was deleted
org.suspendedsending was paused for the organizationreason
org.resumedsending resumed

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.