# SES Marketing Automation on AWS — Journey Architecture Checklist

First-party checklist for the post **AWS SES Marketing Automation with EventBridge and Step Functions (2026)**.

**As of:** 2026-07-22. Pair with [SES pricing plans](https://aws.amazon.com/ses/pricing/) when dedicated IPs / VDM are in scope.

## Decision: build vs buy vs hybrid

- [ ] Documented who owns journey edits (engineers vs marketers)
- [ ] Chosen path:
  - **Build** — EventBridge + Step Functions + SES (+ DynamoDB/RDS contacts)
  - **Buy** — Customer.io / Loops / Klaviyo / Braze for journeys; SES optional for transactional only
  - **Hybrid** — marketing platform for visual journeys; SES for transactional + high-volume promo with config-set isolation
- [ ] Cost model includes eng weeks for build path, not only SES $0.10/1k a-la-carte

## Identity and streams

- [ ] Verified From domains with SPF + DKIM + DMARC alignment
- [ ] Separate configuration sets: `txn`, `lifecycle`, `promo` (minimum)
- [ ] Dedicated / managed DIP decision recorded; **Pro** plan evaluated if managed DIPs + Global VDM needed (Jul 21, 2026+)
- [ ] Suppression store (account and/or tenant-scoped) checked **before** every SES send in the state machine

## Event ingestion

- [ ] Canonical events defined (`UserSignedUp`, `CartAbandoned`, `OrderPlaced`, `PreferenceUpdated`)
- [ ] EventBridge event bus + rules (or Partner Event Source) wired
- [ ] Idempotency keys on events to prevent double-drip sends
- [ ] PII minimization: contact IDs in events; PII looked up in contact store

## Orchestration (Step Functions)

- [ ] State machine per journey family (welcome, abandoned cart, win-back) — avoid one mega-machine
- [ ] `Wait` states use absolute timestamps from business rules, not hardcoded demo delays in prod
- [ ] Choice branches for engagement (opened / clicked / purchased) via DynamoDB flags updated from SES events
- [ ] Failure path: catch → DLQ / EventBridge → ops alert; never silent drop
- [ ] Concurrency / rate limits respect SES account and IP warm-up ceilings

## Send path

- [ ] Application-rendered HTML (React Email / MJML / Handlebars) — do not depend on ESP builders for core paths
- [ ] `List-Unsubscribe` + `List-Unsubscribe-Post` (RFC 8058) on marketing/lifecycle messages
- [ ] Message tags: `journey_id`, `step_id`, `stream` for CloudWatch / Athena forensics
- [ ] SES API v2 preferred; SMTP only if legacy constraint documented

## Feedback loop

- [ ] Configuration set → SNS/EventBridge for bounce, complaint, delivery, open, click (as needed)
- [ ] Hard bounce + complaint → immediate suppression write
- [ ] Open/click processors update journey state (optional engagement branching)
- [ ] Gmail Postmaster + SES complaint ceilings monitored separately (0.10% Postmaster spam vs ~0.1% SES complaint)

## Go-live

- [ ] Shadow run: emit events, assert state transitions, **block** SES send until QA sign-off
- [ ] Seed-list placement check on first production cohort
- [ ] Kill switch: EventBridge rule disable or Step Functions stop execution API documented

## What this checklist is not

- Not a Customer.io / Klaviyo feature parity matrix
- Not legal advice for consent / CAN-SPAM / GDPR
- Not a guarantee that build-your-own automation is cheaper than an ESP at your volume
