For Agentic Apps

Email Tools and APIs for Agentic Apps and AI Agents

An agent that sends email needs four things from its provider: a key that can only send, a safe way to retry, a webhook that says when to stop, and a test mode that never reaches a real inbox. Resend, Postmark, SendGrid, Mailgun and Amazon SES cover the sending side. Customer.io, Loops and Resend's Marketing tab also let an agent start sequences through an API. Each claim below links to the vendor's own documentation, read in October 2026.

Two different jobs hide behind the phrase "an agent that sends email". In the first, the agent is an author: a support bot confirms a refund, a monitoring agent reports an incident, a product assistant mails a weekly summary. It needs a sending API, and its risks are duplicate sends, wrong recipients and writing to addresses that already bounced. In the second, the agent is an operator: it creates contacts, edits templates, starts or pauses automations and reads delivery results. That needs a platform whose management surface is reachable through an API, an MCP server or a CLI, and the risk becomes a mistaken change to something many people will receive.

Providers fall on one side or the other. Postmark, SendGrid's Email API, Mailgun and Amazon SES are senders, so your own code owns the schedule, the waiting and the branching. Customer.io, Loops and Resend (once you use its Marketing tab) keep the sequence logic themselves, so the agent only reports events and reads outcomes. The sections below take them in that order, and a guardrails section covers approval gates, recipient allow-lists, send caps and dry runs, which apply whichever provider you pick.

Six questions to settle before an agent holds the key

Can the key only send?

Providers differ most here. Resend, SendGrid, MailerSend and Amazon SES let you issue a credential narrower than the account owner's. Postmark scopes by server token. Loops and Customer.io document keys without per-key permission levels on the pages checked, so isolate them by workspace and by code path.

Whose rate limit does a swarm share?

Resend's default is 10 requests a second per team, counted across every key, and Loops uses the same figure per team. Ten parallel agent workers draw from one bucket, so the 429 handling belongs in a shared queue rather than in each worker.

What does a retry do?

Agents retry after timeouts, restarts and replayed tool calls. Resend and Loops document an Idempotency-Key header held for 24 hours. For Postmark, SendGrid and SES you deduplicate yourself before each call.

How does the agent learn to stop?

Bounce and complaint events must reach a handler that cancels follow-ups to that address. Check how each webhook is protected (signature, basic auth, IP allowlist) because the agent will act on what arrives.

What does test mode really test?

Some modes validate the request and stop, some deliver to a trap, some still bill you. SendGrid's emits no events, Mailgun's counts as a send on your bill, and Postmark's fake bounces count toward monthly volume.

Can the agent fill a template instead of writing HTML?

Constraining the model to variables in a human-approved template shrinks what it can get wrong. Resend, Postmark, SendGrid, Mailgun, SES and Customer.io all send from stored templates, and Resend rejects a call that leaves a template variable unfilled.

What each provider documents for agent use

Provider Role Key scoping Idempotent send Webhook protection Test path Sequences by API
Postmark Sender Server token per server None listed Basic auth in URL, IP allowlist; payloads unsigned Sandbox mode, bounce-testing domain No
SendGrid Sender plus Marketing Campaigns Custom-access API keys None listed Signed event webhook or OAuth 2.0 sandbox_mode (validation only) Single Sends and automation stats
Mailgun Sender HTTP basic auth; narrower keys not checked None listed HMAC-SHA256 with a webhook signing key o:testmode (billed) No
Amazon SES Sender IAM policies, with recipient and From conditions None listed SNS topics or event publishing Account sandbox, mailbox simulator No
Resend Sender plus Marketing tab sending_access key, optional domain lock Yes, 24 hours Svix signature headers resend.dev test addresses Automations via API, CLI, MCP
Loops Lifecycle platform plus transactional Named keys, no permission levels listed Yes, 24 hours Signed webhook headers Preview endpoint for transactional email Workflows and campaigns via API, MCP, CLI
Customer.io Journeys platform App API key per workspace None listed Reporting webhooks, failed calls retried after an hour Test event for webhooks; no email sandbox checked Triggered automations and broadcasts; CLI built for agents

