// reference
API reference.
Every endpoint VoltMail exposes. All requests speak JSON over HTTPS. Base URL https://api.voltmail.dev.
// send
Send email
Send a single email. Returns a queued ID; the actual delivery happens asynchronously.
/v1/emails// parameters
| Name | In | Type | Description |
|---|---|---|---|
| from* | body | string | Verified sending address. Must use a verified domain. |
| to* | body | string[] | Up to 50 recipients. Each will receive an individual delivery. |
| subject* | body | string | Email subject line. UTF-8, ≤998 bytes. |
| html | body | string | HTML body. Either html or text is required. |
| text | body | string | Plaintext body. Either html or text is required. |
| reply_to | body | string | Reply-To header. |
| tags | body | string[] | Up to 10 tags for filtering and analytics. |
curlcurl https://api.voltmail.dev/v1/emails \
-H "Authorization: Bearer $VOLTMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "from": "noreply@receipts.acme.dev", "to": ["jane@example.com"], "subject": "Your receipt", "html": "<p>Thanks for your order.</p>", "text": "Thanks for your order."}'request body{
"from": "noreply@receipts.acme.dev",
"to": ["jane@example.com"],
"subject": "Your receipt",
"html": "<p>Thanks for your order.</p>",
"text": "Thanks for your order."
}// responses
| 202 | Email accepted and queued. |
| 400 | Bad request — missing required field or malformed JSON. |
| 401 | Missing or invalid API key. |
| 422 | Sender domain not verified, or recipient count exceeds 50. |
example response{
"id": "em_01HV9X3Q8K2BM0F7Z8E5T6Y9N3",
"status": "queued",
"created_at": "2026-05-01T12:00:00Z"
}Send batch
Submit up to 100 messages in a single request. Each is queued independently.
/v1/emails/batch// parameters
| Name | In | Type | Description |
|---|---|---|---|
| messages* | body | object[] | Array of message objects. Same shape as POST /v1/emails. Max 100. |
curlcurl https://api.voltmail.dev/v1/emails/batch \
-H "Authorization: Bearer $VOLTMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d @batch.jsonrequest body{
"messages": [
{ "from": "noreply@acme.dev", "to": ["a@example.com"], "subject": "Hi", "text": "Hello A" },
{ "from": "noreply@acme.dev", "to": ["b@example.com"], "subject": "Hi", "text": "Hello B" }
]
}// responses
| 202 | All messages accepted. |
| 207 | Partial success — some messages rejected. |
| 413 | Batch exceeded 100 messages. |
example response{
"accepted": 2,
"ids": ["em_01HV9X3Q8K2BM0F7Z8E5T6Y9N3", "em_01HV9X3Q8K2BM0F7Z8E5T6Y9N4"]
}Retrieve email
Look up a single email by ID — returns delivery status and timeline.
/v1/emails/{id}// parameters
| Name | In | Type | Description |
|---|---|---|---|
| id* | path | string | Email ID returned from POST /v1/emails. |
curlcurl https://api.voltmail.dev/v1/emails/em_01HV9X3Q8K2BM0F7Z8E5T6Y9N3 \
-H "Authorization: Bearer $VOLTMAIL_API_KEY"// responses
| 200 | Email record with status timeline. |
| 404 | No email with that ID. |
// domains
Add sending domain
Register a new sending domain. Returns the DNS records you need to publish.
/v1/domains// parameters
| Name | In | Type | Description |
|---|---|---|---|
| domain* | body | string | The hostname you want to send from. Use a subdomain — e.g. receipts.acme.dev. |
| region | body | string | us-east-1 (default), eu-west-1, or ap-south-1. |
curlcurl https://api.voltmail.dev/v1/domains \
-H "Authorization: Bearer $VOLTMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "domain": "receipts.acme.dev", "region": "us-east-1"}'request body{
"domain": "receipts.acme.dev",
"region": "us-east-1"
}// responses
| 201 | Domain created. Publish the records and call verify. |
| 409 | Domain already exists in this account. |
example response{
"id": "dom_01HV9X4P0N2A8B6C5D4E3F2G1H",
"domain": "receipts.acme.dev",
"status": "pending",
"records": [
{ "type": "TXT", "name": "@", "value": "v=spf1 include:_spf.voltmail.dev -all" },
{ "type": "TXT", "name": "voltmail._domainkey", "value": "v=DKIM1; k=rsa; p=…" },
{ "type": "CNAME", "name": "_dmarc", "value": "_dmarc.voltmail.dev" }
]
}Get domain status
Check the verification status. Each DNS record reports verified | pending | failed.
/v1/domains/{id}// parameters
| Name | In | Type | Description |
|---|---|---|---|
| id* | path | string | Domain ID. |
curlcurl https://api.voltmail.dev/v1/domains/dom_01HV9X4P0N2A8B6C5D4E3F2G1H \
-H "Authorization: Bearer $VOLTMAIL_API_KEY"// responses
| 200 | Domain object with per-record check results. |
| 404 | No domain with that ID. |
List domains
Return all domains in this account, paginated.
/v1/domains// parameters
| Name | In | Type | Description |
|---|---|---|---|
| limit | query | integer | Page size, default 25, max 100. |
| cursor | query | string | Pagination cursor from a previous response. |
curlcurl 'https://api.voltmail.dev/v1/domains?limit=50' \
-H "Authorization: Bearer $VOLTMAIL_API_KEY"// responses
| 200 | Paginated array of domain objects. |
Remove domain
Remove a domain from your account. In-flight messages still complete; new sends are rejected.
/v1/domains/{id}// parameters
| Name | In | Type | Description |
|---|---|---|---|
| id* | path | string | Domain ID. |
curlcurl -X DELETE https://api.voltmail.dev/v1/domains/dom_01HV9X4P0N2A8B6C5D4E3F2G1H \
-H "Authorization: Bearer $VOLTMAIL_API_KEY"// responses
| 204 | Removed. |
| 404 | Domain not found. |
// api keys
Create API key
Mint a new API key. The plaintext key is shown once — store it immediately.
/v1/api-keys// parameters
| Name | In | Type | Description |
|---|---|---|---|
| name* | body | string | Human-readable label, e.g. "Staging server". |
| scope | body | string | send_only | full_access. Default full_access. |
curlcurl https://api.voltmail.dev/v1/api-keys \
-H "Authorization: Bearer $VOLTMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "name": "Production server", "scope": "send_only"}'request body{
"name": "Production server",
"scope": "send_only"
}// responses
| 201 | Key created. Plaintext appears only on this response. |
| 403 | Caller lacks permission to mint keys. |
example response{
"id": "key_01HV9X5R6T7U8V9W0X1Y2Z3A4B",
"name": "Production server",
"key": "vm_live_8K2BM0F7Z8E5T6Y9N3J4Q5R6",
"scope": "send_only",
"created_at": "2026-05-01T12:00:00Z"
}List API keys
Return key metadata. Plaintext is never re-displayed.
/v1/api-keys// parameters
// no parameters
curlcurl https://api.voltmail.dev/v1/api-keys \
-H "Authorization: Bearer $VOLTMAIL_API_KEY"// responses
| 200 | Array of key metadata records. |
Revoke API key
Immediately revoke a key. In-flight requests using it will fail with 401.
/v1/api-keys/{id}// parameters
| Name | In | Type | Description |
|---|---|---|---|
| id* | path | string | API key ID. |
curlcurl -X DELETE https://api.voltmail.dev/v1/api-keys/key_01HV9X5R6T7U8V9W0X1Y2Z3A4B \
-H "Authorization: Bearer $VOLTMAIL_API_KEY"// responses
| 204 | Revoked. |
// audiences
Create contact
Add a contact to an audience. Idempotent on (audience_id, email).
/v1/contacts// parameters
| Name | In | Type | Description |
|---|---|---|---|
| email* | body | string | Recipient email address. |
| audience_id* | body | string | Target audience. |
| first_name | body | string | Optional first name. |
| last_name | body | string | Optional last name. |
curlcurl https://api.voltmail.dev/v1/contacts \
-H "Authorization: Bearer $VOLTMAIL_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "email": "jane@example.com", "first_name": "Jane", "last_name": "Doe", "audience_id": "aud_01HV9X6S7T8U9V0W1X2Y3Z4A5B"}'request body{
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Doe",
"audience_id": "aud_01HV9X6S7T8U9V0W1X2Y3Z4A5B"
}// responses
| 201 | Contact created. |
| 200 | Contact already exists — returns the existing record. |