Sign inGet started

Eventi email

Emettiamo eventi man mano che ogni destinatario avanza nella consegna. Un invio a tre indirizzi produce tre flussi indipendenti, correlati da email_id e recipient_id. Questa pagina definisce i tipi di evento email. Consulta Webhook per firme, ripetizioni, ordinamento e replay.
Ogni destinatario parte da email.accepted, poi email.processed. Un destinatario broadcast è un messaggio a sé, quindi riceve anche il proprio email.accepted, anche se solo negli eventi API e nel log email anziché come webhook. Da lì il messaggio viene accettato dal server ricevente (email.delivered), viene differito e riprovato (email.deferred, che si risolve in consegnato o rimbalzato), viene rifiutato dal server ricevente (email.bounced), oppure non riceve mai un tentativo di consegna (email.rejected). Dopo una consegna il flusso può proseguire con email.out_of_band_bounce, email.complained, email.opened, email.clicked, email.unsubscribed e email.list_unsubscribed.
Ogni destinatario termina in esattamente uno stato terminale, delivered, bounced, complained o rejected, restituito come status per destinatario da GET /v1/email/messages/{message_id}/recipients. Gli eventi di coinvolgimento non lo cambiano mai: un destinatario che ha aperto resta comunque delivered. Un bounce report tardivo invece lo cambia, perché il server ricevente sta ritrattando un'accettazione già data, quindi il destinatario passa da delivered a bounced. Il messaggio nel suo complesso ha un proprio stato aggregato e conteggi per stato su GET /v1/email/messages/{message_id}.

L'envelope dell'evento

Gli eventi arrivano come l'envelope a tre campi usato da ogni webhook: type, timestamp (quando l'evento si è verificato, RFC 3339) e un oggetto data specifico per tipo.
Esempio di codice
{
  "type": "email.delivered",
  "timestamp": "2026-07-23T14:51:47.107Z",
  "data": {
    "email_id": "em_01ky7qc398fmxraqtxn604zeq9",
    "recipient_id": "er_01ky7qc398fmwsc96nt6anrbqs",
    "workspace_id": "ws_01ky7m21hjffh9s8kq76gyb1xf",
    "recipient": "delivered@messagebird.dev",
    "recipient_role": "to",
    "tags": [{ "name": "category", "value": "welcome" }],
    "metadata": { "order_id": "ord_123" },
    "broadcast_id": null
  }
}
Ogni evento in uscita include email_id, recipient_id, workspace_id, l'indirizzo recipient e il suo envelope recipient_role (to, cc o bcc). Riporta inoltre tags e metadata dalla richiesta di invio, così puoi correlare l'evento con i tuoi record. Ogni valore opzionale è null quando l'invio non ne aveva, broadcast_id incluso: indica il broadcast di cui l'invio faceva parte, così puoi raggruppare gli eventi di un broadcast senza cercare ogni singolo invio, ed è null su un invio senza broadcast associato. Un caso riporta null per un invio che ne aveva uno: un link di disiscrizione da mail inviata prima dell'aggiunta del campo non indica alcun broadcast, quindi un opt-out tramite quel link riporta null su email.unsubscribed e email.list_unsubscribed indipendentemente dal fatto che un broadcast abbia inviato la mail. Tratta null su quei due eventi come non conclusivo, altrimenti sottostimi gli opt-out di un broadcast. broadcast_id ti raggiunge solo sul webhook: gli eventi API qui sotto restituiscono ogni evento senza di esso. I tipi di evento aggiungono campi descritti nelle sezioni ciclo di vita, coinvolgimento, soppressione e inbound.
Gli stessi eventi sono interrogabili a posteriori da GET /v1/email/messages/{message_id}/events, dove ciascuno ha anche un id (prefisso ev_) e un occurred_at. Usali per backfill, replay o riconciliazione rispetto a ciò che il tuo endpoint ha ricevuto. Alcuni campi ti raggiungono solo tramite quell'API anziché tramite il webhook; la descrizione dell'evento pertinente li identifica.

Eventi del ciclo di vita

email.accepted

Abbiamo accettato l'invio e iniziato a preparare la consegna. Si attiva una volta per destinatario richiesto ed è il primo evento di quel flusso. Anche un destinatario broadcast ne riceve uno, perché ogni destinatario è un messaggio a sé, ma viene registrato anziché consegnato: leggilo dagli eventi API o dall'email log, non dal tuo endpoint webhook. Payload: solo la base identità.

email.processed