"None listed" means the field is absent from the vendor reference pages linked in that vendor's section below. It describes those pages, not the whole product.

Senders: your code owns the sequence

Postmark, SendGrid, Mailgun and Amazon SES take a message and deliver it. Waiting, branching and deciding who is eligible all happen in your own agent code.

Postmark

Sender with separate transactional and broadcast streams

Keys and scope. Every send is a POST /email with an X-Postmark-Server-Token header, and the Email API reference describes that token as carrying server-level privileges, found on the API Tokens tab of a single server. No narrower send-only credential appears on that page, so the practical boundary is the server itself: give each agent or environment its own server and token. The API overview returns error code 10 when the wrong token type is used for an endpoint.

Retries and duplicates. The send endpoint's field list (From, To, Subject, the two bodies, Tag, Metadata, MessageStream and a few more) has no idempotency key, so duplicate protection is yours to build. The response includes a MessageID that the single-send guide says to log and later match against bounces from the webhook or the API. Your own event id in Metadata gives a second handle to check against.

Limits. The documented ceilings are sizes: 50 recipients across To, Cc and Bcc per message, and 500 messages or 50 MB per batch call. Those pages state no requests-per-second figure, so confirm with support before an agent fans out thousands of calls.

Webhooks and stop signals. Postmark posts delivery, bounce, spam complaint, open, click and subscription-change events to your URL. It does not sign them. The webhooks guide tells you to protect the endpoint with basic HTTP authentication placed in the URL plus an allowlist of Postmark's IP ranges, and its sample handler validates the payload shape before acting. Postmark also tests the endpoint when you save a webhook and pauses an event type that keeps failing, which means a dead bounce handler surfaces as a status. For an agent, a paused bounce stream is the condition worth alerting on.

Test path. Sandbox mode exists so that CI runs and experiments never reach real recipients. For bounce handling, mail to the bounce-testing.postmarkapp.com domain produces a genuine bounce record. A hard-bounce address also lands on the stream's suppression list, and these test messages still count toward monthly volume. The guardrails section shows the documented request body for a soft bounce.

Templates. POST /email/withTemplate takes a TemplateId or a TemplateAlias plus a TemplateModel object, and a batch variant exists (Templates API). Aliases let a prompt say "send the refund-confirmation template" without the model ever seeing a numeric id.

Suppression. Suppressions live per message stream. The Suppressions API can dump, create (50 per call) and delete them, with the reasons HardBounce, SpamComplaint and ManualSuppression, and deleting a HardBounce suppression is the same as reactivating that bounce. A send to an inactive recipient fails with error code 406. Treat the delete call as a human decision rather than an agent tool.

Sequences. There is no sequence builder behind the API. Message streams separate transactional from broadcast traffic, and broadcast streams require unsubscribe handling while transactional and inbound ones default to none (Message Streams API). If an agent needs a drip, your scheduler decides when to call the send endpoint.

Price. From Postmark's pricing page: Basic, Pro and Platform start at $15, $16.50 and $18 for 10,000 emails a month. The slider reads $55, $60.50 and $66 at 50,000, and $115, $126.50 and $138 at 125,000, with no 100,000 stop. The free plan allows 100 emails a month and no overages.

SendGrid

Email API and Marketing Campaigns under Twilio

Keys and scope. SendGrid's API key guide lists four permission types: Full Access, Custom Access (you pick endpoints and access levels), Billing Access and Email Address Validation Access. Custom Access limited to Mail Send is the one an agent should hold. A key cannot receive more permission than its creator has, the console shows the secret only once, and an account may hold 100 keys, which is enough for one per agent.

Limits. The v3 API sets limits per endpoint and reports them in X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset headers; exceeding one returns 429 (rate limit docs). An agent should read those headers instead of hard-coding a number.

Retries, scheduling and undo. The Mail Send reference has no idempotency field. It does have send_at, which schedules a send up to 72 hours ahead, and batch_id, which lets a batch be paused or cancelled through the Scheduled Sends API. That pair is the nearest thing to an undo button among the senders here.

