Sign inGet started

E-mailevents

We zenden events uit terwijl elke ontvanger de bezorging doorloopt. Een verzending naar drie adressen levert drie onafhankelijke stromen op, gecorreleerd via email_id en recipient_id. Deze pagina beschrijft de e-maileventtypen. Zie Webhooks voor handtekeningen, retries, volgorde en replay.
Elke ontvanger begint bij email.accepted en daarna email.processed. Een broadcast-ontvanger is een eigen bericht, dus krijgt ook een eigen email.accepted, maar alleen in de events API en het e-maillog, niet als webhook. Vanaf daar wordt het bericht geaccepteerd door de ontvangende server (email.delivered), uitgesteld en opnieuw geprobeerd (email.deferred, wat uiteindelijk resulteert in delivered of bounced), geweigerd door de ontvangende server (email.bounced), of er wordt helemaal geen bezorgpoging gedaan (email.rejected). Na een bezorging kan de stroom doorgaan met email.out_of_band_bounce, email.complained, email.opened, email.clicked, email.unsubscribed en email.list_unsubscribed.
Elke ontvanger eindigt in precies één eindstatus: delivered, bounced, complained of rejected, teruggegeven als de status per ontvanger van GET /v1/email/messages/{message_id}/recipients. Engagementevents veranderen die status nooit: een ontvanger die het bericht opende, is nog steeds delivered. Een late bounce verandert de status wél, omdat de ontvangende server een eerder gegeven acceptatie intrekt, waardoor de ontvanger van delivered naar bounced gaat. Het bericht als geheel heeft een eigen samenvattende status en tellingen per status op GET /v1/email/messages/{message_id}.

De event-envelope

Events komen binnen als de drievelds-envelope die elke webhook gebruikt: type, timestamp (wanneer het event plaatsvond, RFC 3339) en een typespecifiek data-object.
Codevoorbeeld
{
  "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
  }
}
Elk uitgaand event bevat email_id, recipient_id, workspace_id, het recipient-adres en de bijbehorende envelope recipient_role (to, cc of bcc). Het echoot ook tags en metadata uit het verzendverzoek, zodat je het event kunt koppelen aan je eigen administratie. Elke optionele waarde is null als de verzending er geen had, inclusief broadcast_id: dat veld noemt de broadcast waar een verzending deel van uitmaakte, zodat je de events van een broadcast kunt groeperen zonder elke verzending op te zoeken, en het is null bij een verzending zonder broadcast erachter. Eén geval rapporteert null voor een verzending die er wel een had: een uitschrijflink van e-mail die is verstuurd voordat we het veld toevoegden noemt geen broadcast, dus een opt-out via zo'n link rapporteert null op email.unsubscribed en email.list_unsubscribed, ongeacht of een broadcast de e-mail verzond. Beschouw null op die twee events als niet-conclusief, anders tel je de opt-outs van een broadcast te laag. broadcast_id ontvang je alleen via de webhook: de events API hieronder geeft elk event zonder dat veld terug. Eventtypen voegen velden toe die beschreven staan in de secties lifecycle, engagement, suppression en inbound.
Dezelfde events zijn achteraf opvraagbaar via GET /v1/email/messages/{message_id}/events, waar elk event ook een id (ev_-prefix) en een occurred_at heeft. Gebruik dit om bij te vullen, opnieuw af te spelen of af te stemmen met wat je endpoint ontving. Enkele velden ontvang je alleen via die API in plaats van via de webhook; de betreffende eventbeschrijving vermeldt welke dat zijn.

Lifecycle-events

email.accepted

We hebben de verzending geaccepteerd en zijn begonnen met het voorbereiden van de bezorging. Wordt één keer per gevraagde ontvanger afgevuurd en is het eerste event in die stroom. Een broadcast-ontvanger krijgt er ook één, omdat elke ontvanger een eigen bericht is, maar het wordt geregistreerd in plaats van bezorgd: lees het uit de events API of het e-maillog, niet via je webhook-endpoint. Payload: alleen de identiteitsbasis.

email.processed

Het bericht is opgebouwd en in de wachtrij geplaatst voor bezorging aan de mailserver van de ontvanger. Payload: alleen de identiteitsbasis via de webhook; de events API voegt mailbox_provider en mailbox_provider_region toe, de classificatie van het ontvangende mailsysteem (bijvoorbeeld gmail, NA), aanwezig wanneer die bepaald kon worden en anders null. Door de timestamp van dit event te vergelijken met die van email.accepted krijg je onze eigen verwerkingstijd voor een enkele verzending. Een broadcast heeft zo'n interval niet: de acceptatie en de verwerking dragen hetzelfde verzendmoment, dus de twee timestamps komen overeen in plaats van verwerkingstijd te omsluiten, en de acceptatie ontvang je alleen via de events API, als occurred_at.