Il messaggio è stato costruito e messo in coda per la consegna al mail server del destinatario. Payload: solo la base identità sul webhook; gli eventi API aggiungono mailbox_provider e mailbox_provider_region, la classificazione del sistema di posta ricevente (ad esempio gmail, NA), presente quando è stato possibile determinarla e null altrimenti. Confrontare il timestamp di questo evento con quello di email.accepted ti dà il nostro tempo di elaborazione su un singolo invio. Un broadcast non ha tale intervallo: la sua accettazione e la sua elaborazione condividono lo stesso istante di dispatch, quindi i due timestamp coincidono anziché delimitare un'elaborazione, e l'accettazione ti raggiunge solo tramite gli eventi API, come occurred_at.

email.delivered

Il mail server ricevente ha accettato il messaggio e se ne è preso la responsabilità. Questo evento non attesta il posizionamento in inbox né la lettura. Inbox Insights fornisce stime campionate di posizionamento; gli eventi di apertura e clic registrano le richieste di tracking. Payload: solo la base identità sul webhook; gli eventi API aggiungono sending_ip, l'indirizzo da cui il messaggio è stato inviato, utile quando un problema di deliverability riguarda un singolo IP, più mailbox_provider e mailbox_provider_region.

email.deferred

Un errore temporaneo: il server ricevente ha chiesto di riprovare più tardi (casella piena, greylisting, limitazione delle richieste). Riproviamo automaticamente, e il destinatario alla fine si risolve in email.delivered o email.bounced, quindi questo evento è informativo anziché terminale, e un destinatario può essere differito più volte prima. Payload: bounce_type, bounce_class, defer_reason (il motivo fornito dal server) e sending_ip sul webhook; gli eventi API aggiungono mailbox_provider e mailbox_provider_region.

Eventi di errore

email.bounced

Un errore permanente al momento di SMTP: il server ricevente ha rifiutato il messaggio e lo stato terminale del destinatario diventa bounced. Payload: bounce_type (vedi la tabella di classificazione), bounce_class, bounce_code (il codice di risposta SMTP, ad esempio 550), bounce_description (il motivo fornito dal server) e sending_ip sul webhook; gli eventi API aggiungono mailbox_provider e mailbox_provider_region. Un hard bounce sopprime l'indirizzo.

email.out_of_band_bounce

Un bounce tardivo: il server ricevente ha accettato il messaggio al momento di SMTP e poi ha inviato un bounce report successivamente. Ha la stessa classificazione di email.bounced (bounce_type, bounce_class, bounce_code, bounce_description, sending_ip sul webhook; mailbox_provider e mailbox_provider_region dagli eventi API). Quando il report viene classificato come bounce (qualsiasi classe nella tabella), il server ha ritrattato la sua accettazione precedente, quindi il destinatario passa da delivered a bounced. I report la cui classe non è nella tabella, come le risposte automatiche, vengono registrati nella timeline e non modificano lo stato. Un hard out-of-band bounce sopprime anch'esso l'indirizzo.

email.rejected

Il destinatario non ha mai raggiunto il mail server remoto, quindi non è stato tentato alcun recapito. Questo è ciò che distingue un rifiuto da un bounce, dove è il server ricevente a dire no. Payload: rejection_reason, anche nel record del destinatario, uno tra:
rejection_reasonSignificato
recipient_suppressedIl destinatario è bloccato a livello di spazio di lavoro, dalla lista di soppressione o da una preferenza dichiarata, quindi la consegna non è mai stata tentata
transmission_failedIl messaggio non è stato trasmesso per la consegna
generation_failureIl messaggio non è stato costruito per la consegna, un problema di template o contenuto
policy_rejectionLa policy di invio ha rifiutato il messaggio
domain_unverifiedIl dominio di invio non era verificato
quota_exceededLa quota di invio dell'organizzazione è stata raggiunta
recipient_not_allowedIl destinatario non era consentito per questo invio; gli invii su un dominio di onboarding condiviso raggiungono solo i membri verificati del tuo spazio di lavoro
Gli eventi API aggiungono anche mailbox_provider e mailbox_provider_region quando il sistema di posta ricevente è stato classificabile prima del rifiuto.

email.complained

Il destinatario ha contrassegnato il messaggio come spam e il provider di posta lo ha segnalato tramite il proprio feedback loop. I reclami arrivano dopo la consegna e impostano lo stato terminale a complained. Payload: feedback_type, il tipo di segnalazione inviata dal provider, come abuse o fraud, e null quando il provider non lo ha specificato, più mailbox_provider e mailbox_provider_region dagli eventi API. Un reclamo sopprime l'indirizzo per la mail di marketing. Mantieni basso il tasso di reclami: i provider limitano i mittenti che accumulano segnalazioni.

Eventi di coinvolgimento

email.opened

