Top Email API Services With Webhook Event Tracking

14 min read

Compare the top email API services with webhook event tracking: inbound events, delivery and bounce payloads, signing, retries, and agent-ready setup.

John Joubert

John Joubert

Founder, Robotomail

Top Email API Services With Webhook Event Tracking
Table of contents

If you need an email API that pushes events to your server instead of making you poll, the practical shortlist is SendGrid, Mailgun, Postmark, Resend, Amazon SES (via SNS or EventBridge), the Gmail API (via Pub/Sub push), and agent-focused options like Robotomail and AgentMail. The top email API services with webhook event tracking split into two camps: outbound-first providers that emit delivery, bounce, open and click events for mail you send, and inbound-capable providers that also push a webhook when a human replies. If your agent needs to read replies and act on them, you want both.

We run mail infrastructure for AI agents, so most of the support questions we see are not "which provider has the most event types" but "why did my handler miss an event" and "why does my agent not know the reply arrived". This post covers the comparison and the operational details that decide whether your webhook pipeline survives a week in production.

What "webhook event tracking" actually means

The phrase gets used for three different things. Sort out which one you need before you pick a provider.

Outbound delivery events. The provider tells you what happened to a message you sent: accepted, delivered, deferred, bounced, marked as spam, unsubscribed. These are the events that matter for list hygiene and for knowing whether your agent's message actually landed.

Engagement events. Opens and clicks. Opens are tracked with a 1x1 pixel, clicks by URL rewriting. Both are approximations. Apple's Mail Privacy Protection pre-fetches images through a proxy, and corporate security gateways scan links, so open and click counts include machine traffic you did not generate. Treat them as directional signals, never as proof a person read a message.

Inbound events. Someone replies to your address and the provider POSTs the parsed message to your endpoint. This is the event type that most "email API" comparisons gloss over, and the only one that lets an agent run a conversation. If you are building a loop where the agent sends, waits, reads the reply and responds, inbound webhooks are the whole product. We wrote up the parsing side in detail in how to parse an inbound email webhook.

A fourth thing people expect and rarely get: an events API to query history. Webhooks are at-least-once and fire-and-forget. If your handler was down for ten minutes, you want to backfill rather than guess. Providers vary a lot here.

Comparison: top email API services with webhook event tracking

Service Inbound webhook Delivery / bounce events Open & click events Payload signing Best for
Robotomail Yes, message.received with parsed body and thread id Yes, plus queryable events API Not the focus Yes AI agents that send and receive
SendGrid Yes, Inbound Parse on a dedicated subdomain Yes, rich event set Yes Yes, ECDSA signature High-volume marketing and transactional
Mailgun Yes, routes with store-and-notify Yes, with temporary vs permanent failure split Yes Yes, HMAC over timestamp + token Teams that want routing rules in the provider
Postmark Yes, inbound stream with JSON payload Yes, separate message streams Yes Basic auth or custom headers Transactional mail where deliverability detail matters
Resend Yes, inbound support Yes, via Svix-delivered webhooks Yes Yes, Svix signature Modern DX, React email templates
Amazon SES Yes, receipt rules to SNS, S3 or Lambda Yes, event destinations to SNS, EventBridge, Firehose Yes SNS message signing AWS-native stacks with existing queues
Gmail API Push notifications via Pub/Sub, then fetch No, it is a mailbox not a sender No Pub/Sub auth Acting on a real human Gmail account
AgentMail Yes, agent-oriented inbound events Yes Not the focus Yes Agent inboxes, similar category to Robotomail

Two things to read off that table. First, nearly everyone does outbound events well, because that is table stakes for a sending platform. Second, inbound quality varies enormously: some providers hand you a clean JSON object with parsed text, HTML, headers and attachments; others hand you a multipart form post with a raw MIME blob and let you deal with it.

The services in detail

Robotomail

We built Robotomail for the case where the agent is the mailbox owner, not a human. You provision a mailbox over the API or CLI, register a webhook, and every inbound message arrives as a JSON event with the body already parsed and a stable thread id so replies land in the right conversation.

Events use a consistent { event, timestamp, data } envelope with snake_case fields in data. Inbound mail is message.received. There is also an events endpoint so you can query what happened rather than relying only on the push, which is what you want after a deploy that took your endpoint down. The full list and the signature verification details are in the webhooks concept docs and the events API reference.

Where Robotomail is not the right answer: you want open and click heatmaps for a marketing campaign, or you are blasting a million messages a month. That is a bulk sending problem, not an agent inbox problem.

SendGrid

The SendGrid Event Webhook is the reference implementation of outbound event tracking. One endpoint receives batched JSON arrays covering processed, dropped, delivered, deferred, bounce, open, click, spam report and unsubscribe events. Payloads can be signed with an ECDSA key so you can verify authenticity without a shared secret in a header.