Webhooks and stop signals. The Event Webhook reports processed, delivered, deferred, bounce and dropped delivery events, plus open, click, spam report and unsubscribe engagement events (event reference). Agents tend to miss the dropped event: SendGrid drops mail to an unsubscribed, previously bounced or spam-reporting address, so a send can be accepted and still never leave. Protect the endpoint with the signed webhook (an X-Twilio-Email-Event-Webhook-Signature header checked against a public key), OAuth 2.0, or both.

Test path. Sandbox mode validates a Mail Send request without delivering it, answering 200 instead of the usual 202. It creates no events and uses no credits, and a template id is assumed to hold content rather than checked. It proves the payload is well formed. It cannot rehearse your bounce handler.

Templates. Dynamic template ids begin with d- and take their data through dynamic_template_data, rendered with Handlebars (dynamic templates guide).

Sequences. The API reference menu lists Single Sends and automation statistics. Creating an automation is not among the listed endpoints, so sequence design stays in the dashboard while an agent can create one-off sends and read results.

Price. The Email API pricing page offers 100 emails a day free for 60 days, then Essentials from $19.95 a month, whose selector reads $19.95 at 50,000 emails and $34.95 at 100,000. Pro reads $89.95 at 100,000. Marketing Campaigns has its own free plan of 2,000 contacts and 6,000 emails a month.

Mailgun

Sender with HMAC-signed webhooks and plan-based log retention

Keys and scope. The Messages endpoint authenticates with HTTP basic auth. Webhook calls are signed with an account-wide webhook signing key that is separate from your API key. The send reference describes no narrower send-only credential, so look in the control panel for one before handing an agent the primary key.

Retries and duplicates. That same reference has no idempotency key for sends. The only one on the page belongs to Inbox Placement tests, so deduplication stays with you.

Webhooks and stop signals. Webhooks can be configured at account or domain level for accepted, delivered, temporary_fail, permanent_fail, opened, clicked, unsubscribed and complained events (webhooks guide). Each post carries a token, a timestamp and a signature, and the signature is a hex HMAC-SHA256 of timestamp plus token keyed with the signing key (securing webhooks). A handler can therefore reject a forged bounce before an agent acts on it.

Test path. Setting o:testmode=yes makes Mailgun accept a message without sending it, and the test mode guide warns that you are charged for those messages. An agent test suite that loops over thousands of fixtures in test mode therefore shows up on the invoice.

Templates and correlation. Stored templates are referenced by name, with an optional version and variables passed as JSON. recipient-variables merges per-recipient values into a single batch call, and custom v: variables are echoed in events, which makes them a convenient carrier for your own job id.

Price. Mailgun's pricing page lists Free at 100 emails a day, Basic at $15 for 10,000 a month, Foundation at $35 for 50,000 and Scale at $90 for 100,000. Log retention grows from 1 day on Free and Basic to 5 days on Foundation and 30 on Scale. Retention matters for agents because the log is how you reconstruct what a misbehaving run actually sent.

Amazon SES

Sender governed by AWS IAM, quotas and SNS

Keys and scope. Access runs through IAM. A policy grants actions such as ses:SendEmail, and condition keys can restrict ses:Recipients (To, CC and BCC), ses:FromAddress and ses:FeedbackAddress (IAM guide). That is a recipient allow-list enforced by the platform's permission system, which none of the other providers' pages checked here describe.

Sandbox and quotas. New accounts start in a per-region sandbox: mail goes only to verified addresses or the mailbox simulator, at most 200 messages per 24 hours and one per second (production access guide). Beyond the sandbox, sending quotas still limit daily volume and send rate, count per recipient rather than per message, and reject a call that would exceed the daily maximum. AWS recommends one SendEmail call per recipient, since a failed call rejects the whole message.

Retries and duplicates. The SendEmail reference lists no client token, so the check for an earlier send runs in your code before the call.

Webhooks and stop signals. SES has no webhook of its own. Bounce and complaint events arrive by email, through an SNS topic, or as event publishing via configuration sets, and if you set up none of them SES forwards bounces and complaints to the Return-Path address (notifications guide). The SNS route, ending at a queue or function, is the one most agent stacks will build.