email.delivered

De ontvangende mailserver heeft het bericht geaccepteerd en de verantwoordelijkheid ervoor op zich genomen. Dit event bevestigt geen inboxplaatsing of lezing. Inbox Insights biedt steekproefsgewijze plaatsingsschattingen; open- en klikevents registreren trackingverzoeken. Payload: alleen de identiteitsbasis via de webhook; de events API voegt sending_ip toe, het adres van waaruit het bericht is verzonden, wat ertoe doet als een bezorgbaarheidsprobleem naar één IP wijst, plus mailbox_provider en mailbox_provider_region.

email.deferred

Een tijdelijke fout: de ontvangende server vroeg ons het later opnieuw te proberen (volle mailbox, greylisting, beperking van het aantal verzoeken). We proberen automatisch opnieuw en de ontvanger resulteert uiteindelijk in email.delivered of email.bounced, dus dit event is informatief en niet terminaal, en een ontvanger kan meerdere keren worden uitgesteld. Payload: bounce_type, bounce_class, defer_reason (de reden die de server opgaf) en sending_ip via de webhook; de events API voegt mailbox_provider en mailbox_provider_region toe.

Failure-events

email.bounced

Een permanente fout op SMTP-moment: de ontvangende server weigerde het bericht en de eindstatus van de ontvanger wordt bounced. Payload: bounce_type (zie de classificatietabel), bounce_class, bounce_code (de SMTP-antwoordcode, bijvoorbeeld 550), bounce_description (de reden die de server opgaf) en sending_ip via de webhook; de events API voegt mailbox_provider en mailbox_provider_region toe. Een hard bounce onderdrukt het adres.

email.out_of_band_bounce

Een late bounce: de ontvangende server accepteerde het bericht op SMTP-moment en stuurde daarna een bouncerapport. Het heeft dezelfde classificatie als email.bounced (bounce_type, bounce_class, bounce_code, bounce_description, sending_ip via de webhook; mailbox_provider en mailbox_provider_region uit de events API). Wanneer het rapport als bounce wordt geclassificeerd (elke klasse in de tabel), heeft de server de eerdere acceptatie ingetrokken en gaat de ontvanger van delivered naar bounced. Rapporten met een klasse die niet in de tabel staat, zoals auto-replies, worden op de tijdlijn geregistreerd en laten de status ongewijzigd. Een hard out-of-band bounce onderdrukt het adres eveneens.

email.rejected

De ontvanger heeft de externe mailserver nooit bereikt, dus er is geen bezorgpoging gedaan. Dat onderscheidt een rejection van een bounce, waarbij de ontvangende server degene is die nee zegt. Payload: rejection_reason, ook op het ontvangerrecord, een van:
rejection_reasonBetekenis
recipient_suppressedDe ontvanger is geblokkeerd op werkruimteniveau, door de suppressielijst of door een opgegeven voorkeur, dus er is nooit een bezorgpoging gedaan
transmission_failedHet bericht kon niet worden verzonden voor bezorging
generation_failureHet bericht kon niet worden opgebouwd voor bezorging, een template- of inhoudsprobleem
policy_rejectionHet verzendbeleid weigerde het bericht
domain_unverifiedHet verzenddomein was niet geverifieerd
quota_exceededHet verzendquotum van de organisatie was bereikt
recipient_not_allowedDe ontvanger was niet toegestaan voor deze verzending; verzendingen via een gedeeld onboardingdomein bereiken alleen geverifieerde leden van je werkruimte
De events API voegt ook mailbox_provider en mailbox_provider_region toe wanneer het ontvangende mailsysteem vóór de afwijzing geclassificeerd kon worden.

email.complained

De ontvanger markeerde het bericht als spam en de mailboxprovider meldde dit terug via zijn feedbackloop. Klachten komen binnen na bezorging en zetten de eindstatus op complained. Payload: feedback_type, het soort rapport dat de provider stuurde, zoals abuse of fraud, en null wanneer de provider dit niet specificeerde, plus mailbox_provider en mailbox_provider_region uit de events API. Een klacht onderdrukt het adres voor marketingmail. Houd je klachtratio laag: providers vertragen afzenders die rapporten verzamelen.

Engagementevents

email.opened

De trackingpixel in de berichttekst is geladen. Payload: ip_address en user_agent wanneer bekend; de events API voegt is_prefetched, country (ISO 3166-1 alpha-2, afgeleid van het client-IP), mailbox_provider en mailbox_provider_region toe. Controleer is_prefetched voordat je een open telt. Het is true wanneer een privacyfunctie van de inbox de pixel automatisch ophaalde in plaats van dat een persoon het bericht opende, en het meetellen daarvan blaast je openratio op. Open- en kliktracking behandelt de instrumentatie.

