A configuration set is Amazon SES's named bundle of sending behaviour - event destinations, reputation tracking, tracking domain, IP pool, TLS policy, suppression scope, and VDM settings - that you attach to a send so all those rules apply at once. AWS lets you create up to 10,000 of them per region per account (AWS service quotas, 2026), but the vast majority of senders run with two to five: one for marketing, one for transactional, and maybe one per tenant. This guide covers what's inside a configuration set, how to create one across console, CLI, and Terraform, when to split into multiple, and the mistakes that quietly cost teams visibility.
Disclosure: Mailblast is a hosted management layer that operates on top of your own Amazon SES account. The technical details below are vendor-neutral; the final section explains how Mailblast provisions configuration sets in your account.
What a configuration set actually contains
A configuration set in SES v2 is a JSON envelope with seven optional sub-objects, each controlling one slice of send behaviour (AWS CreateConfigurationSet API reference, 2026). All are independent: you can run an empty configuration set that does nothing useful, or one with every block populated. The choice of what to populate is what makes config sets a "send profile" rather than a single feature.
The seven blocks, in roughly the order most teams configure them:
- TrackingOptions - the custom redirect domain SES uses for open and click tracking, plus an HTTPS policy. Without this, SES uses a shared
awstrack.mesubdomain that occasionally triggers spam filters. - DeliveryOptions - the
SendingPoolName(which dedicated IP pool to send from) and theTlsPolicy(OPTIONALorREQUIRE).REQUIRErejects mail that cannot establish TLS with the recipient MX. - ReputationOptions - a single
ReputationMetricsEnabledboolean that turns per-configuration-set bounce and complaint rate publishing on or off in CloudWatch. - SendingOptions - a single
SendingEnabledboolean that pauses every send through this configuration set without touching the SES account itself. Useful kill switch for runaway campaigns. - SuppressionOptions - whether the account-level suppression list applies, and optionally a tenant or account suppression scope override per configuration set.
- VdmOptions - Virtual Deliverability Manager toggles: dashboard engagement metrics, optimized shared delivery for the shared IP pool.
- Tags - free-form key/value labels for billing and access control.
Event destinations are not in this list because they are not part of the configuration set itself - they are separate resources created with CreateConfigurationSetEventDestination and attached to one parent configuration set, up to a hard ceiling of 10 destinations per set (AWS SES service quotas, 2026). A configuration set with zero event destinations still functions; it just emits no events anywhere. We cover destinations in depth in our SES event publishing reference.
When to use multiple configuration sets
Start with two: one for marketing, one for transactional. Marketing bounces and complaints should not pollute the account-wide rate AWS uses to evaluate the account - SES warns at 5% bounce and pauses at 10% (AWS, 2026). Per-stream metrics also let you wire separate CloudWatch alarms - the SES CloudWatch monitoring guide walks through alarming on Reputation.BounceRate per configuration set.
A typical two-config-set layout looks like this:
| Setting | marketing-prod | transactional-prod |
|---|---|---|
| Dedicated IP pool | marketing-pool | transactional-pool |
| Custom redirect domain | links.example.com | None (no click tracking) |
| Open and click tracking | On | Off |
| Reputation metrics | On | On |
| Account suppression list | Enforced | Bypassed for password resets |
| TLS policy | OPTIONAL | REQUIRE |
| Event destinations | CloudWatch + Firehose + SNS | CloudWatch + SNS bounces only |
| Purpose | Newsletters, drip, broadcasts | Receipts, password resets, alerts |
You may need more than two. A multi-tenant SaaS sending on behalf of customers usually creates one configuration set per tenant so each tenant's metrics, suppression scope, and IP pool are independent. An agency running campaigns for three brands on the same SES account does the same. The 10,000-per-region limit means you can grow to a few thousand tenants before you hit a structural ceiling - and if you do hit it, AWS will raise the quota on request.
Creating a configuration set across console, CLI, and Terraform
Three creation paths all hit the same SES v2 CreateConfigurationSet API (AWS, 2026). Names are capped at 64 alphanumeric characters plus hyphens and underscores and cannot be renamed once created, so settle on a naming convention before the first Create call. Production setups should keep configuration sets in version control - the console is fine for experiments but not for keeping two regions in sync.
Console. SES console - your region - Configuration sets - Create set. Name it, then toggle the boxes for reputation metrics, sending enabled, tracking options, and suppression. The console is the easiest way to learn the surface area but the worst way to keep two regions in sync.
AWS CLI. The aws sesv2 create-configuration-set call mirrors the API request body 1:1.
aws sesv2 create-configuration-set \
--configuration-set-name marketing-prod \
--tracking-options CustomRedirectDomain=links.example.com,HttpsPolicy=REQUIRE \
--delivery-options SendingPoolName=marketing-pool,TlsPolicy=OPTIONAL \
--reputation-options ReputationMetricsEnabled=true \
--sending-options SendingEnabled=true \
--suppression-options SuppressedReasons=BOUNCE,COMPLAIN \
--tags Key=Environment,Value=production Key=Stream,Value=marketing
Terraform. The aws_sesv2_configuration_set resource is the canonical declarative form.
resource "aws_sesv2_configuration_set" "marketing_prod" {
configuration_set_name = "marketing-prod"
delivery_options {
sending_pool_name = "marketing-pool"
tls_policy = "OPTIONAL"
}
reputation_options {
reputation_metrics_enabled = true
}
sending_options {
sending_enabled = true
}
suppression_options {
suppressed_reasons = ["BOUNCE", "COMPLAINT"]
}
tracking_options {
custom_redirect_domain = "links.example.com"
}
tags = {
Environment = "production"
Stream = "marketing"
}
}
To set this as the default configuration set on a verified identity - so every send from that identity flows through it without code changes:
aws sesv2 put-email-identity-configuration-set-attributes \
--email-identity example.com \
--configuration-set-name marketing-prod
After this call, any SendEmail from example.com that does not specify a ConfigurationSetName will pick up marketing-prod automatically.
Event destinations - the most common use
Event destinations are why most teams create configuration sets in the first place. SES supports five destination types - CloudWatch, Amazon Data Firehose, SNS, EventBridge, and Pinpoint - and ten event types from send through subscription (AWS, 2026). Each destination is a separate resource attached to one configuration set (up to 10 per set) and can filter on its own subset of events.
Pick by use case, not by familiarity. SNS for sub-second event handling (bounce processors, suppression-list writers - see the SES SNS feedback loop guide). CloudWatch for real-time metrics and alarms. Firehose for an S3 data lake plus Athena queries. EventBridge for cross-account routing and SaaS targets. Pinpoint only if you are already on Pinpoint. The right answer for most SES tenants is two or three destinations on the same configuration set, each filtered to the events that destination actually needs.
Reputation tracking and sending status per config set
Two of the simplest blocks - ReputationOptions.ReputationMetricsEnabled and SendingOptions.SendingEnabled - are also two of the most useful. Reputation metrics are off by default on new configuration sets; turning them on tells SES to publish Reputation.BounceRate and Reputation.ComplaintRate to CloudWatch with the ses:configuration-set dimension set (AWS reputation metrics docs, 2026). Without this, the only reputation metrics you can see are account-wide aggregates.
The practical use is per-stream reputation. With reputation metrics enabled on marketing-prod and transactional-prod independently, the SES console's reputation dashboard shows two separate bounce-rate curves, and CloudWatch alarms can fire on the marketing curve without paging when transactional bounces spike from an unrelated cause. Splitting marketing and transactional onto separate configuration sets without enabling per-config-set reputation metrics negates most of the point of the split.
SendingEnabled is the kill switch. Flipping it to false on marketing-prod halts every send through that configuration set within seconds, while transactional traffic on transactional-prod keeps flowing. AWS will pause sending on an entire SES account if reputation drops too far, but per-config-set sending control gives you a less destructive intermediate response - shut down the noisy stream, leave the rest alone, investigate.
Using configuration sets in your code
Once a configuration set exists, telling SES to use it on a send is a one-line addition. The API field is ConfigurationSetName; the SMTP equivalent is the X-SES-CONFIGURATION-SET header (AWS, Specifying a configuration set when you send email, 2026). Both work alongside message tags, and SES auto-tags every event with ses:configuration-set so downstream consumers can route on the set name without any extra wiring.
Boto3 example:
import boto3
ses = boto3.client("sesv2")
ses.send_email(
FromEmailAddress="noreply@example.com",
Destination={"ToAddresses": ["customer@example.net"]},
Content={
"Simple": {
"Subject": {"Data": "Your receipt"},
"Body": {"Html": {"Data": "<p>Thanks for your order.</p>"}},
}
},
ConfigurationSetName="transactional-prod",
EmailTags=[
{"Name": "stream", "Value": "receipt"},
{"Name": "tenant", "Value": "acme-corp"},
],
)
Raw SMTP send - inject the header into the MIME message:
X-SES-CONFIGURATION-SET: transactional-prod
X-SES-MESSAGE-TAGS: stream=receipt, tenant=acme-corp
From: noreply@example.com
To: customer@example.net
Subject: Your receipt
Content-Type: text/html; charset=UTF-8
<p>Thanks for your order.</p>
SES strips both headers before delivery so recipients never see them. The same X-SES-CONFIGURATION-SET header also works for SendRawEmail and SendBulkEmail calls, and the API field is identical across SDK languages.
Common mistakes
Three patterns account for most config-set incidents we see in customer SES audits. Each quietly negates the reason you created configuration sets in the first place, and each stays invisible in the SES console until you go looking - typically after AWS puts the account under review at 5% bounce or 0.1% complaint (AWS, 2026).
Using one configuration set for everything. The most common mistake. Marketing, transactional, password resets, system alerts all flow through default-config-set, so when bounce rate climbs you cannot tell whether it is the newsletter or the password-reset flow. Split at minimum into marketing versus transactional. The cost is zero - configuration sets are free; only event destinations attached to them have per-call costs.
Event destinations pointing at SNS topics with no subscribers. SES dutifully publishes events to a topic, the topic accepts them, and nobody reads them. This is silent data loss - SES does not warn you when a destination's downstream is dark. Always test a new destination with one send and trace the event end to end before scaling traffic, and add a CloudWatch alarm on each SNS topic's NumberOfMessagesPublished going to zero for a non-trivial period.
Forgetting to set a default configuration set on the identity. Every SendEmail call without a ConfigurationSetName parameter bypasses every event destination, every reputation toggle, and every tracking option. If a single legacy code path forgets to pass the parameter, you get a quiet trickle of un-tracked sends that never appear in your dashboards. Set a default config set on each identity with PutEmailIdentityConfigurationSetAttributes so this failure mode is structurally impossible.
How Mailblast uses configuration sets on your SES
Mailblast is a hosted management layer on top of your own SES account (BYO-SES) and provisions configuration sets on first connect. We create one set per workspace with an SNS event destination that publishes bounce, complaint, delivery, open, click, reject, and rendering-failure events to a topic in your account. A Mailblast endpoint subscribes to the topic so per-contact timelines, suppression, and campaign analytics in the UI match what SES emitted.
Because the configuration set, the SNS topic, the IAM role, and the verified identities all live in your AWS, you keep full control. You can add a Firehose destination to the same configuration set for your own data lake, point an EventBridge rule at the topic to copy events to another bus, or detach the destination entirely and run Mailblast in send-only mode without event ingestion. The technical surface - configuration sets, message tags, event JSON - is identical to a hand-rolled setup because Mailblast is a thin management layer on top of SES, not a hosted ESP that wraps SES centrally.
FAQ
What is an Amazon SES configuration set?
A configuration set is a named bundle of SES sending rules - event destinations, reputation tracking, tracking domain, IP pool, TLS policy, suppression scope, and VDM settings - that you attach to a send so all those rules apply at once. Think of it as a reusable send profile: one for marketing, one for transactional, separate ones per workspace if you run multi-tenant.
How many configuration sets can I have per AWS account?
SES allows up to 10,000 configuration sets per AWS region per account, which is far more than any normal sender will use. Configuration sets are region-scoped: a config set named marketing-prod in us-east-1 is a different resource from a config set with the same name in eu-west-1, and you create and manage them separately in each region.
Do I need a configuration set on every SendEmail call?
No, but messages sent without one bypass every event destination, reputation toggle, and tracking option you have configured. The common pattern is to set a default configuration set on each verified identity so every send is routed through it automatically, and override the ConfigurationSetName parameter only for the rare send that needs different behaviour.
What is the difference between a configuration set and an event destination?
A configuration set is the parent container. An event destination is one of up to 10 child rules inside that container that says where SES should publish events (CloudWatch, Firehose, SNS, EventBridge, Pinpoint) and which event types each destination receives. One configuration set can have multiple event destinations, each filtering on a different subset of event types.
How does Mailblast use configuration sets in my SES account?
Mailblast operates inside your AWS account (BYO-SES) and creates a dedicated configuration set per workspace on first connect. It attaches an SNS event destination pointing at a topic in your account, then subscribes a Mailblast endpoint to that topic so bounce, complaint, open, click, and delivery events flow back into the Mailblast UI for reporting and suppression.