Test path. The mailbox simulator accepts success@, bounce@, ooto@, complaint@ and suppressionlist@simulator.amazonses.com, each producing the matching outcome.

Suppression. Accounts created after 25 November 2019 use the account-level suppression list for bounces and complaints by default. SES accepts a message to a suppressed address without sending it, and the message still counts toward the daily quota (suppression list guide).

Price. AWS's pricing page shows new accounts starting on the Essentials plan at $0.16 per 1,000 emails for 0 to 10 million a month. Pro and Enterprise charge $0.22 and $0.23 per 1,000, plus fixed fees of $105 and $500 per account per region per month.

Two more senders worth knowing: Mailtrap and MailerSend

A sandbox you can flip to production, and domain-scoped API tokens

Mailtrap. Its Email Sandbox is a fake SMTP server that captures test mail so it never reaches real recipients, and it needs no domain verification. In the official SDKs the switch to live sending is a sandbox flag plus an inbox id in the client constructor: set the flag to false and drop the id. That makes an agent's staging and production runs differ by one configuration value. The billing plans page lists sending at $15 for 10,000 emails a month, $20 for 50,000 and $30 for 100,000 on Basic, and $85 at 100,000 on Business.

MailerSend. API tokens are generated for a sending domain and carry scopes, so a token can be limited to one domain and the areas it needs. The webhook list covers activity.sent, delivered, soft_bounced, hard_bounced, opened, clicked, unsubscribed and spam_complaint, with deferred and suppressed on paid plans only. Its pricing page gives the free plan 500 emails a month and 100 daily API requests, which an agent in a loop can exhaust quickly, and lists Starter at $31.50 a month for 50,000 emails (billed yearly at $378).

Platforms: the vendor owns the sequence

Resend's Marketing tab, Loops and Customer.io let an agent report an event and leave the timing, eligibility and delivery to the vendor. That shrinks what the agent can do wrong per call and widens what a wrong call can reach.

Resend

Sending API plus a Marketing tab with automations, an MCP server and a CLI

Keys and scope. Resend's API key page and the create-key reference describe two permissions, full_access and sending_access, and a sending key can be locked to one verified domain. Permission and domain can be changed only in the dashboard, since the update endpoint renames a key and nothing else, so an agent holding a sending key has no route to widen it. The dashboard shows each key's last use and request logs, and the page suggests deleting keys unused for 30 days.

Limits. The usage limits page sets a default of 10 requests per second per team across all keys, answered by ratelimit-limit, ratelimit-remaining, ratelimit-reset and retry-after headers and a 429. Quotas are a separate meter. The free plan has a daily cap that resets at midnight UTC, every plan has a monthly one, and exceeding either returns 429 with daily_quota_exceeded or monthly_quota_exceeded.

Retries and duplicates. Send Email and Send Batch accept an Idempotency-Key header, exposed as idempotencyKey in the SDKs, up to 256 characters and remembered for 24 hours (idempotency docs). Reusing a key with a different payload returns 409 invalid_idempotent_request, and a request still in flight returns 409 concurrent_idempotent_requests, which is safe to retry later. The code sample in the guardrails section is taken from those docs.

Webhooks and stop signals. Event types include email.sent, email.delivered, email.delivery_delayed, email.bounced, email.complained, email.failed and email.suppressed, along with contact and domain events (event types). Requests carry Svix headers, and the SDK's verify call needs the raw request body because re-serialised JSON breaks the signature (verification guide). A missed event can be replayed.

Test path. Addresses at resend.dev simulate outcomes: delivered@, bounced@, complained@ and suppressed@resend.dev. A label after a plus sign, such as delivered+signup@resend.dev, separates scenarios in your logs (test emails). The page asks you not to send to invented addresses during testing, because the resulting bounces count against your own domain.

Templates. A published template is sent by id or alias with a variables object. It cannot be combined with html, text or react in the same call, and a call that leaves a variable unfilled fails validation (Send Email reference). FIRST_NAME, LAST_NAME, EMAIL and UNSUBSCRIBE_URL are reserved variable names.

