Sending email
There are two ways to send: one message at a time, or a batch of up to 100 in a single request. Both validate each email (valid addresses, a body, a verified from-domain, and that the recipient isn't suppressed) and enforce the usage-only billing gate before queueing.
The email object
Every send uses the same shape:
from— sender address on a verified domain (required).fromName— optional display name.to— recipient address (required).cc,bcc,replyTo— optional.subject— required.htmland/ortext— at least one body is required.templateId— optional template to render instead of an inline body.variables— optional key/value map for substitution.tags— optional comma-separated labels for your own reporting.
Single send
A successful POST /v1/emails returns 202 Accepted with the message id
and "status": "queued". If the free tier is exhausted and no payment method is on
file (or your spend cap is reached), you'll get 402 Payment Required.
Batch send
POST /v1/emails/batch accepts an emails array of up to 100 items. Each
item is validated and queued independently — the response reports how many were accepted vs.
rejected, with a per-item error for any that failed:
curl https://api.mailstack.voostack.com/v1/emails/batch \
-H "Authorization: Bearer ms_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"emails": [
{ "from": "hi@you.com", "to": "a@example.com", "subject": "Hi A", "text": "Hello A" },
{ "from": "hi@you.com", "to": "b@example.com", "subject": "Hi B", "text": "Hello B" }
]
}'{
"accepted": 1,
"rejected": 1,
"results": [
{ "index": 0, "id": "…", "status": "queued" },
{ "index": 1, "status": "rejected", "error": "Recipient is suppressed." }
]
} Variables & tags
Pass variables to fill in {{ placeholders }} in your subject or
body, and tags to label messages for your own segmentation:
curl https://api.mailstack.voostack.com/v1/emails \
-H "Authorization: Bearer ms_live_xxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"from": "hi@you.com",
"to": "user@example.com",
"subject": "Welcome, {{ name }}",
"html": "<p>Hi {{ name }}, your code is {{ code }}.</p>",
"variables": { "name": "Sam", "code": "8421" },
"tags": "welcome,onboarding"
}'Checking status
Call GET /v1/emails/{id} to retrieve a message and its current status. The
response includes the lifecycle status, the provider message id once sent, recipients, subject,
tags, and timestamps:
{
"id": "8f3a1c2e-…",
"fromEmail": "hi@you.com",
"toEmail": "user@example.com",
"subject": "Welcome",
"status": "Sent",
"providerMessageId": "0102018f…",
"errorMessage": null,
"tags": "welcome,onboarding",
"queuedAt": "2026-06-18T10:00:00Z",
"sentAt": "2026-06-18T10:00:02Z",
"createdAt": "2026-06-18T10:00:00Z"
}