Send emails with Spring Boot
Transactional and marketing email from a Spring service, with Spring's RestClient. One call returns an id you can trace.
✓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 Spring Boot?
Create a key, keep it on the server, and call one endpoint from a Spring service.
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
Set AEM_KEY=aem_… in the environment and inject it with @Value("${sendandretain.api-key}"). Never commit the key itself.
application.propertiessendandretain.api-key=${AEM_KEY}Send the email
A service posts with Spring's RestClient, built from the injected RestClient.Builder. retrieve() throws on a 4xx or 5xx, and a retried job that reuses the Idempotency-Key won't send twice.
EmailService.java@Value("${sendandretain.api-key}") private String apiKey; public Map<?, ?> sendWelcome(User user) { return restClient.post() .uri("https://sendandretain.com/api/v1/emails") .header("Authorization", "Bearer " + apiKey) .header("Idempotency-Key", "welcome-" + user.id()) .contentType(MediaType.APPLICATION_JSON) .body(Map.of("to", user.email(), "template", "welcome")) .retrieve() .body(Map.class); }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 Spring Boot app?
Services, events, and scheduled jobs
A service owns the call. @Async moves it off the request thread; a durable worker survives restarts.
Events after commit
Send events after the transaction commits, so automations never act on a change that rolled back.
A raw body for webhooks
A @RestController takes the body as a String, so the signature is checked over the exact bytes.
[ 03 / 05 ]Marketing email
Can I send marketing emails from Spring Boot too?
Yes. Send an event from the same service 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 Spring Boot?
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 Spring Boot signup service using Send & Retain, with an idempotency key.”
After commit
“Send our order confirmation email from a @TransactionalEventListener so it only goes out after the commit.”
Webhook
“Add a Spring controller that verifies Send & Retain delivery webhooks and marks bounced users.”
Trial automation
“Send a trial_started event from our Spring Boot service and build a paused trial-conversion automation for it.”
[ 05 / 05 ]Related
Keep building with Spring Boot
Questions people ask us
Send your first email from Spring Boot today.
Create a key, paste the code into a Spring service, and watch the email land in the message log.