Suppression. An address is suppressed after a hard bounce, a complaint or a manual entry, for the whole team and every domain, for transactional and broadcast mail alike. The list is readable and writable through the API (bulk calls take 100 addresses), and suppression.added and suppression.removed webhooks announce changes. An address removed before its cause is fixed gets suppressed again (suppressions).

Scheduling and cancel. scheduled_at accepts times up to 30 days ahead (schedule docs), and a scheduled email can be removed with the cancel endpoint. Together they give you an approval window.

Sequences and agent tooling. On the Marketing tab, Automations start from custom events your app sends and chain steps that send an email or manage a contact, delay, wait for an event, or branch on a condition. They can be created and inspected through the API, the CLI and MCP, and every trigger produces a run you can debug. The hosted MCP server at mcp.resend.com signs in with OAuth and exposes emails (send, cancel, update, batch), templates, contacts, broadcasts, automations, events, API keys, webhooks and logs. An agent connected that way holds far more than send access, so choose deliberately which tools it may call.

Price. Resend's pricing page lists Free at 3,000 emails a month and 100 a day. Pro is $20 for 50,000 emails and reads $35 at 100,000, and Scale is $90 for 100,000 and $160 at 200,000. The Marketing tab is free up to 1,000 contacts with 10,000 automation runs and 3 segments, then reads $40 at 5,000 contacts, $80 at 10,000, $250 at 50,000 and $450 at 100,000.

Loops

Lifecycle platform with event-triggered workflows and agent tooling

Keys and scope. Requests carry a Bearer API key generated under Settings, and the API introduction suggests a separate key for each purpose, lets you revoke any key, and warns against exposing it client-side. No per-key permission levels are listed, so the real boundary is which code path holds the key.

Limits. The baseline is 10 requests per second per team, with a stricter 60 requests per 60 seconds per team for the content API (campaigns, email messages, transactional emails, workflows and similar endpoints). Responses carry x-ratelimit-limit and x-ratelimit-remaining, and exceeding the limit returns 429; Loops recommends retries with exponential backoff and offers higher limits on request. An agent that edits workflows through the API reaches the 60-per-minute ceiling long before the 10-per-second one.

Retries and duplicates. Send event and send transactional email both take an Idempotency-Key header of up to 100 characters. Reusing a key within 24 hours returns 409 Conflict.

Webhooks and stop signals. An account has one webhook endpoint, signed with webhook-id, webhook-timestamp and webhook-signature headers and delivered at up to 10 events per second (webhooks). Email events are delivered, softBounced, hardBounced, unsubscribed and spamReported. A hard bounce unsubscribes the contact, so a contact.unsubscribed event follows it. The API can also check a contact's suppression status and remove the suppression, which is another call to keep out of an agent's toolbox.

Sequences and agent tooling. A POST to the events endpoint names a contact and an event, and any published workflow listening for it takes over the waiting and sending. The API also lists, creates and updates workflows, campaigns and email content, and Loops offers an MCP server plus a CLI with agent skills for coding agents. Transactional email has a preview endpoint for test sends.

Price. Loops' pricing page shows a free plan with unlimited contacts but sends capped at 4,000 in any rolling 30 days to the 1,000 newest contacts, plus a Powered by Loops footer. Paid plans scale with subscribers, reading $99 a month at 9,998 and $249 at 49,989 on the dated slider, and transactional sending is included.

Customer.io

Journeys platform with separate APIs for data, sending and agents

Keys and scope. Customer.io splits access by API. Track and Pipelines use basic authorization, the App API uses bearer authorization, and an App API key covers one workspace (API overview, transactional guide). The cio CLI is built for coding agents and signs in with service-account tokens, which the docs say are for setting up and testing transactional messages and never for production code.

Limits. Track and Pipelines allow 3,000 requests per 3 seconds as a soft limit that is not enforced with 429s. The App API allows 10 requests per second and answers excess with 429 and a Retry-After header, and transactional sends share the 3,000-per-3-seconds figure. Message frequency limits are a different feature that caps how many messages one person receives in a time frame, and an agent-driven journey is where to switch them on.

