Sending
Messages
Send email — inline or templated — and read its full lifecycle back.
A message is a single email to a single recipient. Send inline HTML, or reference a template by slug or id and pass variables.
Send a message
POST
/v1/messagestorequiredstring | Recipient address, or { email, name }. |
subjectstring | Required unless the template supplies one. |
html / textstring | Inline body. Omit when using a template. |
templatestring | A template slug. Use template_id for the id. |
variablesobject | Values merged into the template (Handlebars). |
from / reply_tostring | Override the sender / reply-to (must be a verified sender). |
typeenum | `transactional` (default) or `marketing` — meters against the right wing. |
send_atstring | ISO 8601 — schedule for later instead of sending now. |
idempotency_keystring | Exactly-once — see Idempotency. |
tags / metadataarray / object | Your own labels; echoed back on events. |
send-template.ts
const msg = await mail.messages.create({
to: { email: "ada@example.com", name: "Ada" },
template: "welcome",
variables: { name: "Ada", action_url: "https://acme.com/start" },
tags: ["onboarding"],
idempotencyKey: `welcome-${user.id}`,
});
// → { id: "msg_…", status: "queued", … }Retrieve, audit & prove
GET
/v1/messagesGET
/v1/messages/:idGET
/v1/messages/:id/auditGET
/v1/messages/:id/proofaudit.ts
const { trail } = await mail.messages.audit(msg.id);
// queued → sending → sent → delivered → opened …
const proof = await mail.messages.proof(msg.id); // { bundle, signature }noteSuppressed, bounced, and unsubscribed recipients are checked automatically before every send — you can't accidentally email someone who opted out.