email.clicked

De ontvanger klikte op een getrackte link. Payload: url (de aangeklikte link), ip_address en user_agent wanneer bekend; de events API voegt country, mailbox_provider en mailbox_provider_region toe. Klikken zijn over het algemeen een sterker engagementsignaal dan opens, omdat privacyproxy's trackingpixels automatisch kunnen laden.

email.unsubscribed

De ontvanger gebruikte de uitschrijflink in de berichttekst. Payload: alleen de identiteitsbasis via de webhook; de events API voegt mailbox_provider en mailbox_provider_region toe. Registreert een opt-outvoorkeur die marketingmail blokkeert. Uitschrijflinks behandelt hoe de link in je mail terechtkomt.

email.list_unsubscribed

De ontvanger gebruikte de one-click-uitschrijfknop die de mailboxprovider in zijn eigen UI toont, aangestuurd door de List-Unsubscribe-headers van het bericht. Payload: alleen de identiteitsbasis via de webhook (plus mailbox_provider en mailbox_provider_region uit de events API); het mechanisme is het eventtype zelf, daarom is het gescheiden van email.unsubscribed. Registreert ook een opt-outvoorkeur die marketingmail blokkeert.

Berichtniveauevents

Twee events beschrijven het bericht als geheel in plaats van één ontvanger, dus hun data heeft email_id, workspace_id, tags en metadata maar geen ontvangeridentiteit. Beide horen bij geplande verzending.

email.scheduled

We hebben een verzending geaccepteerd met een scheduled_at in de toekomst. Payload: de berichtniveaubasis plus scheduled_at. Wanneer dat tijdstip aanbreekt, begint de lifecycle per ontvanger bij email.accepted.

email.canceled

Een gepland bericht is geannuleerd voordat het werd verzonden, dus het levert helemaal geen lifecycle-events per ontvanger op. Payload: alleen de berichtniveaubasis.

Inbound- en mailboxevents

email.received behandelt inkomende e-mail. Het wordt afgevuurd wanneer we een inbound bericht ontvangen en parsen. De payload bevat de inbound_message_id, adressering, onderwerp en authenticatieresultaten. Setup, payload en de fetch-back API staan in E-mail ontvangen. Een mailbox heeft daarbovenop een eigen email_mailbox.*-familie, behandeld in de mailboxgids.

Bounceclassificatie

bounce_class is de numerieke bounceclassificatie die is opgenomen bij email.bounced, email.out_of_band_bounce en email.deferred. Het vat samen in de grove bounce_type en behoudt de fijnmazige code, zodat je een volle mailbox nog kunt onderscheiden van een routeringsfout, ook al rapporteren beide als soft:
bounce_classbounce_typeBetekenis
1undeterminedHet antwoord van de ontvangende server was dubbelzinnig
10, 30hardPermanente fout: ongeldig adres of een domein dat niet bestaat
20 to 24, 40, 70, 100softTijdelijke fout: volle mailbox, server tijdelijk onbereikbaar, DNS- of routeringsprobleem
25adminAdministratieve weigering: relay geweigerd, domein op blocklist
50 to 54blockDe ontvangende server weigerde het verzendende IP
Elke klasse buiten deze lijst wordt afgebeeld op undetermined. Alleen hard-bounces onderdrukken het adres; soft, block, admin en undetermined niet, omdat het adres mogelijk nog bezorgbaar is.

Auto-suppressie

Twee events voegen een ontvanger automatisch toe aan de suppressielijst van de werkruimte, en ze blokkeren verschillende soorten mail:
EventSuppressie reasonWat het blokkeert
email.bounced of email.out_of_band_bounce met bounce_type: "hard"hard_bounceAlle mail, inclusief transactionele
email.complainedcomplaintMarketingmail; transactionele wordt nog steeds verzonden
Een hard bounce blokkeert alles, omdat het adres zelf niet meer bestaat. Een klacht blokkeert alleen marketing, omdat iemand die je nieuwsbrief als spam meldde nog steeds zijn wachtwoordreset nodig heeft.
email.unsubscribed en email.list_unsubscribed blokkeren mail op dezelfde manier als een klacht, alleen marketing, maar via een ander record: in plaats van een suppressie toe te voegen registreren ze de opt-out van de ontvanger als een opgegeven voorkeur. Wat een opt-out doet behandelt dat record volledig.
Elke toevoeging vuurt een email_suppression.created-event af met de suppression_id, het onderdrukte email, de reason en de workspace_id. Het volledige recordschema en hoe je handmatig vermeldingen beheert staan in de Suppressiegids.
Latere verzendingen naar een onderdrukt adres worden direct afgewezen als email.rejected met rejection_reason: "recipient_suppressed", en tellen nooit mee voor je bezorgbaarheid.

Volgende stappen