As mentioned in the overview, webhooks allow us to create event-driven applications.
AgentMail supports multiple event types that allow you to build comprehensive, event-driven workflows for your email agents.
All webhook payloads follow the same basic structure:
The AgentMail SDKs export typed classes for each webhook payload shape, so you can parse raw payloads into fully typed objects.
Copy one of the blocks below into Cursor or Claude for webhook event parsing in one shot.
message.receivedInboxes. This is the most common trigger to kick off agent workflows.Something here to notice is message.received and its filtered variants are
the only webhook events that include both the metadata on the Thread and the
Message in the payload. Other event types send only metadata on the event.
Let us know if you need
metadata on other event types by emailing support@agentmail.cc
The text and preview fields may be absent when the original email only
contains HTML with no plain-text part. This is common with forwarded emails
from clients like Gmail and Outlook. When handling incoming messages, always
check for html as the primary content source and treat text as optional.
message.received.spammessage.received. Messages classified as spam are not delivered as message.received events.This event is only delivered if the API key used to create the webhook has the label_spam_read permission. Without this permission, the webhook creation will be rejected with a 403 Forbidden error.
message.received.blockedmessage.received. Messages that match a block list are not delivered as message.received events.This event is only delivered if the API key used to create the webhook has the label_blocked_read permission. Without this permission, the webhook creation will be rejected with a 403 Forbidden error.
message.received.unauthenticatedunauthenticated because legitimate senders may omit the headers; messages with authentication headers that explicitly fail are dropped.message.sentInboxes.message.deliveredWhat is the difference between message.sent and message.delivered?
message.sent means the message has successfully left our servers and is out
to travel the network. This typically happens before message.delivered
where message.delivered means the receiving email server (whether it’s Gmail
or Outlook) gives us the 200 OK saying the email has been received. What
they do with the email after is unknown.
Does message.delivered mean I landed in their inbox?
Nope. As mentioned message.delivered means the receiving email server,
whether it’s Gmail or Outlook tells us “Hey AgentMail, we got your email,
we’ll take it from here!”. They typically have their own proprietary
algorithms to determine whether the email is going to end up in the inbox or
spam, but rest assured we handle everything needed for providers like Gmail
to deem the emails primary inbox worthy
message.bouncedmessage.complainedmessage.rejectedIf you send an email to a bounced address, rejected address, or
complained address we prevent you from sending to this email address ever
again to keep bounce rates low. Make sure to keep your account bounce rate
under 4%, otherwise we will put your account under review.
domain.verifiedWhen creating a webhook, you can specify which events to subscribe to. This allows you to:
For example, if you only need to trigger workflows on incoming messages, you can subscribe to just message.received. If you’re building a delivery tracking system, you might subscribe to message.sent, message.delivered, and message.bounced.
By default, spam, blocked, and unauthenticated events are not delivered. To receive them, you must explicitly include message.received.spam, message.received.blocked, or message.received.unauthenticated in the event_types list when creating your webhook. The API key must also have the corresponding label_spam_read or label_blocked_read permission for spam and blocked events.
If you have any specific webhook notifications you would like, please ping us in the #feature-requests channel in the Discord