Transactional sends. Each send should reference a transactional_message_id. Without it the message is tracked as uncategorized, which mixes the metrics of every send type, and through the CLI an agent can pass auto_create to have the record made on first use. If the recipient does not exist yet Customer.io creates the person, so validate addresses before the call or a typo becomes a profile.

Webhooks and stop signals. Reporting webhooks post events such as email_sent, email_delivered, email_bounced, email_dropped, email_spammed, email_failed, email_undeliverable and email_unsubscribed. Failed calls are retried in a batch after an hour, a disabled webhook does not backfill what it missed, and payloads can gain fields without notice, so a handler should ignore keys it does not know (reporting webhooks).

Sequences and agent tooling. Event-triggered automations are the core product: code or an agent records an event and a journey handles delays and eligibility. The App API triggers broadcasts and transactional messages and fetches data. The CLI wraps the Journeys and Data Pipelines APIs behind one cio api command, publishes cio schema for each endpoint, and installs skills for assistants such as Claude Code.

Price. Customer.io's pricing page shows Essentials at $100 a month at 5,000 profiles, $145 at 10,000 and $505+ at 50,000, with 1M email sends included. It meters profiles, not sends. Premium starts at $1,000 a month billed yearly, and companies that have raised under $10M can apply for 12 months free through the Startup Program.

Guardrails for an agent that can press send

None of these controls come from a model's good behaviour. They are ordinary engineering around a tool that has side effects in the real world, and each one maps onto something the providers above already expose.

Human approval before anything leaves

Split drafting from sending. The agent writes a message into a review queue, a person approves it, and a separate sender job holds the API key. When you want the provider to hold the message during review, use a scheduled send: Resend takes scheduled_at up to 30 days ahead and has a cancel endpoint, and SendGrid takes send_at with a batch_id that can be paused or cancelled. Require approval by default for a first message to a new recipient, any message to a list rather than a person, and any change to a template or automation that others will receive.

Recipient allow-lists

Check the recipient against your own source of truth immediately before the call, not inside the prompt. In development and staging, accept only addresses on your own domain. Where the provider can enforce it, do so: Amazon SES lets an IAM policy restrict ses:Recipients, and an SES account in the sandbox can only mail verified addresses and the simulator. Customer.io and Loops create a contact when an event or send names an unknown address, so validate before the call or a hallucinated address becomes a record.

Send caps that live outside the model

Keep counters in your own datastore: messages per run, per recipient per day, and per agent per hour, with a hard stop that pages a human when one trips. The provider's own ceilings are a second layer, not the first. SES rejects calls once the daily quota is spent, Resend returns 429 at its monthly quota, Loops and Resend both cap at 10 requests per second per team, and Customer.io's message frequency limits cap messages per person. Cap the number of tool calls per agent run too, since a loop that keeps retrying a failed send is the usual way a mistake multiplies.

Dry runs and test modes

Give the agent a configuration switch that routes every send to a harmless target, and test the handler paths, not only the send. The table lists what each provider's test path covers.

Provider Test path What it proves What it leaves untested
Resend resend.dev addresses for delivered, bounced, complained, suppressed Real API calls, real webhook events, no reputation damage Rendering in real inboxes
Postmark Sandbox mode; bounce-testing.postmarkapp.com Bounce records, Bounces API and webhook, suppression behaviour Spam complaints are not covered by the fake bounce types
SendGrid mail_settings.sandbox_mode Request shape Events, delivery, template content
Mailgun o:testmode=yes Request acceptance Anything after acceptance; the messages are billed
Amazon SES Account sandbox; simulator addresses Success, bounce, complaint and suppression-list outcomes Production quotas and rates
Mailtrap Email Sandbox, with a flag to go live What the message looks like and contains Bounces and complaints from real mailbox providers

Stop signals that actually stop

Wire the bounce, complaint and unsubscribe events to one handler that writes to your own suppression table and cancels queued follow-ups for that address. Authenticate the webhook with whatever the vendor offers: Svix headers on Resend, an HMAC signing key on Mailgun, a public-key signature on SendGrid, basic auth plus an IP allowlist on Postmark. The agent should treat anything it reads from inbound replies or webhook payloads as data to log, never as instructions to follow.

