Transactional Email
Send templated and ad-hoc transactional email from your project — register reusable templates, send to a user or a raw address, manage suppressions, and inspect delivery history.
Amba sends transactional email on your behalf — welcome mails, receipts, password resets, anything triggered by an app event. You register reusable HTML templates, then send by template name (to an end user or a raw address) or send a one-off ad-hoc message. Every send is recorded in a delivery log, and bounces / complaints are suppressed automatically so you don't keep mailing a dead address.
All routes mount under /v1/admin/projects/:projectId/email/* and require
a developer Bearer token (your PAT). The amba_email_* MCP tools wrap the
same surface for agentic use.
Endpoints
| Method | Path | Description |
|---|---|---|
| POST | /admin/projects/:projectId/email/templates | Register or update a template (upsert). |
| GET | /admin/projects/:projectId/email/templates | List templates. |
| GET | /admin/projects/:projectId/email/templates/:name | Describe one template. |
| PATCH | /admin/projects/:projectId/email/templates/:name | Update a template's fields. |
| DELETE | /admin/projects/:projectId/email/templates/:name | Delete a template. |
| POST | /admin/projects/:projectId/email/send | Send (by template or ad-hoc). |
| GET | /admin/projects/:projectId/email/deliveries | List deliveries (filter by template/status). |
| GET | /admin/projects/:projectId/email/deliveries/:id | Describe one delivery. |
| POST | /admin/projects/:projectId/email/suppressions | Add a manual suppression. |
| GET | /admin/projects/:projectId/email/suppressions | List suppressions. |
| DELETE | /admin/projects/:projectId/email/suppressions/:email | Remove a suppression (unblock). |
Templates
A template is a named subject + HTML body, with an optional plain-text
body. Template names must match ^[a-z][a-z0-9_]*$. The body uses
{{variable}} placeholders that are filled in from the data you pass at
send time. When no text_body is set, a plain-text version is derived
from the HTML automatically.
POST .../email/templates is an upsert — registering a template whose
name already exists overwrites the subject and body.
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | yes | ^[a-z][a-z0-9_]*$. |
subject | string | yes | Non-empty. Supports {{variables}}. |
html_body | string | yes | Supports {{variables}}. |
text_body | string | no | Plain-text fallback. Auto-derived if omitted. |
Sending
POST .../email/send accepts one of three body shapes:
Templated, to an end user (looks up the user's email from your project):
Templated, to a raw address:
Ad-hoc (no template):
The response carries the delivery id and status:
status is one of queued (accepted for delivery), suppressed (the
recipient is on the suppression list — nothing was sent), or failed.
Deliveries
Every send writes a delivery row you can list and inspect. Filter by
?template=, ?status=, and ?limit= (max 200).
A delivery's status progresses through queued → sent, or lands on
suppressed / failed. last_error carries a human-readable reason when
a send fails.
Suppressions
Bounces and complaints add the address to the suppression list
automatically; subsequent sends to a suppressed address return
status: "suppressed" without contacting the recipient. You can also add
a manual suppression, or remove one to unblock an address you've
confirmed is valid again.
reason is one of bounce, complaint, or manual (default manual).
Filter the list with ?reason=.
From an agent or function
-
MCP — the
amba_email_*tools (amba_email_send, the template and suppression operations, and delivery reads) wrap the endpoints above so an agent can send mail without touching HTTP. Pass yourpatand theproject_id. -
Functions — call the send endpoint from a function using the injected
env.AMBA_INTERNAL_TOKEN:
Errors
| Code | Status | Meaning |
|---|---|---|
INVALID_TEMPLATE_NAME | 400 | Name doesn't match ^[a-z][a-z0-9_]*$. |
TEMPLATE_NOT_FOUND | 404 | Send referenced a template that isn't registered. |
USER_NOT_FOUND | 404 | to.user_id has no email on file. |
EMAIL_VALIDATION | 400 | The send payload was malformed. |
EMAIL_PROVIDER_REJECTED | 502 / 503 | The mail couldn't be handed off; safe to retry on 503. |