Inbound is a separate feature, Inbound Parse, and it works differently from the event webhook: you point MX records for a subdomain at SendGrid, and it POSTs a multipart form with the message fields. It is capable but it is a second system with its own semantics, and you will write more parsing code than you expect. See our SendGrid comparison for the agent-specific tradeoffs.

Mailgun

Mailgun's event model is good and its routing model is better. Webhooks cover delivered, permanent failure, temporary failure, opened, clicked, complained and unsubscribed, and the distinction between temporary and permanent failure is genuinely useful: you retry one and suppress the other.

Signing is HMAC over a timestamp and token, which gives you replay protection if you actually check the timestamp. Inbound goes through routes, where you write a match expression and an action, including store-and-notify so you can fetch the full message later. That indirection is powerful for multi-tenant setups and annoying when you just want one agent to get one webhook. More in our Mailgun comparison.

Postmark

Postmark's webhook payloads are the cleanest of the traditional transactional providers. Separate webhook types for delivery, bounce, spam complaint, open, click, subscription change and inbound, each with a well-documented JSON shape and a detailed bounce taxonomy instead of a generic failure code.

Authentication on webhooks is basic auth or custom headers rather than a cryptographic signature, so put the endpoint behind a secret path and verify credentials. Inbound arrives as structured JSON with parsed text, HTML, headers and attachment metadata, which makes it one of the easier traditional providers to point an agent at.

Resend

Resend delivers webhooks through Svix, which means you get a standard signature scheme, a usable retry policy and a delivery log UI without the vendor building that themselves. Event types cover the sent, delivered, bounced, complained, opened and clicked lifecycle. Inbound is supported too.

The developer experience is the selling point. If your stack is already TypeScript and you want templates in React, it fits. If your agent needs dozens of ephemeral addresses created and torn down programmatically, read our Resend comparison first, because per-mailbox provisioning is a different shape of problem than per-message sending.

Amazon SES

SES does not have webhooks in the usual sense. It has event destinations, and you choose where events go: SNS topics, EventBridge, Kinesis Firehose, CloudWatch. Event types include sends, deliveries, bounces, complaints, opens, clicks, rejects, rendering failures and delivery delays. Inbound uses receipt rules that can write to S3, invoke Lambda or publish to SNS.

This is the most flexible option and the most work. You get a durable queue for free, which is the right architecture, and in exchange you assemble it yourself: topic, subscription confirmation, SNS signature validation, S3 lifecycle rules for stored messages, IAM policies. Worth it if you already live in AWS. Overkill if you want one agent to answer one inbox.

Gmail API

The Gmail API is in this list because people search for it, but it is a different category. It does not emit delivery or engagement events, because it is not a sending platform, it is an interface to a human mailbox. Its "webhook" is a watch request that publishes change notifications to a Pub/Sub topic; the notification tells you the mailbox changed and gives you a historyId, then you call the API to find out what actually happened.

That means every notification costs you extra API calls, watches expire and must be renewed, and the whole thing requires OAuth with a user consent screen plus a security review if you ask for broad scopes. For an autonomous agent that needs its own address, this is a bad fit, and we explained why in Gmail API alternatives for AI agents and in the Gmail API comparison.

AgentMail

AgentMail sits in the same category as Robotomail: inboxes designed for agents, with inbound webhook events as the primary interface rather than an add-on. If you are evaluating that category seriously you should look at both. Our side-by-side is at compare/agentmail, and the honest trade-offs are in AgentMail alternatives.

How to choose

Answer these in order and the shortlist collapses quickly.

  1. Does your agent need to receive mail, or only send? Send-only means almost any provider works and you optimize for deliverability and price. Receive means you are evaluating inbound payload quality, threading support, and how many addresses you can create.
  2. How many addresses do you need, and how fast? One shared inbox is easy. One mailbox per customer, per ticket or per agent run is where provider models diverge sharply. Check whether address creation is an API call or a dashboard action with DNS steps.
  3. Do you need threading, or just messages? Agents that hold conversations need In-Reply-To and References handled correctly in both directions, or every reply starts a new thread in the recipient's client. See what email threading is.
  4. Do you actually need open and click events? If a human is not going to look at the resulting chart, skip them. They add tracking pixels and rewritten URLs to your mail, which costs you deliverability and privacy goodwill for data you will not use.
  5. Can you backfill? If your only record of an event is a POST you may have dropped, you have a gap. Prefer a provider with a queryable events endpoint, or write every event to your own durable store the instant it arrives.

Wiring up webhook event tracking with Robotomail

Three steps: create a mailbox, register a webhook, handle events.

Create the mailbox from the CLI:

npx @robotomail/cli mailbox create shopping-agent

Or over the API:

curl -X POST https://api.robotomail.com/v1/mailboxes \
  -H "Authorization: Bearer rm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"address": "shopping-agent"}'

Send from it:

