Webhook Events

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:

1{
2 "type": "event",
3 "event_type": "event.name",
4 "event_id": "evt_123abc..."
5 // ... event-specific data object
6}

Message Events

message.received

  • Description: Triggered whenever a new email is successfully received and processed in one of your Inboxes. This is the most common trigger to kick off agent workflows.
  • Example use-case: Kick off a internal workflow when a customer complaint email hits the support inbox

Something here to notice is message.received is the only webhook event that includes 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

1{
2 "type": "event",
3 "event_type": "message.received",
4 "event_id": "evt_123abc",
5 "message": {
6 "inbox_id": "inbox_456def",
7 "thread_id": "thd_789ghi",
8 "message_id": "msg_123abc",
9 "labels": ["received"],
10 "timestamp": "2023-10-27T10:00:00Z",
11 "from": [
12 {
13 "name": "Jane Doe",
14 "email": "jane@example.com"
15 }
16 ],
17 "to": [
18 {
19 "name": "Support Agent",
20 "email": "support@agentmail.to"
21 }
22 ],
23 "subject": "Question about my account",
24 "preview": "A short preview of the email text...",
25 "text": "The full text body of the email.",
26 "html": "<html>...</html>",
27 "created_at": "2023-10-27T10:00:00Z"
28 },
29 "thread": {
30 // ... thread properties
31 }
32}

message.sent

  • Description: Triggered when a message is successfully sent from one of your Inboxes.
  • Use Case: Track outgoing messages, update your database, or trigger follow-up workflows after sending.
1{
2 "type": "event",
3 "event_type": "message.sent",
4 "event_id": "evt_456def",
5 "send": {
6 "inbox_id": "inbox_456def",
7 "thread_id": "thd_789ghi",
8 "message_id": "msg_123abc",
9 "timestamp": "2023-10-27T10:05:00Z",
10 "recipients": [
11 "recipient@example.com"
12 ]
13 }
14}

message.delivered

  • Description: Triggered when a sent message is successfully delivered to the recipient’s mail server.
  • Use Case: Confirm successful delivery, update message status, or trigger delivery confirmation workflows.
1{
2 "type": "event",
3 "event_type": "message.delivered",
4 "event_id": "evt_789ghi",
5 "delivery": {
6 "inbox_id": "inbox_456def",
7 "thread_id": "thd_789ghi",
8 "message_id": "msg_123abc",
9 "timestamp": "2023-10-27T10:06:00Z",
10 "recipients": [
11 "recipient@example.com"
12 ]
13 }
14}

What is the difference between message.sent and message.delivered?

message.sent means the message has succesfully left our servers and is out to travel the network. This is typically happens before message.delivered where message.delivered means the recieving email server(whether its Gmail or Outlook) gives us the 200 OK saying the email has been received. What they do with the email after is unknown.

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 properitary 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.bounced

  • Description: Triggered when a sent message fails to deliver and bounces back. Includes bounce type and sub-type information.
  • Use Case: Handle bounced emails, update recipient status, or trigger bounce handling workflows.
1{
2 "type": "event",
3 "event_type": "message.bounced",
4 "event_id": "evt_012jkl",
5 "bounce": {
6 "inbox_id": "inbox_456def",
7 "thread_id": "thd_789ghi",
8 "message_id": "msg_123abc",
9 "timestamp": "2023-10-27T10:07:00Z",
10 "type": "Permanent",
11 "sub_type": "General",
12 "recipients": [
13 {
14 "address": "invalid@example.com",
15 "status": "bounced"
16 }
17 ]
18 }
19}

message.complained

  • Description: Triggered when a recipient marks your message as spam or files a complaint.
  • Use Case: Handle spam complaints, update sender reputation, or trigger complaint handling workflows.
1{
2 "type": "event",
3 "event_type": "message.complained",
4 "event_id": "evt_345mno",
5 "complaint": {
6 "inbox_id": "inbox_456def",
7 "thread_id": "thd_789ghi",
8 "message_id": "msg_123abc",
9 "timestamp": "2023-10-27T10:08:00Z",
10 "type": "abuse",
11 "sub_type": "spam",
12 "recipients": [
13 "complainer@example.com"
14 ]
15 }
16}

message.rejected

  • Description: Triggered when a message is rejected before being sent, typically due to validation errors or policy violations.
  • Use Case: Handle rejected messages, log rejection reasons, or trigger validation workflows.
1{
2 "type": "event",
3 "event_type": "message.rejected",
4 "event_id": "evt_678pqr",
5 "reject": {
6 "inbox_id": "inbox_456def",
7 "thread_id": "thd_789ghi",
8 "message_id": "msg_123abc",
9 "timestamp": "2023-10-27T10:09:00Z",
10 "reason": "Invalid recipient address"
11 }
12}

If 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 Events

domain.verified

  • Description: Triggered when a domain is successfully verified and ready to use for sending emails.
  • Use Case: Automatically enable domain-specific features, update domain status, or trigger post-verification workflows.
1{
2 "type": "event",
3 "event_type": "domain.verified",
4 "event_id": "evt_901stu",
5 "domain": {
6 "domain_id": "dom_123abc",
7 "status": "verified",
8 "feedback_enabled": true,
9 "records": [
10 // ... DNS verification records
11 ],
12 "created_at": "2023-10-27T09:00:00Z",
13 "updated_at": "2023-10-27T10:00:00Z"
14 }
15}

Event Filtering

When creating a webhook, you can specify which events to subscribe to. This allows you to:

  • Reduce webhook traffic by only subscribing to events you need
  • Create specialized webhooks for specific workflows

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.

If you have any specific webhook notifications you would like, please ping us in the #feature-requests channel in the Discord