Wraps Logo
Infrastructure / Events

EventBridge Events

Every email event flows through your AWS account's EventBridge bus. Create rules to build alerts, analytics, workflows, and more.

How It Works

When you send an email through Wraps, SES publishes event notifications to the default EventBridge bus in your AWS account. Wraps creates a rule on that bus to capture events into its processing pipeline — but because it's your bus, you can add your own rules alongside Wraps' rule with zero configuration.

architecture.txt
# Email Event Flow## Your App ─→ SES ─→ Configuration Set ─→ EventBridge (default bus)#                                              │#                                    ┌─────────┴─────────┐#                                    │                    │#                              Wraps Rule           Your Rules#                                    │                    │#                                   SQS              [targets]#                                    │#                                 Lambda#                                    │#                                DynamoDB

Your events, your bus, your rules

EventBridge evaluates every rule on the bus independently. Adding your own rules has no impact on Wraps' processing pipeline, and you get native fan-out, content-based filtering, and IAM security — no webhook endpoints to manage.

What Wraps Handles Automatically

Wraps' built-in pipeline captures all configured events and processes them into DynamoDB. You get this for free — custom rules are for anything extra you want to build.

FieldSourceDescription
messageIdmail.messageIdSES message ID (partition key)
sentAtmail.timestampWhen the email was sent (sort key)
accountIdenvelope.accountYour AWS account ID
frommail.sourceSender email address
tomail.destinationRecipient email addresses
subjectmail.commonHeadersEmail subject line
eventTypedetail.eventTypeEvent type (Send, Delivery, Bounce, etc.)
eventDataFull event JSONComplete event payload for detailed analysis
expiresAtComputedTTL (90 days Production, 365 days Enterprise)

Suppression normalization

When SES reports a bounce with sub-type Suppressed or OnAccountSuppressionList, Wraps normalizes these into a distinct Suppressed event type in DynamoDB. This makes it easy to distinguish real bounces from suppression-list entries.

Event Types Reference

SES uses three different naming conventions depending on where you look. This mapping table is the key to writing EventBridge rules correctly.

EventEventBridge detail-typedetail.eventTypeWhen It Fires
SendEmail SentSendEmail accepted by SES for delivery
DeliveryEmail DeliveredDeliveryRecipient mail server accepted the email
OpenEmail OpenedOpenRecipient opened the email (tracking pixel loaded)
ClickEmail ClickedClickRecipient clicked a tracked link
BounceEmail BouncedBounceEmail could not be delivered
ComplaintEmail Complaint ReceivedComplaintRecipient marked email as spam
RejectEmail RejectedRejectSES rejected the email (virus, policy)
Delivery DelayEmail Delivery DelayedDeliveryDelayTemporary delivery issue, SES will retry
Rendering FailureEmail Rendering FailedRendering FailureSES template rendering failed
SubscriptionEmail SubscribedSubscriptionRecipient changed subscription preferences
Inbound Emailemail.receivedInbound email received (source: wraps.inbound)

Delivery Events

Engagement Events

System Events

Inbound Events

Bounce & Complaint Reference

Bounces and complaints are the most important events to handle correctly. AWS monitors your bounce and complaint rates and will suspend your account if they exceed thresholds.

SES suspension thresholds

AWS will place your SES account under review if your bounce rate exceeds 5% or your complaint rate exceeds 0.1%. Persistent violations lead to sending suspension.

Bounce Type Matrix
bounceTypebounceSubTypeRecommended Action
PermanentGeneralSuppress immediately — address is invalid
PermanentNoEmailSuppress — mailbox does not exist
PermanentSuppressedAlready on SES suppression list (Wraps normalizes to Suppressed)
PermanentOnAccountSuppressionListAccount-level suppression (Wraps normalizes to Suppressed)
PermanentUnsubscribedRecipientRecipient unsubscribed — remove from mailing list
TransientGeneralRetry later — temporary issue
TransientMailboxFullRetry, suppress after repeated failures
TransientMessageTooLargeReduce message size and resend
TransientContentRejectedReview email content for policy violations
TransientAttachmentRejectedReview attachment type and size
UndeterminedUndeterminedInvestigate manually — check diagnostic code

