email.onUnsubscribed
The recipient opted out — mirror it into your own preferences.
Fires when the recipient opts out through an unsubscribe link, their mail client’s one-click header, or a reply that reads as an opt-out. The provider already stops the next send; this hook keeps your own preference UI in sync, so someone who unsubscribed by email doesn’t see themselves still subscribed in your app.
hooks: {
email: {
onUnsubscribed: async (event) => {
await prisma.emailPreference.upsert({
where: {
email_list: { email: event.recipient, list: event.listId ?? "*" },
},
create: { email: event.recipient, list: event.listId ?? "*", subscribed: false },
update: { subscribed: false },
});
},
},
},
listId is set when the provider names the list they left. Without it the opt-out isn’t tied to a list — usually all non-transactional mail, not necessarily every email. AIInbx says which: getAIInbxOutbound(event)?.unsubscribeScope is "all" or "optional". Resend, Mailgun, and AIInbx emit this event.
Payload
emailDriver?string
EmailKit driver id that produced this event, attached by the EmailKit client.
stringschemaVersion?"1"
Schema version for forward-compat
"1"eventId?string
Unique event identifier for dedupe
stringmessageIdstring
Unique message identifier from the email provider
stringproviderId?string
Provider-specific message identifier (in addition to messageId). This is the provider's internal ID for this message, separate from the RFC Message-ID. Useful for provider-specific operations or tracking.
stringrecipientstring
Email address of the recipient (always available)
stringstatus| "sent"
| "delivered"
| "opened"
| "clicked"
| "bounced"
| "complained"
| "rejected"
| "unsubscribed"
Event status/type
| "sent"
| "delivered"
| "opened"
| "clicked"
| "bounced"
| "complained"
| "rejected"
| "unsubscribed"timestampDate
Timestamp when the event occurred
Datefrom?EmailAddress
Sender email address (available in sent/accepted events)
EmailAddressto?EmailAddress[]
Recipient email addresses (available in sent/accepted events)
EmailAddress[]subject?string
Email subject (available in sent/accepted events)
stringtags?EmailTag[]
Custom metadata/tags associated with the email
EmailTag[]metadata?Record<string, string>
Custom metadata key-value pairs
Record<string, string>campaignId?string
Campaign or tracking identifier
stringrecipientDomain?string
Domain of the recipient (e.g., "gmail.com")
stringserver?string
Receiving server information
stringprovider?Record<string, unknown>
Provider-specific typed extras, namespaced by provider (e.g. `provider.aiinbx` — read it with `getAIInbxOutbound(event)`).
Record<string, unknown>raw?unknown
Provider-specific raw data (for debugging or advanced use cases)
unknownlistId?string
Unsubscribe list the recipient opted out of, when the provider names one. Absent means not list-specific, which is not necessarily every email.
stringsource?"link" | "one_click" | "reply" | (string & {})
How the recipient opted out
"link" | "one_click" | "reply" | (string & {})