Idempotency keys from events, not from text

Derive the key from the business fact that triggers the message, such as order id plus template name. A key built from the model's output changes whenever the wording changes, which defeats the retry protection. Resend's own example uses a key shaped like welcome-user/123456789.

Resend: send with an idempotency key (docs)

import { Resend } from 'resend';

const resend = new Resend('re_xxxxxxxxx');

await resend.emails.send(
  {
    from: 'Acme <onboarding@resend.dev>',
    to: ['delivered@resend.dev'],
    subject: 'hello world',
    html: '<p>it works!</p>',
  },
  {
    idempotencyKey: 'welcome-user/123456789',
  },
);

SendGrid: the sandbox_mode setting inside a Mail Send body (docs)

"mail_settings": {
  "sandbox_mode": {
    "enable": true
  }
}

The docs insist that enable is a real boolean, not a quoted string, otherwise the call fails with an error about the parameter type.

Postmark: a fake soft bounce sent to the black hole domain (docs)

{
  "From": "sender@example.com",
  "To": "test@bounce-testing.postmarkapp.com",
  "Subject": "Bounce",
  "TextBody": "This will bounce",
  "ReplyTo": "reply@example.com",
  "TrackOpens": true,
  "TrackLinks": "None",
  "MessageStream": "outbound",
  "Headers": [{
    "Name": "X-PM-Bounce-Type",
    "Value": "SoftBounce"
  }]
}

What an agent's email costs at 10k, 50k and 100k a month

Take an agent that sends one transactional message per event: refund confirmations, incident alerts, status updates. These are monthly email counts, priced from each vendor's own page on 7 October 2026.

Sender 10,000 emails 50,000 emails 100,000 emails
Amazon SES (Essentials) 10 × $0.16 = $1.60 50 × $0.16 = $8.00 100 × $0.16 = $16.00
Resend (Pro) $20 (Free stops at 3,000) $20 $35 on Pro; $90 on Scale
Mailtrap (Basic) $15 $20 $30
Mailgun $15 (Basic) $35 (Foundation) $90 (Scale)
Postmark (Basic / Pro / Platform) $15 / $16.50 / $18 $55 / $60.50 / $66 No 100k stop; 125k reads $115 / $126.50 / $138
SendGrid (Email API) No paid tier listed below 50,000; the free trial is 100 a day for 60 days $19.95 (Essentials) $34.95 Essentials; $89.95 Pro
MailerSend No flat price listed: Hobby includes 5,000 and bills extra usage per 1,000 $31.50 (Starter, billed yearly) $68 (Starter, per its pricing FAQ)

The spread is large but mostly irrelevant at 10,000 emails: every row sits between $1.60 and $20, so choose on the controls described above. It matters at 100,000, where SES is the cheapest row and Mailgun Scale, at $90, is the dearest. The SES figure is pure arithmetic (thousands of emails times $0.16), and its quotas and sandbox mean you must also budget time for production access. Resend's two 100,000 figures differ because the slider reads Pro at $35 while the Scale plan lists $90 for 100,000 with its own feature set, so check which plan features you need before comparing. Postmark's slider skips from 50,000 to 125,000, so its nearest comparable reading sits above this row.

If the same agent also runs lifecycle sequences, the meter changes from emails to people. These are monthly prices by contact or profile count, from each vendor's pricing page.

Platform 10,000 contacts 50,000 contacts 100,000 contacts
Resend Marketing $80 $250 $450
Loops $99 (at 9,998 subscribers) $249 (at 49,989) Not read from the slider
Customer.io Essentials $145 $505+ Not listed; the selector tops out at 50k+ and points to Premium, which starts at $1,000

Read those two tables together. A delivery plan at $20 and an audience plan at $80 to $145 for 10,000 people are not competing for the same job: the first charges for delivery and leaves sequencing to your code, the second charges for the audience and runs the timing, eligibility and unsubscribes for you. An agent that only confirms refunds and sends alerts never needs the second table. An agent that onboards users over three weeks probably does, because building and monitoring that timing yourself costs engineering time that the contact-based price replaces.

