Skip to main content
Queue a single transactional email. The request returns immediately with a message id; delivery happens asynchronously and is reported over webhooks. POST /v1/emails Provide 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.

Body parameters

from
object
required
The sender, { email, name? }. The email domain must be verified for this project (or the shared onboarding domain in test mode).
to
object[]
required
One or more recipients, each { email, name? }. At least one is required.
subject
string
The subject line. Required unless templateId is given.
html
string
The HTML body. Provide html, text, or both.
text
string
The plain-text body. Recommended alongside html for deliverability.
cc
object[]
Carbon-copy recipients.
bcc
object[]
Blind carbon-copy recipients.
replyTo
object[]
Addresses to set in the Reply-To header.
templateId
string
Send a stored template by id or slug. With a template, subject/html/text are optional and merge variables come from data.
data
object
Merge variables for the template ({{handlebars}} placeholders).
headers
object
Extra headers to set on the message, as a string-to-string map.
tags
object[]
Labels for filtering and analytics, each { name, value }.
attachments
object[]
Files to attach, each { filename, content, contentType? } where content is base64-encoded bytes.
scheduledAt
string
Schedule the send for a future time (ISO 8601). Omit to send immediately.

Headers

Idempotency-Key
header
Make this POST safe to retry — the same key replays the original result for 24 hours, per project. See Idempotency & retries.
X-Drin-Product
header
Names the sending project for account-wide keys (alias: X-Drin-Sender). Project-scoped keys may omit it.

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!"
  }'

Response

202 Accepted — the message was queued. Track its lifecycle with GET /v1/emails/{id} or over webhooks.
202 Accepted
{
  "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 mode. The shared onboarding domain can only deliver to your own address. To email anyone from your own brand, verify a domain first.