- Amazon SES is outbound email at $0.10 per 1,000 messages; receiving routes raw MIME to S3, SNS, or Lambda, not an inbox.
- PostNuvia provisions a real inbox (address, storage, threading, webhooks, MCP) in one API call.
- SES fits send-only, AWS-native, million-message workloads; PostNuvia fits two-way agent loops and multi-tenant identity.
- Of seven agent-loop steps, SES covers send and raw receive; the rest is customer-built.
- Free plan includes real send and receive with no credit card.
Amazon SES is a high-volume send pipeline. PostNuvia is an inbox. For an agent that sends, receives, threads, and replies, SES leaves parsing, storage, threading, and identity to the team, while PostNuvia ships those as the inbox primitive. This page maps the seven loop steps, the receive-side build cost, side-by-side code samples, and when SES is still the right call.
When SES is the right call
Pick SES when the workload is send-only, the team already lives in AWS day to day, volume is in the millions of messages per month, or raw MIME in S3 is an acceptable receive shape.
Pick SES if any of the following describes the use case:
- Send-only workloads. Password resets, transactional notifications, marketing broadcasts. No inbound, no threading, no replies to parse.
- The team is fluent in AWS. SES does not require an all-AWS stack, but the receive pipeline leans on Lambda, S3, and DynamoDB, so it fits best when those are already part of daily work.
- Volume is in the millions of messages per month. SES per-email pricing is the lowest among mainstream providers.
- An inbox abstraction is not part of the requirement. Receiving as raw MIME in S3 is acceptable.
When PostNuvia is the right call
Pick PostNuvia when the agent needs two-way email, scoped identity per agent or tenant, MCP or webhook workflows, or a managed inbox instead of an S3 and Lambda stack.
Pick PostNuvia if any of the following describes the use case:
- The agent needs two-way email: send, receive, parse, thread, respond.
- Each agent or tenant needs a scoped identity (own address, own API key, isolated data).
- The team prefers a managed inbox layer over building one on top of S3, Lambda, and a database.
- The agent uses MCP or webhook-driven workflows.
- The team wants full inbox functionality, threads, labels, and attachments through a clean REST API, rather than assembling it across the AWS SDK.
- The agent is built on a coding platform like OpenClaw or Hermes.
- Receiving needs to work in any AWS region.
What each one is built for
Amazon SES launched in January 2011 as a high-volume sending service from inside AWS, with receive added later as routing rather than as an inbox object.
Amazon SES launched in January 2011 as a high-volume sending service from inside AWS. The receive flow was added through receipt rules that route incoming mail to one of three downstream actions: an S3 bucket, an SNS topic, or a Lambda function. There is no inbox object in SES. Each incoming message lands as raw MIME, and the customer is responsible for parsing, storage, and threading.
PostNuvia is built around the inbox as the primitive. Each inbox has its own address, a persistent message store, automatic threading, webhooks, and WebSockets. Inboxes can be grouped into Inbox Pods that isolate one tenant from another.
The agent loop
An AI agent that uses email for work runs through a consistent set of operations across the full loop. Mapping each step to what each provider handles natively:
| Step in the agent loop | Amazon SES | PostNuvia |
|---|---|---|
| Send outbound message | Native | Native |
| Receive inbound message | Native (raw MIME to S3, SNS, or Lambda) | Native (webhook, WebSocket; see building-real-time-ai-agents-postnuvia-webhooks) |
| Parse content and attachments | Not included. Requires a MIME parser plus custom logic for attachment extraction | Built in |
| Thread reply against conversation | Customer-built (Message-ID parsing, DB) | Built in |
| Store conversation history | Customer-built (S3 + database) | Built in |
| Respond in-thread | Native send, customer-built threading | Native threaded reply API |
| Stable identity per agent | IAM + verified domain (no inbox primitive) | Inbox is the identity |
SES handles two of those seven steps. The rest sit on the customer's side.
What an PostNuvia subscription buys
An PostNuvia subscription buys engineering time, faster provisioning, inbox-shaped architecture, multi-tenant pods, and bundled MCP, webhooks, and compliance reporting.
- Engineering time you don't spend. Building a working receive pipeline on SES (receipt rules, Lambda parser, DynamoDB schema for threading, retry and replay logic, webhook fan-out) is a project that has to happen before the agent runs, plus ongoing maintenance. PostNuvia collapses that work into one API call to provision the inbox and a webhook URL to receive events.
- Time to first inbox. Provisioning an PostNuvia inbox is one API call. Provisioning the SES equivalent (verified sending domain, S3 bucket, receipt rule, Lambda, database, IAM policies) is configuration across several AWS services that has to be set up before the first message can be received and processed.
- Architectural fit. The inbox-as-primitive matches what an agent needs: a stable identity with its own address, history, and scoped credentials. SES does not have an inbox primitive. Building one on top of SES is doable but is building.
- Multi-tenant scale-out. PostNuvia's Inbox Pods isolate tenant data by default and let API keys scope to a specific pod. The SES equivalent is per-tenant S3 buckets or prefixes, per-tenant database scoping, per-tenant IAM policies, and offboarding cleanup across all of the above.
- What's bundled. MCP server for agent integrations, signed webhooks, suppression list, dedicated IPs on Enterprise (contact sales), and SOC 2 Type II reporting (Startup and above). On SES, each of these is either build-it-yourself, buy-from-a-separate-service, or inherit-from-the-AWS-account.
Code: the full agent loop
The send call looks similar on both providers. The receive flow does not, because SES stops at raw MIME.
PostNuvia
Source: https://raw.githubusercontent.com/postnuvia-to/postnuvia-python/main/reference.md and https://docs.postnuvia.com
from postnuvia import PostNuvia
from postnuvia.inboxes.types import CreateInboxRequest
client = PostNuvia(api_key="your_api_key")
# Provision an inbox
inbox = client.inboxes.create(
request=CreateInboxRequest(username="sales-agent")
)
# Send the first email
client.inboxes.messages.send(
inbox_id=inbox.inbox_id,
to=["lead@example.com"],
subject="Quick question",
text="Hi Alex, saw your post about email infrastructure..."
)
# Webhook handler for inbound replies
def on_inbound_email(payload):
message_id = payload["message"]["message_id"]
client.inboxes.messages.reply(
inbox_id=inbox.inbox_id,
message_id=message_id,
text="Thanks for getting back. To answer your question..."
)Amazon SES
The send is similar in size. The receive code below assumes the surrounding AWS configuration is already in place: verified sending domain, S3 bucket, SES receipt rule, Lambda function, DynamoDB tables, IAM policies. SES send and receive docs: https://docs.aws.amazon.com/ses/latest/dg/send-email.html and https://docs.aws.amazon.com/ses/latest/dg/receiving-email.html.
Source: https://docs.postnuvia.com
import boto3, email
ses = boto3.client('ses', region_name='us-east-1')
s3 = boto3.client('s3')
# Send
ses.send_email(
Source='sales-agent@yourdomain.com',
Destination={'ToAddresses': ['lead@example.com']},
Message={
'Subject': {'Data': 'Quick question'},
'Body': {'Text': {'Data': 'Hi Alex...'}}
}
)
# Lambda triggered when an inbound email lands in S3
def lambda_handler(event, context):
bucket = event['Records'][0]['s3']['bucket']['name']
key = event['Records'][0]['s3']['object']['key']
raw = s3.get_object(Bucket=bucket, Key=key)['Body'].read()
msg = email.message_from_bytes(raw)
# Parse threading headers manually
message_id = msg.get('Message-ID')
in_reply_to = msg.get('In-Reply-To')
references = msg.get('References', '')
# Look up thread state in DynamoDB
# ...query, conversation reconstruction...
# Build reply with proper threading headers
# ...attach In-Reply-To and References...
# ...send via ses.send_raw_email()...
# Persist new message
# ...DynamoDB write...
# Search requires a separate index pipeline if needed
# ...OpenSearch or Pinecone, kept in sync...The SES code above is incomplete because the surrounding AWS configuration is not part of the API call. That configuration is the project PostNuvia collapses into the inbox creation step.
Identity and multi-tenancy
For a multi-tenant agent product, the structural difference between SES account identity and PostNuvia inbox identity matters more than per-email cost.
On SES, the unit of identity is the AWS account and the verified sending domain. Multi-tenant isolation requires per-tenant S3 buckets or prefixes, per-tenant database schemas or row-level scoping, per-tenant IAM policies, and offboarding cleanup across all of the above.
On PostNuvia, each inbox is the unit of identity. Inboxes group into Pods, which isolate tenant data by default. API keys can be scoped to a specific pod, so a credential leak in one tenant's environment cannot reach another's mail.
Migrating from SES to PostNuvia
Send side: close to a drop-in replacement. boto3.client('ses').send_email becomes client.inboxes.messages.send with similar arguments.
Receive side: the larger change, and the larger savings. The S3 bucket, Lambda parser, database threading logic, and any search indexing pipeline get retired in favor of a webhook endpoint that handles PostNuvia's inbound events.
Custom domains: PostNuvia DNS records can run in parallel with SES records during the transition. Both providers operate concurrently while the migration completes.
Limitations
Amazon SES does not provide an inbox, threading, or multi-tenant pod model; you build those. PostNuvia is not the lowest per-email price at million-message send volumes, and it is not a general AWS email console replacement for teams that only need outbound.
Choosing between them
Amazon SES is the right call for send-only workloads, AWS-native teams, and high-volume outbound mail at the lowest per-email price.
Amazon SES is the right call for send-only workloads, AWS-native teams, and high-volume outbound. PostNuvia is the right call for AI agents that send and receive, multi-tenant agent products, and teams that prefer a managed inbox layer over building one. See also why Gmail and SendGrid don't work for AI agents, 5 best email APIs compared, and real-time agents with webhooks.
The Free plan provisions real inboxes with full sending and receiving. No credit card required.
PostNuvia is the first email provider built for AI agents. Create an inbox in one API call, send and receive email, no OAuth and no domain verification. Free tier, no credit card required.

![6 Best Email API For Developers Compared [2026]](/_next/image?url=%2Fblog%2Femailapi1.png&w=3840&q=75&dpl=dpl_9Xxp5qEkSmTW17MqAGhxjJiNDjB9)