Wraps suppression normalization

Wraps automatically detects bounces with sub-type Suppressed or OnAccountSuppressionList and stores them with event type Suppressed in DynamoDB instead of Bounce. This keeps your bounce metrics accurate by excluding addresses that were already suppressed.

Creating Custom Rules

The default EventBridge bus evaluates all rules independently. Your rules run alongside Wraps' rule with no interference. Create rules in the AWS Console, CLI, CDK, or Terraform using these event patterns.

Match all SES events

Capture every email event on the bus. Use this to forward everything to a single target.

JSONpattern-all-events.json
{  "source": ["aws.ses"],  "detail-type": [    "Email Sent",    "Email Delivered",    "Email Bounced",    "Email Complaint Received",    "Email Opened",    "Email Clicked",    "Email Rejected",    "Email Rendering Failed",    "Email Delivery Delayed",    "Email Subscribed"  ]}
Filter bounces and complaints only

Alert on the events that matter most for sender reputation.

JSONpattern-bounces-complaints.json
{  "source": ["aws.ses"],  "detail-type": [    "Email Bounced",    "Email Complaint Received"  ]}
Filter permanent bounces only

Use content-based filtering to match only permanent hard bounces. Transient bounces are excluded.

JSONpattern-permanent-bounces.json
{  "source": ["aws.ses"],  "detail-type": ["Email Bounced"],  "detail": {    "bounce": {      "bounceType": ["Permanent"]    }  }}
Match inbound email events

Inbound events use a different source. Match them separately from outbound SES events.

JSONpattern-inbound.json
{  "source": ["wraps.inbound"],  "detail-type": ["email.received"]}

Available Targets

TargetUse Case
LambdaCustom processing, database writes, API calls
SNSFan-out to email, SMS, Slack, PagerDuty
SQSBuffered processing, batch operations
Step FunctionsMulti-step workflows, orchestration
API DestinationForward to external webhooks (Slack, Zapier, etc.)
CloudWatch LogsLogging, debugging, audit trail

Common Use Cases

Practical examples of what you can build with custom EventBridge rules.

Alert on Bounces & Complaints

Route bounce and complaint events to SNS, then subscribe a Slack channel or PagerDuty endpoint. Get notified immediately when your sender reputation is at risk.

EventBridge → SNS → Slack / PagerDuty
Build Engagement Analytics

Capture open and click events in a Lambda function that writes to your own database. Build custom dashboards with open rates, click-through rates, and per-link analytics.

EventBridge → Lambda → Your Database
Trigger Workflows

Use Step Functions to orchestrate multi-step processes. For example: when a welcome email is delivered, wait 3 days, check if the recipient opened it, then send a follow-up.

EventBridge → Step Functions → SES
Forward to Your Webhook

Use an API Destination to forward events to any HTTP endpoint. Connect to Zapier, Make, n8n, or your own API without managing infrastructure.

EventBridge → API Destination → Your Endpoint

Quotas & Limits

Key EventBridge limits to keep in mind when creating custom rules.

ResourceDefault LimitNotes
Rules per event bus300Adjustable up to 2,000 via AWS support
Targets per rule5Hard limit (use fan-out via SNS for more)
PutEvents rate10,000/secVaries by region; SES manages publishing
Event pattern size2,048 charsAdjustable via AWS support

Next Steps

What Gets Deployed: Email

See every AWS resource Wraps creates, organized by preset.

View Resources
Email SDK Reference

Send emails with the TypeScript SDK after deploying.

View SDK Docs
Configuration Presets

Compare presets and customize your configuration.

View Guide

Need Help?

If you run into any issues, check our GitHub discussions or open an issue.

Get Help