SimpliDeliver Email
A developer-first transactional email platform on AWS SES — REST API, event pipeline, domain verification, dashboard and 351 pages of docs — built as a documented replication of a category leader, from a 915-URL teardown to a shipping product.
Summary
SimpliDeliver Email is a transactional email platform built as a deliberate, documented replication of Resend — the reasoning being that the sequencing decisions of a category leader are worth more than rediscovering them. It began as a full teardown: 915 sitemap URLs enumerated, the entire 353-page docs corpus read, all 47 API paths / 83 operations / 123 schemas, 95 MCP tools, 19 webhook event types, 95 changelog entries and 44 customer stories captured into a parity source of truth, which established the single most important finding — the product is a control plane, deliverability layer and UX layer on top of SES, and the MTA is the easy 5%. What shipped from that is a Turborepo monorepo: a Hono REST API with bearer auth, idempotency replay, rate limiting and full request logging; a worker running the send outbox and the SES event consumer; a Next.js dashboard with the full send/domain/logs/metrics loop; a Fumadocs site of 351 live pages; a published Node SDK; and Terraform/Lambda/Cloudflare infrastructure — 249 tests over 27 files, four custom CI guards, and 17/17 Playwright with axe at zero serious violations on every route.
Target user
Developers and technical teams who need transactional email they can integrate in an afternoon — an API key, a verified domain, a `POST /emails`, and a log page that shows the full request and response when something bounces. The docs are the product surface as much as the API is.
- 01
Ran a full-surface teardown of the reference product before writing a line: 915 sitemap URLs, the complete 353-page docs corpus (2.0 MB / 211k words, verified 353/353), all 47 API paths / 83 operations / 123 schemas from the live OpenAPI spec, 95 MCP tools, all 19 webhook events, 95 changelog entries read as a dated build timeline, and 44 customer stories — committed as a parity source of truth with an explicit precedence order (live API probe → OpenAPI → schemas → docs corpus → per-page markdown).
- 02
Built the public REST API on Hono with a middleware stack that is the actual product surface: bearer API-key auth, domain-scope enforcement, idempotency replay, rate limiting, structured error handling, per-request tracing, and an `api_logs` table capturing full request and response bodies with field-level redaction — because the logs page is a top-5 loved feature of the reference and retrofitting it later is painful.
- 03
Shipped the send pipeline with batch atomicity, address validation, MIME rendering, SSRF-guarded attachment fetching, scheduled sends and cancellation, plus RFC 8058 one-click unsubscribe with a per-recipient signed token minted at dispatch.
- 04
Built the events pipeline as one idempotent consumer: SES notifications off SQS, deduped, rank-projected onto the email timeline (so a late `delivered` can never overwrite a `bounced`), auto-suppressing hard bounces and complaints, with reputation tracking that puts a tenant on probation and then pauses it.
- 05
Implemented domain verification end to end — BYODKIM key generation, the DKIM/SPF/DMARC/MAIL FROM record set, provider detection, and a worker-driven poller that resolves live DNS until the identity verifies — namespaced entirely under a subdomain so the company's live production mail domain is never touched.
- 06
Shipped the dashboard as the full loop, proven by one Playwright spec: sign up → onboarding → mint a key → send → watch the timeline → add a domain → copy records → verified, with axe reporting zero serious or critical violations on every route and every open modal.
- 07
Published and audited a 351-page documentation site (Fumadocs, OpenAPI-generated reference, `llms.txt` and `llms-full.txt` routes) by sweeping every route against a production build rather than counting files — 351/351 pages and 226/226 internal links returning 200, with four real defects found and fixed in the sweep.
- 08
Wrote four custom CI guards that encode architectural decisions the type system cannot: minimum folder depth (so the tree never needs reorganising as phases land), no competitor hostnames anywhere in shipped code or filenames, no direct Redis client construction, and no colour literal or inline style in any dashboard component.
- 09
Published a Node SDK to npm and proved it against the running API with a contract test suite, so the quickstart in the docs is executed rather than asserted.
`SES_ADAPTER=aws npm run dev:worker` had been quietly running the *fake* adapter — a green run that proved nothing about the real integration. Fixed with `envMode: loose`, which changes nothing about caching (the hash only ever used declared variables) and restores the ordinary expectation that a variable set in the shell wins.
Ten parallel build lanes all reported done while four of seven convergence gates were still open — a real send against live SES, a live-DNS domain verification, an events round trip through the SES simulator, and an external developer following the published docs unaided. None of them is a build; all of them need credentials, real DNS, or a person who is not on the team. The project keeps a single `STATE.md` whose stated rule is that the git log and the code win over the issue tracker, because the tracker had already drifted once and was reconciled against ground truth rather than the other way around.
- L01
Replicating a mature product deliberately is a research technique, not a shortcut.
Reading 95 changelog entries as a dated build timeline told me what a funded team shipped first and what they deferred for three years — pagination and idempotency belong in the API from day one, the component library for writing emails was the single biggest adoption driver and belongs in Phase 1 rather than Phase 10, and inbound email had zero customer citations across 44 case studies and can wait.
- L02
The infrastructure constraints worth writing down are the ones that fail somewhere else.
A shared Redis with `noeviction`, an ECS box with ~384 CPU units left, and an SES grant in a region that already belongs to another product — none of those break this product when violated; they break a neighbour's, days later. Those three are the top of the project's own conventions file for exactly that reason.
- L03
Verify by sweeping the built artefact, never by counting files.
The docs file tree and the URL tree are different shapes — the source loader drops a path segment — so a file-based audit was wrong in both directions. Sweeping all 351 routes and all 226 internal links against a production build found a hard 500, twelve mis-named URLs, two 404-ing well-known routes and a section root serving nothing.
- L04
Two renderings, one call, is the whole portability story for logging.
One `log` from the shared contracts package, pretty when stdout is a TTY and JSON lines everywhere else, with a per-request child bound to the `x-request-id` the customer actually sees — about 100 hand-rolled lines with the same call shape as pino, and pino stays the upgrade path if throughput ever makes it matter.
- playwright e2e
- 17/17
- docs pages live
- 351
- app source loc
- 20952
- core domain loc
- 5368
- build lanes merged
- 8/10
- reference api ops mapped
- 83
- convergence gates proven
- 3/7