Transactional Email API
One HTTP call sends a receipt, a password reset, or a booking confirmation from your own verified domain. Everything below works with a live API key. No SDK to install, and nothing to sign in for.
Quickstart
Send mail with one HTTP call. Authenticate with your API key (looks like tk_live_…) and send from a verified sending domain. The examples below use no-reply@send.yourdomain.com as a stand-in for yours. Building with an AI coding assistant? Download the and drop it into your repo. It contains everything your agent needs.
curl -X POST "https://www.zorromail.app/tx/v1/messages" \
-H "Authorization: Bearer $ZORROMAIL_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-receipt" \
-d '{
"from": "no-reply@send.yourdomain.com",
"fromName": "Acme Support",
"to": ["customer@example.com"],
"subject": "Your receipt",
"html": "<h1>Thanks!</h1><p>Order #1042 confirmed.</p>",
"text": "Thanks! Order #1042 confirmed."
}'const res = await fetch('https://www.zorromail.app/tx/v1/messages', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.ZORROMAIL_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': 'order-1042-receipt',
},
body: JSON.stringify({
from: 'no-reply@send.yourdomain.com',
fromName: 'Acme Support',
to: ['customer@example.com'],
subject: 'Your receipt',
html: '<h1>Thanks!</h1><p>Order #1042 confirmed.</p>',
}),
});
if (!res.ok) throw new Error(`send failed: ${res.status}`);
const { id, status } = await res.json();import os, requests
res = requests.post(
"https://www.zorromail.app/tx/v1/messages",
headers={
"Authorization": f"Bearer {os.environ['ZORROMAIL_API_KEY']}",
"Idempotency-Key": "order-1042-receipt",
},
json={
"from": "no-reply@send.yourdomain.com",
"fromName": "Acme Support",
"to": ["customer@example.com"],
"subject": "Your receipt",
"html": "<h1>Thanks!</h1><p>Order #1042 confirmed.</p>",
},
timeout=30,
)
res.raise_for_status()
message = res.json()Sender name. fromName is what recipients see in their inbox. Leave it out and mail clients fall back to the local part of the address (no-reply), so send a properly capitalized name like Acme Support. You can also write it inline as Acme Support <no-reply@send.yourdomain.com>, or save it once on the sender under Sender emails and every send picks it up automatically.
Request fields
| Field | Type | Notes |
|---|---|---|
| from | string | Required. Must be on a verified sending domain, e.g. no-reply@send.yourdomain.com. May carry the sender name inline: Acme Support <no-reply@send.yourdomain.com> |
| fromName | string | Optional. Sender name shown in the inbox, e.g. Acme Support (max 78 chars). Without it clients display "no-reply" |
| to | string[] | Required. Recipient addresses |
| subject | string | Required, max 998 chars |
| html / text | string | At least one required. Send both for best deliverability |
| cc, bcc | string[] | Optional |
| replyTo | string | Optional. Where replies land (use a real inbox). Accepts Name <addr@domain> |
| headers | object | Optional extra headers, e.g. {"X-Order-Id": "123"} |
| attachments | array | {filename, contentBase64, contentType} |
Optional Idempotency-Key request header: retries with the same key return the original result instead of sending a duplicate. Use it for anything triggered by payments or retried jobs.
Responses & errors
Success is 202 with {"id", "status", "suppressedRecipients?"}. Recipients who previously bounced, complained, or unsubscribed are suppressed automatically. They appear in suppressedRecipients and are never contacted.
| Status | Meaning | What to do |
|---|---|---|
| 400 | Validation failed | Fix the payload; do not retry as-is |
| 401 | Missing/invalid/revoked API key | Check the key |
| 422 | From-domain not verified | Verify the sending domain first |
| 429 | Rate limit (100 req/min) or monthly quota | Back off and retry later |
| 502 | Upstream provider failure | Retry with the same Idempotency-Key |
Suppression list
Manage suppressed addresses with the same API key:
# list
curl "https://www.zorromail.app/tx/v1/suppressions" -H "Authorization: Bearer $ZORROMAIL_API_KEY"
# add manually
curl -X POST "https://www.zorromail.app/tx/v1/suppressions" \
-H "Authorization: Bearer $ZORROMAIL_API_KEY" -H "Content-Type: application/json" \
-d '{"email": "someone@example.com"}'
# remove
curl -X DELETE "https://www.zorromail.app/tx/v1/suppressions/someone@example.com" \
-H "Authorization: Bearer $ZORROMAIL_API_KEY"Included automatically
- Delivery, bounce, complaint, open, and click tracking per message
- Hard bounces and complaints auto-suppress the recipient
- One-click List-Unsubscribe header (RFC 8058) on every send
- Raw copy of every message archived for audit