SMTP relay service
Amazon SES logo

Amazon SES API + MCP (2026): SES v2 REST, SigV4, 10 SDKs

Amazon SES exposes a full REST/JSON control plane through the SES v2 API (API version 2019-09-27, service id sesv2) and ships first-party SDKs for 10 languages plus the AWS CLI v2. Every call is signed with SigV4 against a regional endpoint (https://email.{region}.amazonaws.com), so the same IAM policies, roles, and CloudTrail auditing that govern the rest of your AWS account also govern email sending. On the MCP front, however, AWS has not shipped a production-grade first-party MCP server dedicated to SES as of August 2026 — agents rely on the general-purpose AWS MCP Server (GA May 2026), the AWS-authored sample repo, or community wrappers.

At a glance

v2
SES API version
Model dated 2019-09-27, service id sesv2, JSON payloads, SigV4 signing.

10
Official SDKs
Python, Node, Java, Go, .NET, PHP, Ruby, Rust, Kotlin, plus AWS CLI v2.

No
First-party MCP
No dedicated production SES MCP server — AWS sample + community wrappers only.

MCP integration in 2026

Model Context Protocol lets AI agents call SES actions (send email, add contacts, list identities) as typed tools instead of raw REST calls. AWS shipped a general-purpose MCP surface in 2026 but has still not published a production-ready MCP server dedicated to SES — a gap worth flagging before wiring agents to your sending account.

No official SES-dedicated MCP server — general AWS MCP Server + samples only

AWS has not released a first-party, production-grade MCP server scoped to SES. The aws-samples/sample-for-amazon-ses-mcp repo exposes every public SES v2 action to MCP clients, but the README explicitly labels it a sample built on the in-development Smithy Java MCP integration and warns against production use. The closest first-party path is the general AWS MCP Server, which reached GA on May 15, 2026 and can drive SES alongside every other AWS service.

Available MCP servers

Five MCP entry points can address SES today. Only two carry an AWS label, and neither is a production-hardened SES-only server.

Why buyers should care. If you already run agents on Amazon Q Developer or Claude Desktop, the general AWS MCP Server plus tight IAM scoping is the safest 2026 pattern: reuse existing SES policies, get CloudTrail audit trails for free, and avoid trusting a community wrapper with your production access. If you want a dedicated SES tool surface today, expect to run the aws-samples repo yourself and treat it as a sample — not a managed service — until AWS ships a first-party production server. Contrast this with Postmark, Mailgun, and SendGrid, all of which are also community-MCP-only in 2026.

Amazon SES API essentials

Base URLhttps://email.{region}.amazonaws.com — e.g. https://email.us-east-1.amazonaws.com. Regional endpoint is mandatory; there is no global SES endpoint.
API versionSES v2 (2019-09-27), service id sesv2. SES v1 (ses) remains for backward compatibility only.
ProtocolHTTPS REST/JSON, signed with AWS Signature Version 4. TLS 1.2+ required.
Response formatJSON. Errors return AWS-standard Code / Message shapes with X-Amzn-RequestId headers for support cases.
TimeoutDefault SDK request timeout is 60 s. No fixed server-side max is documented per call; long operations expose asynchronous jobs.
PaginationCursor-based with NextToken. List calls accept PageSize and return NextToken when more results exist.
IdempotencyNo global Idempotency-Key header. Most mutating actions (identity/template create) are naturally idempotent via unique names; SendEmail is not — retries on 5xx can double-send if not gated.
Bulk operationsSendBulkEmail accepts up to 50 Destinations per call against a templated message.
IPv6Dual-stack SMTP and API endpoints supported since May 2025.

Resources are grouped by function — email identities, templates, contact lists, configuration sets, event destinations, suppression, dedicated IP pools, and account-level settings — and most operations map cleanly to REST verbs. The v2 API is intentionally leaner than v1: several legacy actions were dropped or renamed, so migrating from ses to sesv2 usually means changing the client, not just the endpoint.

Authentication methods

AWS Signature Version 4 (SigV4)

Every SES v2 HTTPS call is signed with SigV4 using an AWS access key ID and secret access key. Long-lived IAM user keys are supported but not recommended for production — prefer roles. The SDKs handle SigV4 transparently once credentials are resolved via the default provider chain (environment, shared config file, EC2/ECS/EKS/Lambda role, IAM Identity Center).

IAM roles + STS temporary credentials

Production workloads should assume a role through an EC2 instance profile, ECS task role, EKS IRSA, or Lambda execution role. Short-lived credentials are issued by STS automatically and rotated by the AWS runtime, and every SES action is auditable in CloudTrail with the role’s ARN. IAM Identity Center (AWS SSO) is the recommended human path for CLI-driven operations.

IAM SMTP credentials (SMTP interface only)

The SMTP endpoint uses a separate credential pair: a 20-char IAM SMTP username and a 44-char IAM SMTP password derived from an IAM user secret via HMAC-SHA256. These are region-specific and generated in the SES console or with the smtp_credentials_generate.py helper. Authentication is AUTH LOGIN over TLS; SES rejects unencrypted SMTP connections.

Scope caveat. There is no per-key OAuth scoping like Mailchimp or SendGrid. All access is governed by IAM policies attached to the caller (user, role, or SMTP-generating IAM user). Grant only ses:SendEmail, ses:SendBulkEmail, and the specific list/manage actions each workload needs — a blanket ses:* policy against your production account is a common audit finding.

Rate limits

LimitValueNotes
Sandbox daily cap200 messages / 24 hHard cap for new accounts (and each new region) until production access is granted. Send only to verified addresses.
Sandbox send rate1 msg/secPer-second rate applied on top of the daily cap while in sandbox.
Production initial rate14 msg/secTypical starting rate after production access is granted; auto-scales upward on healthy sending patterns.
Recipients per message50Combined To + Cc + Bcc per message. SendBulkEmail allows up to 50 Destinations per call.
Message size40 MBRaw payload after base64 encoding, SES v2 and SMTP. SES v1 legacy SendEmail still caps at 10 MB. Messages larger than 10 MB are bandwidth-throttled to about 40 MB/s.
Concurrent SMTP connectionsNot publishedAWS does not disclose a fixed concurrent SMTP count — throughput is expressed as msg/sec.
API requests per minuteNot published as a single RPMEach administrative action has its own throttling profile plus the per-account send rate.

SES throttles on the send rate (msg/sec) rather than a public RPM figure, and every administrative action has its own quota. For bursty workloads, batch through SendBulkEmail, use a configuration set with an SNS or CloudWatch event destination to observe rejections, and implement exponential backoff on Throttling and ThrottlingException errors — the AWS SDKs ship this retry policy by default but the intervals are worth tuning for spiky traffic.

Official SDKs

AWS ships and maintains SES v2 clients across every mainstream backend language plus the CLI. All track the current sesv2 Smithy model, receive monthly-cadence releases, and are covered by AWS support.

LanguagePackageInstallRepo
Pythonboto3 (client sesv2)pip install boto3boto/boto3
JavaScript / TypeScript (Node)@aws-sdk/client-sesv2npm install @aws-sdk/client-sesv2aws/aws-sdk-js-v3
Javasoftware.amazon.awssdk:sesv2Maven / Gradle dependencyaws/aws-sdk-java-v2
Gogithub.com/aws/aws-sdk-go-v2/service/sesv2go get github.com/aws/aws-sdk-go-v2/service/sesv2aws/aws-sdk-go-v2
.NET (C#)AWSSDK.SimpleEmailV2dotnet add package AWSSDK.SimpleEmailV2aws/aws-sdk-net
PHPaws/aws-sdk-php (SesV2Client)composer require aws/aws-sdk-phpaws/aws-sdk-php
Rubyaws-sdk-sesv2gem install aws-sdk-sesv2aws/aws-sdk-ruby
Rustaws-sdk-sesv2cargo add aws-sdk-sesv2awslabs/aws-sdk-rust
Kotlinaws.sdk.kotlin:sesv2Gradle: implementation("aws.sdk.kotlin:sesv2:$version")awslabs/aws-sdk-kotlin
CLIaws sesv2Install AWS CLI v2aws/aws-cli
Pick the v2 client. The v1 clients (ses, AWSSDK.SimpleEmail, SesClient) are still shipped and still work, but they cannot access newer resources (contact lists, VDM, event destinations v2, dedicated IP pools API) and cap raw messages at 10 MB. Any new SES integration in 2026 should target the sesv2 namespace across every SDK — older tutorials sometimes still import SESClient instead of SESv2Client.

Notable community SDKs

Because SES is API-first and covered by every AWS SDK, dedicated third-party SES SDKs are uncommon. Framework-level helpers are more useful: Laravel’s ses-v2 mail transport, Django’s django-ses, Rails’ aws-sdk-rails, WordPress WP Mail SMTP and WP Offload SES, and NestJS mailer modules all wrap the official SDKs and are the pragmatic path for stack-native integration. For agent workloads see the MCP directory above.

Endpoints reference

The full SES v2 REST reference lives in the Amazon SES v2 API Reference. The 15 endpoints below cover the resources most senders touch: sending, identities, templates, configuration sets and event destinations, contact lists, suppression, dedicated IPs, and account-level settings.

ResourceMethodsDescription
Email (transactional)
/v2/email/outbound-emails
POSTSendEmail — send a formatted or raw email to up to 50 recipients.
Bulk email
/v2/email/outbound-bulk-emails
POSTSendBulkEmail — templated message to up to 50 Destinations in one call.
Custom verification email
/v2/email/outbound-custom-verification-emails
POSTSendCustomVerificationEmail — verification email using a custom template.
Email identities
/v2/email/identities
GET, POSTListEmailIdentities / CreateEmailIdentity — manage verified domains and addresses.
Email identity (single)
/v2/email/identities/{EmailIdentity}
GET, DELETEGetEmailIdentity / DeleteEmailIdentity — read or remove a verified identity.
Email templates
/v2/email/templates
GET, POSTListEmailTemplates / CreateEmailTemplate — manage reusable templates.
Email template (single)
/v2/email/templates/{TemplateName}
GET, PUT, DELETEGet, update, or delete a specific email template.
Configuration sets
/v2/email/configuration-sets
GET, POSTListConfigurationSets / CreateConfigurationSet — group sending options and event destinations.
Event destinations
/v2/email/configuration-sets/{ConfigurationSetName}/event-destinations
GET, POSTManage CloudWatch, SNS, Firehose, or EventBridge destinations for send events.
Contact lists
/v2/email/contact-lists
GET, POSTListContactLists / CreateContactList — manage list-of-contacts resources.
Contacts
/v2/email/contact-lists/{ContactListName}/contacts
GET, POSTListContacts / CreateContact — manage subscribers within a contact list.
Suppressed destinations
/v2/email/suppression/addresses
GET, PUT, DELETEManage the account-level suppression list of hard-bounced and complained addresses.
Dedicated IP pools
/v2/email/dedicated-ip-pools
GET, POSTListDedicatedIpPools / CreateDedicatedIpPool — group dedicated IPs by purpose.
Dedicated IPs
/v2/email/dedicated-ips
GETGetDedicatedIps — list and inspect dedicated IPs assigned to the account.
Account
/v2/email/account
GET, PUTGetAccount / PutAccountDetails — read production status, quotas, update account details.

Code examples

Python (boto3): ping, add contact, send transactional

import boto3
from botocore.exceptions import ClientError

# SES v2 client - region must match where your identity is verified
ses = boto3.client('sesv2', region_name='us-east-1')

# 1) Ping / sanity check: list verified identities
try:
    resp = ses.list_email_identities(PageSize=10)
    print('Verified identities:', [i['IdentityName'] for i in resp.get('EmailIdentities', [])])
except ClientError as e:
    print('Ping failed:', e.response['Error']['Message'])
    raise

# 2) Add a subscriber to a contact list
try:
    ses.create_contact(
        ContactListName='smtpedia-newsletter',
        EmailAddress='reader@example.com',
        UnsubscribeAll=False,
        AttributesData='{"first_name":"Alaa"}'
    )
    print('Subscriber added.')
except ses.exceptions.AlreadyExistsException:
    print('Contact already exists.')
except ClientError as e:
    print('Create failed:', e.response['Error']['Message'])
    raise

# 3) Send a transactional email
try:
    ses.send_email(
        FromEmailAddress='hello@yourdomain.com',
        Destination={'ToAddresses': ['reader@example.com']},
        Content={
            'Simple': {
                'Subject': {'Data': 'Welcome to SMTPedia'},
                'Body': {'Text': {'Data': 'Thanks for signing up.'}}
            }
        }
    )
    print('Email sent.')
except ClientError as e:
    print('Send failed:', e.response['Error']['Message'])

Node.js (@aws-sdk/client-sesv2): add contact, send email

import { SESv2Client, CreateContactCommand, SendEmailCommand } from '@aws-sdk/client-sesv2';

const ses = new SESv2Client({ region: 'us-east-1' });

async function main() {
  // 1) Add a subscriber to a contact list
  try {
    await ses.send(new CreateContactCommand({
      ContactListName: 'smtpedia-newsletter',
      EmailAddress: 'reader@example.com',
      UnsubscribeAll: false,
      AttributesData: JSON.stringify({ first_name: 'Alaa' })
    }));
    console.log('Subscriber added.');
  } catch (err) {
    if (err.name !== 'AlreadyExistsException') throw err;
    console.log('Contact already exists.');
  }

  // 2) Send a transactional email
  await ses.send(new SendEmailCommand({
    FromEmailAddress: 'hello@yourdomain.com',
    Destination: { ToAddresses: ['reader@example.com'] },
    Content: {
      Simple: {
        Subject: { Data: 'Welcome to SMTPedia' },
        Body: { Text: { Data: 'Thanks for signing up.' } }
      }
    }
  }));
  console.log('Email sent.');
}

main().catch(err => { console.error('SES error:', err); process.exit(1); });

Common gotchas

SMTP credentials are not your AWS access keys

SES SMTP requires a distinct IAM SMTP username/password pair, generated in the SES console or derived from an IAM user’s AWS secret via HMAC-SHA256. Using the raw AWS access key ID + secret against the SMTP endpoint will always return 535 authentication failed. The API side has the reverse trap: agents pointed at email.us-east-1.amazonaws.com using an SMTP password will fail SigV4 signing every time.

SMTP credentials are region-specific

The SMTP password is derived using the region string as part of the signing key. Credentials generated for us-east-1 will fail against email-smtp.eu-west-1.amazonaws.com. Regenerate a separate set of SMTP credentials for every region you send from, and store them per-region in your secret manager — a single “SES password” env var is the wrong shape for a multi-region deployment.

Sandbox is aggressive and easy to forget

New accounts (and each new region) start in the SES sandbox: 200 messages per 24 h, 1 msg/sec, and you can only send to verified addresses. Production access requires a support case describing use case, expected volume, and bounce/complaint handling — approvals typically take about 24 h but can be denied or partially granted. Automate the sandbox check into your bootstrap script (GetAccount exposes the flag).

Bounce and complaint thresholds trigger account review

SES puts accounts under review at a 5% bounce rate or 0.1% complaint rate and can pause sending at 10% bounces or 0.5% complaints. You must process bounce/complaint SNS notifications, honour the account-level suppression list, and never re-mail hard bounces. Wire an SNS or EventBridge event destination on day one, not after the first pause.

EC2 blocks port 25 by default

Amazon throttles outbound TCP 25 on EC2 instances by default. Use port 587 or 2587 for STARTTLS, or 465 / 2465 for TLS-wrapper, or file a “Request to Remove Email Sending Limitations” support case. Applications hard-coded to port 25 will silently time out on EC2 with no clear error — this is one of the most common false “SES is down” reports.

Deprecations and changelog

  • August 7, 2026 — SES now emits an isBotEvent field in Open and Click event notifications, letting customers distinguish automated (MPP, security scanners) opens from real human engagement without extra configuration.
  • May 29, 2026 — Virtual Deliverability Manager (VDM) launched Inbox Placement Metrics, industry blocklist monitoring, and pre-send inbox-placement testing across all commercial SES regions.
  • May 15, 2026 — AWS MCP Server reached general availability, giving agents a first-party MCP entry point into AWS services — the closest AWS has come to an official MCP surface for SES.
  • April 1, 2026 — SES Mail Manager added new features for enhanced inbound security and email processing (expanded rules, address list controls, larger archives).
  • May 1, 2025 — SES enabled IPv6 support when calling SES outbound endpoints, allowing dual-stack SMTP and API connectivity.

Track future changes in the Amazon SES Developer Guide document history and the AWS Messaging & Targeting What’s New feed.

Frequently asked questions

What is the difference between the SES v1 and SES v2 APIs?

SES v2 (API version 2019-09-27, service id sesv2) is the current REST/JSON surface and receives all new features (contact lists, VDM, event destinations v2, dedicated IP pools API). SES v1 is the legacy Query API kept for backward compatibility; it caps raw messages at 10 MB versus 40 MB on v2 and lacks the newer resources. New integrations should target v2 (@aws-sdk/client-sesv2, boto3 client sesv2, AWSSDK.SimpleEmailV2).

Which authentication methods does the Amazon SES v2 API support?

Every HTTPS call is signed with AWS Signature Version 4 (SigV4). Credentials can come from a long-lived IAM user access key + secret, from an IAM role assumed via EC2 instance profile / ECS task role / EKS IRSA / Lambda execution role, or from short-lived STS credentials issued by IAM Identity Center. The SMTP interface uses a separate IAM SMTP username/password pair (AUTH LOGIN over TLS) derived from an IAM user secret — not the raw AWS access key.

How do I paginate results from ListEmailIdentities or ListContacts?

SES v2 list operations use a cursor called NextToken. Send PageSize on the first request; if a NextToken is present in the response, pass it back on the next call to fetch the following page. Stop when the response omits NextToken. All official SDKs expose a paginator helper (ses.get_paginator('list_email_identities') in boto3, paginateListEmailIdentities in AWS SDK for JavaScript v3).

What is the maximum message size and recipient count for SES v2 SendEmail?

A single SendEmail or SMTP submission accepts up to 50 recipients combined across To/Cc/Bcc, and a raw payload up to 40 MB after base64 encoding. Beyond 10 MB, SES additionally applies a bandwidth ceiling of about 40 MB/s per connection. For fan-out to more than 50 addresses in one call, use SendBulkEmail against a template with up to 50 Destinations entries.

Which official AWS SDKs support the SES v2 client?

AWS ships and maintains SES v2 clients in Python (boto3, client sesv2), JavaScript/TypeScript (@aws-sdk/client-sesv2), Java (software.amazon.awssdk:sesv2), Go (aws-sdk-go-v2/service/sesv2), .NET (AWSSDK.SimpleEmailV2), PHP (SesV2Client), Ruby (aws-sdk-sesv2), Rust (aws-sdk-sesv2), and Kotlin (aws.sdk.kotlin:sesv2), plus the AWS CLI v2 (aws sesv2). All are actively maintained against the current sesv2 Smithy model.

Is there an official Amazon SES MCP server for AI agents?

No production-grade, first-party SES MCP server exists as of August 2026. AWS publishes aws-samples/sample-for-amazon-ses-mcp, but it is explicitly a sample, not for production. Agents wanting SES today can use the general-purpose AWS MCP Server (GA May 2026), a community wrapper like omd01/aws-ses-mcp, or expose SES through Zapier MCP. Contrast with Postmark and Mailgun — also community-only in 2026.

Changelog (recent)

  • 2026-08-19 API + MCP tab published on SMTPedia. First-party MCP status inventoried: no dedicated production SES MCP server as of this date.
  • 2026-08-07 SES added the isBotEvent field to Open and Click event notifications, letting senders separate MPP and security-scanner opens from real human engagement without extra tooling.
  • 2026-05-29 Virtual Deliverability Manager (VDM) launched Inbox Placement Metrics, blocklist monitoring, and pre-send inbox-placement testing across all commercial SES regions.
AAlaa Touil RRabeb How we test →

This review follows our email infrastructure testing methodology. We disclose affiliate relationships in our editorial independence policy.