Send an email
Queue a single transactional email. The request returns immediately with a message id; delivery happens asynchronously and is reported over webhooks.
POST
/v1/emailsProvide a from address on a verified domain (or the shared onboarding domain in test mode), at least one recipient, a subject, and a body — html, text, or both. Or send a stored template with templateId + data and omit the subject and body.
01 Body parameters
fromobjectRequired
The sender,
{ email, name? }. The email domain must be verified for this project (or the shared onboarding domain in test mode).toobject[]Required
One or more recipients, each
{ email, name? }. At least one is required.subjectstringOptional
The subject line. Required unless
templateId is given.htmlstringOptional
The HTML body. Provide
html, text, or both.textstringOptional
The plain-text body. Recommended alongside
html for deliverability.ccobject[]Optional
Carbon-copy recipients.
bccobject[]Optional
Blind carbon-copy recipients.
replyToobject[]Optional
Addresses to set in the
Reply-To header.templateIdstringOptional
Send a stored template by id or slug. With a template,
subject/html/text are optional and merge variables come from data.dataobjectOptional
Merge variables for the template (
{{handlebars}} placeholders).headersobjectOptional
Extra headers to set on the message, as a string-to-string map.
tagsobject[]Optional
Labels for filtering and analytics, each
{ name, value }.attachmentsobject[]Optional
Files to attach, each
{ filename, content, contentType? } where content is base64-encoded bytes.scheduledAtstringOptional
Schedule the send for a future time (ISO 8601). Omit to send immediately.
02 Headers
Idempotency-KeyheaderOptional
Make this POST safe to retry — the same key replays the original result for 24 hours, per project. See Idempotency & retries.
X-Drin-ProductheaderOptional
Names the sending project for account-wide keys (alias:
X-Drin-Sender). Project-scoped keys may omit it.03 Request
curl https://api.drin.run/v1/emails \
-H "Authorization: Bearer $DRIN_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": { "email": "onboarding@yourdomain.com", "name": "Acme" },
"to": [{ "email": "you@example.com" }],
"subject": "Hello from Drin",
"html": "<p>It works!</p>",
"text": "It works!"
}'04 Response
202 Accepted — the message was queued. Track its lifecycle with GET /v1/emails/{id} or over webhooks.
{
"id": "msg_01HZX9K3T2QF7P0M4N8B6C5D",
"status": "queued"
}Errors
422 validation_error if a field is malformed (param names the field); 409 suppressed if every recipient is on the suppression list; 409 conflict on an idempotency replay with a different body. See Errors.Test modeThe shared onboarding domain can only deliver to your own address. To email anyone from your own brand, verify a domain first.