Il pixel di tracking nel corpo del messaggio è stato caricato. Payload: ip_address e user_agent quando noti; gli eventi API aggiungono is_prefetched, country (ISO 3166-1 alpha-2, derivato dall'IP del client), mailbox_provider e mailbox_provider_region. Controlla is_prefetched prima di contare un'apertura. È true quando una funzionalità di privacy dell'inbox ha recuperato il pixel automaticamente anziché una persona che apre il messaggio, e contarli gonfia il tasso di apertura. Tracking di apertura e clic descrive la strumentazione.

email.clicked

Il destinatario ha cliccato un link tracciato. Payload: url (il link cliccato), ip_address e user_agent quando noti; gli eventi API aggiungono country, mailbox_provider e mailbox_provider_region. I clic sono generalmente un segnale di coinvolgimento più forte delle aperture, perché i proxy di privacy possono caricare i pixel di tracking automaticamente.

email.unsubscribed

Il destinatario ha usato il link di disiscrizione nel corpo del messaggio. Payload: solo la base identità sul webhook; gli eventi API aggiungono mailbox_provider e mailbox_provider_region. Registra una preferenza di opt-out che blocca la mail di marketing. Link di disiscrizione descrive come il link viene inserito nella tua mail.

email.list_unsubscribed

Il destinatario ha usato il pulsante di disiscrizione one-click che il provider di posta mostra nella propria UI, guidato dagli header List-Unsubscribe del messaggio. Payload: solo la base identità sul webhook (più mailbox_provider e mailbox_provider_region dagli eventi API); il meccanismo è il tipo di evento stesso, ed è per questo che è separato da email.unsubscribed. Registra anch'esso una preferenza di opt-out che blocca la mail di marketing.

Eventi a livello di messaggio

Due eventi descrivono il messaggio nel suo complesso anziché un singolo destinatario, quindi il loro data contiene email_id, workspace_id, tags e metadata ma nessuna identità del destinatario. Entrambi appartengono all'invio programmato.

email.scheduled

Abbiamo accettato un invio con un scheduled_at nel futuro. Payload: la base a livello di messaggio più scheduled_at. Quando quel momento arriva, il ciclo di vita per destinatario inizia da email.accepted.

email.canceled

Un messaggio programmato è stato annullato prima della partenza, quindi non produce alcun evento del ciclo di vita per destinatario. Payload: solo la base a livello di messaggio.

Eventi inbound e mailbox

email.received copre la posta in arrivo. Si attiva quando riceviamo e analizziamo un messaggio inbound. Il suo payload include inbound_message_id, indirizzamento, oggetto e verdetti di autenticazione. Setup, payload e l'API di fetch-back sono in Ricezione email. Una mailbox ha la propria famiglia email_mailbox.* in aggiunta, documentata nella guida alle mailbox.

Classificazione dei bounce

bounce_class è la classificazione numerica dei bounce inclusa in email.bounced, email.out_of_band_bounce e email.deferred. Si aggrega nella categoria grossolana bounce_type e conserva il codice di dettaglio, così puoi distinguere una casella piena da un errore di routing anche se entrambi risultano come soft:
bounce_classbounce_typeSignificato
1undeterminedLa risposta del server ricevente era ambigua
10, 30hardErrore permanente: indirizzo non valido o dominio inesistente
20 to 24, 40, 70, 100softErrore transitorio: casella piena, server temporaneamente non disponibile, problema DNS o di routing
25adminRifiuto amministrativo: relay negato, dominio in blocklist
50 to 54blockIl server ricevente ha rifiutato l'IP di invio
Qualsiasi classe fuori da questa lista corrisponde a undetermined. Solo i bounce hard sopprimono l'indirizzo; soft, block, admin e undetermined no, perché l'indirizzo potrebbe essere ancora raggiungibile.

Soppressione automatica

Due eventi aggiungono automaticamente un destinatario alla lista di soppressione dello spazio di lavoro, e bloccano tipi di mail diversi:
EventoSoppressione reasonCosa blocca
email.bounced o email.out_of_band_bounce con bounce_type: "hard"hard_bounceTutta la mail, transazionale inclusa
email.complainedcomplaintMail di marketing; la transazionale viene comunque inviata
Un hard bounce blocca tutto perché l'indirizzo stesso non esiste più. Un reclamo blocca solo il marketing, perché chi ha segnalato la tua newsletter come spam ha comunque bisogno del reset della password.
email.unsubscribed e email.list_unsubscribed bloccano la mail allo stesso modo di un reclamo, solo il marketing, ma tramite un record diverso: invece di aggiungere una soppressione, registrano l'opt-out del destinatario come preferenza dichiarata. Cosa fa un opt-out descrive quel record nel dettaglio.
Ogni aggiunta genera un evento email_suppression.created che contiene suppression_id, l'email soppresso, il reason e il workspace_id. Lo schema completo del record e come gestire le voci manualmente si trovano nella Guida alle soppressioni.
Gli invii successivi a un indirizzo soppresso vengono rifiutati in anticipo come email.rejected con rejection_reason: "recipient_suppressed", e non incidono mai sulla tua deliverability.

Prossimi passi