Choose A if, choose B if

Choose Amazon SES if

The agent already runs on AWS and you want the platform's permission system to enforce which recipients and From addresses it may use. You accept that templates, sequencing and webhook plumbing are yours to assemble, and that a new account has to leave the sandbox first.

Choose Resend if

One vendor should cover transactional sends and a first layer of automation, with sending-only keys locked to a domain, retry-safe sends and ready-made test addresses. Plan for the 10 requests per second that every key on a team shares, and decide which MCP tools the agent really needs.

Choose Postmark if

The agent mostly sends receipts and alerts from templates, and you want transactional and broadcast traffic kept apart in separate streams, with one server and token per agent. You must be comfortable protecting unsigned webhooks with basic auth and an IP allowlist, and with building your own duplicate check.

Choose SendGrid if

You want custom-access keys, a signed event webhook, and scheduled sends that a batch id lets you pause or cancel. Its Email API plans begin at 50,000 emails a month, so it fits poorly below that volume.

Choose Mailgun if

Audits matter: you want HMAC-signed webhooks and up to 30 days of logs on the Scale plan to reconstruct what an agent sent. Remember that test mode is billed, so keep large fixture runs on another path.

Choose Loops if

The agent should report product events and let published workflows run the timing, with idempotent event calls and a price that starts free. You accept that keys have no listed permission levels and that content-API calls are limited to 60 a minute.

Choose Customer.io if

Journeys will branch across several channels, you want message frequency limits to cap what any one person receives, and a CLI designed for coding agents appeals. Budget for profile-based pricing that starts at $100 a month.

Choose Mailtrap alongside any of them if

You want staging runs captured in a sandbox inbox and production reached by flipping a single flag. If the agent must also reach people by push or in-app message, a notification layer such as Novu, Knock or Courier sits above the email provider; this page does not evaluate those.

Narrowed it to two providers?

Head-to-head pages cover the pairs agent builders most often weigh, and the transactional guide explains where one-off sends end and sequences begin.

Questions about email for AI agents

Which email API is safest to give an AI agent?

Safest means the key can do the least. Resend lets you create a sending_access key restricted to one verified domain, SendGrid offers custom-access keys that grant only chosen endpoints, and Amazon SES uses IAM policies that can restrict which recipient and From addresses a caller may use. Postmark ties a server token to one server, so a separate server per agent is the nearest equivalent. Whichever you choose, keep the key in the sending service, not in the model context.

How do I stop an agent from sending the same email twice?

Resend and Loops both accept an Idempotency-Key header and remember the key for 24 hours, so a retried request returns the original result instead of sending again. The Postmark, SendGrid and SES send references list no such field, so there you keep your own record of sent events and check it before every call. Build the key from the business event, such as an order id plus a template name, never from text the model generated.

What should an agent do when an email bounces or draws a spam complaint?

Stop writing to that address and tell the rest of the system. Every vendor on this page emits bounce and complaint events through webhooks, SNS or event publishing, and most also keep a suppression list that silently skips suppressed addresses on later sends. Give the agent a hard rule that a bounce or complaint event cancels pending follow-ups for that recipient, and review suppressions before anyone removes an address.

Can an agent run email sequences, or only send single messages?

Customer.io, Loops and Resend (through its Marketing tab) expose automations or workflows that an API call can start with an event, and all three document agent tooling in the form of MCP servers or a CLI. Postmark, Mailgun and Amazon SES are senders: the schedule, the waiting and the branching stay in your own code. SendGrid sits between the two, with Single Sends in its API and automation statistics.

How can an agent test email without messaging real people?

Use the provider's own test path: Resend has resend.dev test addresses for delivered, bounced, complained and suppressed outcomes, Postmark has sandbox mode and a bounce-testing domain, Amazon SES has a mailbox simulator while an account is in the sandbox, and Mailtrap's Email Sandbox captures test mail instead of delivering it. SendGrid's sandbox mode only validates the request and produces no webhook events, so it cannot rehearse your bounce handler.