Send emails with Next.js
Transactional and marketing email from a Route Handler or Server Action. One API call, and your key never leaves the server.
✓Free to start. Unlimited contacts on every tier.
One request, complete trace
Request
POST /api/v1/emails
Authorization: Bearer aem_…
Idempotency-Key: welcome-8f21
{ "to": "[email protected]", "template": "welcome" }
202 Accepted
{ "id": "msg_7ca31", "status": "queued" }
[ 01 / 05 ]Quickstart
How do I send email from Next.js?
Create a key, keep it on the server, and call one endpoint from a Route Handler or Server Action.
Get an API key
Open Settings → API & MCP and create a key with the Send + manage permission (the default). It starts with aem_ and is shown once.
Store it as a server-side environment variable
Add the key to .env.local and to your host's environment settings. Never prefix it with NEXT_PUBLIC_, or Next.js ships it to the browser.
.env.localAEM_KEY=aem_…Send the email
A Route Handler posts to the email API. The Idempotency-Key header makes retries safe: the same key never sends a second email.
app/api/welcome/route.tsexport async function POST(request: Request) { const { email, userId } = await request.json(); const res = await fetch("https://sendandretain.com/api/v1/emails", { method: "POST", headers: { Authorization: `Bearer ${process.env.AEM_KEY}`, "Content-Type": "application/json", "Idempotency-Key": `welcome-${userId}` }, body: JSON.stringify({ to: email, template: "welcome" }), }); return Response.json(await res.json(), { status: res.status }); }Check the response
A 202 means queued, not delivered. Keep the id, then follow delivery in the message log or through a signed webhook.
202 Accepted{ "id": "msg_7ca31", "status": "queued" }
[ 02 / 05 ]Where it goes
Where should email code live in your Next.js app?
Route Handlers and Server Actions
Use a Server Action for a form in your own app. Use a Route Handler when another service calls you, or for a webhook URL.
Events after the write
Send the signup or payment event after the database write succeeds, so automations follow what really happened.
A raw body for webhooks
Read the body with req.text() before parsing JSON, so the signature check sees the original bytes.
[ 03 / 05 ]Marketing email
Can I send marketing emails from Next.js too?
Yes. Send an event from the same Server Action when a user signs up, starts a trial, or goes quiet, and an automation sends the right email. Automations start paused, and every email goes to one person: no newsletter blasts.
- Transactional and marketing email share one contact record and one unsubscribe list.
- Unsubscribes, bounces, and complaints are suppressed for you before every send.
- Templates are react.email components; published versions never change under you.
[ 04 / 05 ]Example prompts
What can you ask your coding agent to do in Next.js?
Claude Code, Cursor, and Codex can do these over the Send & Retain MCP server, with your repo open. Automations they build stay paused until you turn them on.
Welcome email
“Add a welcome email to our Next.js signup route using Send & Retain, with an idempotency key.”
Password reset
“Write a password reset email in our brand, send me a test, then call it from our reset Server Action.”
Webhook
“Add a Route Handler that verifies Send & Retain delivery webhooks and marks bounced users in our database.”
Trial automation
“Send a trial_started event from our Next.js app and build a paused trial-conversion automation for it.”
[ 05 / 05 ]Related
Keep building with Next.js
Questions people ask us
Send your first email from Next.js today.
Create a key, paste the code into a Route Handler or Server Action, and watch the email land in the message log.