curl -X POST https://api.robotomail.com/v1/mailboxes/mbx_shopping/messages \
  -H "Authorization: Bearer rm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"to": ["vendor@example.com"], "subject": "Order #A-4521 delivery update?", "bodyText": "Hi, checking on the status of order A-4521."}'

Webhooks are registered as their own resource, not inline on the mailbox, so you can point several mailboxes at one endpoint. The registration call and the signature verification scheme are in the webhooks API reference.

When mail arrives, your endpoint receives:

{
  "event": "message.received",
  "data": {
    "message_id": "...", "mailbox_id": "...", "mailbox_address": "shopping-agent@robotomail.co",
    "from": "vendor@example.com", "subject": "Re: Order #A-4521 delivery update?", "body_text": "...",
    "thread_id": "...", "received_at": "2026-04-17T10:00:00.000Z"
  }
}

A handler that does the right thing:

import express from "express";

const app = express();
const seen = new Set<string>(); // use Redis or a table in production

app.post("/webhooks/email", express.json(), async (req, res) => {
  // 1. Verify the signature before trusting anything. See /docs/api/webhooks.

  const { event, data } = req.body;

  // 2. Acknowledge immediately. Never run an LLM call inside the request.
  res.status(200).end();

  // 3. Deduplicate. Webhooks are at-least-once.
  if (event !== "message.received") return;
  if (seen.has(data.message_id)) return;
  seen.add(data.message_id);

  // 4. Hand off to a queue or background job.
  await queue.add("handle-reply", {
    threadId: data.thread_id,
    mailboxId: data.mailbox_id,
    from: data.from,
    subject: data.subject,
    body: data.body_text,
    messageId: data.message_id,
  });
});

When the agent replies, include inReplyTo with the inbound message_id so the thread holds together in the recipient's client:

curl -X POST https://api.robotomail.com/v1/mailboxes/mbx_shopping/messages \
  -H "Authorization: Bearer rm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{"to": ["vendor@example.com"], "subject": "Re: Order #A-4521 delivery update?", "bodyText": "Thanks, that works.", "inReplyTo": "msg_abc123"}'

A full walkthrough of the receive-and-reply loop, including attachments, is in the receive and reply guide.

Operational gotchas that apply to every provider

Acknowledge in under a second. Every provider has a timeout, and a slow handler gets retried, which means duplicate processing. Return 200 first, process after. If your handler calls a model before responding, you will eventually time out and double-send a reply.

Assume at-least-once, never exactly-once. Store the provider's message id and check it before acting. An agent that sends two replies because of one retried webhook looks broken to the recipient in a way that is hard to explain.

Events are not ordered. A delivered event can arrive after a bounce event for a different recipient in the same send, and inbound messages for one thread can arrive out of order if a retry is involved. Order by the timestamp in the payload, not by arrival.

Verify signatures, and check the timestamp too. An HMAC without a freshness window still permits replay. Reject anything older than a few minutes.

Log every raw payload. Cheap insurance. When a provider's event semantics surprise you, the raw body is the only way to prove what happened.

Validate your endpoint under load before you ship. The failure mode is not a 500, it is a queue that silently backs up while your agent sits waiting for a reply that already arrived.

If you want more depth on the receiving side specifically, we covered the architecture choices in receiving email by webhook and the provider-by-provider webhook support survey in the best email API for webhook support.

FAQ

Which email API has the best inbound webhook payload?

For structured, ready-to-use JSON, Postmark and Robotomail are the easiest to consume: parsed text, HTML, headers and attachment metadata without MIME work on your side. SendGrid's Inbound Parse and SES receipt rules are powerful but push more parsing and plumbing onto you. If your agent needs threading as well as parsing, check whether the payload includes a thread identifier, not just a message id.

Do I need open and click tracking for an AI agent?

Usually no. Open tracking requires a pixel and click tracking rewrites your links, both of which cost deliverability, and the numbers are contaminated by image proxies and link scanners. Agents care about delivered, bounced and replied. Reply is the signal that matters, and that is an inbound webhook, not an engagement pixel.

Can I use webhooks instead of IMAP polling?

Yes, and you should. Polling IMAP means latency you tune by hand, connection limits, and state you have to track across restarts. A webhook arrives in seconds and carries the parsed message with it. We compared the two approaches in IMAP for AI agents.

What happens to events while my endpoint is down?

Providers retry on a backoff schedule, typically for hours, then give up. That is why a queryable events history matters: after an outage you reconcile from the API rather than hoping the retries covered you. With Robotomail you can list events and messages over the API to backfill, and the limits that apply are documented in concepts/limits.

Ready to give an agent its own inbox with webhook events instead of a polling loop? Start at robotomail.com, or read the quickstart and have a mailbox receiving events in a few minutes.

Give your AI agent a real email address

Create a mailbox, connect your agent and test a conversation. Send, receive and retrieve the thread through one API.

Related posts