# What to Look For in a Developer-First Transactional Email API

Source: https://wraps.dev/blog/developer-first-email-api-checklist

Seven things that separate an API you enjoy from one you tolerate. Each has a test you can run in an afternoon, and a note on how Wraps does against it.

9 min read•Wraps Team

Wraps fails the first item on this list. We build one of these, so read the scoring with that in mind, and the scoring is here anyway because a checklist only one product passes is an advertisement.

Every item below is something you can verify yourself in an afternoon with a free account. That is the point. Feature matrices are written by marketing teams; these tests are not.

01

## Idempotency on the send call

Your worker retries. The queue redelivers. A Lambda times out after the send succeeded but before the ack. Without a key the API can deduplicate on, every one of those is a second copy of a password reset in somebody's inbox. Stripe solved this in 2015 and email providers have been slow to follow.

The test

Send the same request twice with the same idempotency key. Two emails means no idempotency, whatever the docs imply.

Wraps fails this

Wraps does not accept an idempotency key on send today. Workflow steps deduplicate internally on an execution and step id, but a direct email.send() called twice sends twice. Resend added idempotency keys in 2025 and is ahead of us here. If you are sending from an at-least-once queue, deduplicate on your side.

02

## Time from signup to a delivered email

This is the single best proxy for how much the vendor thought about developers. Not time to a 200 response — time to a message that actually lands in an inbox you control.

The test

Time yourself, from account creation to a real delivered message. Under ten minutes is good. An hour means the setup cost is being hidden from the pricing page.

Wraps partly passes

One command deploys the infrastructure in about two minutes. Then AWS reviews your SES sandbox request before you can mail anyone who has not verified themselves, which takes an hour to three days and is AWS's decision, not ours. Fast to your own inbox, slower to strangers than a managed API.

03

## Templates that live in source control

A drag-and-drop editor is useful for the people who are not you. It becomes a problem when it is the only place a template exists, because now the marketing email cannot be code reviewed, diffed, or rolled back, and the template is stuck in the vendor's dialect.

The test

Render a production template from a file in your repo, with no vendor API call in the path.

Wraps passes

Templates are React Email components. They compile to plain HTML that any provider can send, so they keep working if you leave. The editor is TSX in Monaco rather than a block builder, which is the right trade for engineers and the wrong one if your marketing team wants to work unaided.

04

## Webhooks with a signature and a retry policy

Delivery events are how you know anything. What matters is not that webhooks exist but that they are signed, that failures retry with backoff, and that there is a dead letter path so a bad deploy on your side does not silently drop an hour of events.

The test

Return a 500 from your handler on purpose. Find out whether the event comes back, how many times, and where it goes when it stops.

Wraps partly passes

Retries are the strong half: events go SES to EventBridge to SQS with a dead letter queue, all inside your AWS account, so when your handler fails the messages sit in your own queue instead of disappearing into a vendor's retry budget. The signature is the weak half. The X-Wraps-Signature header carries a static shared secret, not an HMAC over the body, so it tells you the request came from us but proves nothing about the payload and does nothing against replay. Verify it, and do not treat it as a Stripe-style signature.

05

## Observability past a delivery percentage

A dashboard that reports 98% delivered is not observability. You need the event trail for one message, by id, when a specific customer says they did not get their invoice.

The test

Take a message id from a send you made last week and pull its full event trace. Count the clicks it took.

Wraps passes

Per-message event timelines, with send, delivery, open, click, bounce, complaint and reject. Retention is plan-fixed rather than configurable: 30 days on Free, 90 on Pro, 365 on Business. On the Production and Enterprise presets the raw events also land in a DynamoDB table in your account, so a longer window is yours to build. The Starter preset does not deploy that table.

06

## Transactional and marketing kept apart

One promotional send with a bad list can take the complaint rate above the threshold, and the password resets go to spam with it. The two streams need separate identities so the reputation damage cannot cross over.

The test

Ask how to isolate the two. If the answer is a tag or a category rather than a separate sending identity, they share a fate.

Wraps partly passes

You can separate them properly because it is your SES account: configuration sets, separate subdomains, separate identities are all available. Wraps does not force that split for you or set it up by default, so this is a thing you have to know to do.

07

## An honest answer about deliverability

Nobody can promise inbox placement, and a vendor that does is telling you something useful about themselves. What you want is a clear statement of whose reputation you are sending on and what happens to it when a neighbour on the same IP pool has a bad week.

The test

Ask whether you are on a shared IP pool, what a dedicated one costs, and who owns the sending identity.

Wraps passes

You send on your own SES account and your own domain, so there are no neighbours. That cuts the other way too: a bad list is entirely your complaint rate, with no shared pool to absorb it, and getting out of the SES sandbox is on you.

## What the list leaves out on purpose

Price is not on it. Price is easy to compare and it is the thing everybody already checks, which is why it is a bad filter — every provider knows their pricing page is being read. The seven items above are the ones that are expensive to discover after you have built on top of somebody.

SDK language coverage is also not on it. If you are on TypeScript or Python every serious provider has you covered, and if you are on something rarer you already know to check.

## Run the tests

The quickstart gets you to a delivered email, which covers item two. The events guide covers items four and five.

[Email quickstart](https://wraps.dev/docs/quickstart/email)[Events and webhooks](https://wraps.dev/docs/guides/webhooks)
