Skip to content

Send an email

POST
/emails
curl --request POST \
--url https://api.vaartix.com/emails \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: order-1042-receipt' \
--data '{ "from": "Acme <[email protected]>", "to": [ "[email protected]" ], "subject": "Your Acme order", "html": "<p>Thanks for your order, Priya.</p>", "tags": [ { "name": "category", "value": "receipt" } ] }'

Accepts an email and queues it for sending. Returns as soon as it is queued; follow its progress with GET /emails/{id}.

Works with send-only and full-access keys. Limited to 10 requests per second per key.

Idempotency-Key
string
<= 256 characters

Retrying with the same key within 24 hours returns the first email instead of sending again. Reusing a key with a different body returns 409 idempotency_conflict.

Example

order-1042-receipt
Media typeapplication/json
object
from
required

Must be on a domain your team has verified (or a subdomain of it), or test.vaartix.com for test mode.

string
to
required
One of:
string
cc
One of:
string
bcc
One of:
string
replyTo
One of:
string
subject
required
string
<= 998 characters
html

HTML body. Provide html, text or both.

string
text

Plain-text body.

string
headers

Custom headers such as List-Unsubscribe. Standard headers (From, To, Subject, …) cannot be set.

object
key
additional properties
string
tags
Array<object>
<= 10 items
object
name
required
string
/^[A-Za-z0-9_-]{1,256}$/
value
required
string
/^[A-Za-z0-9_-]{1,256}$/
attachments

Up to 30 MB in total. Executable files are not allowed.

Array<object>
object
filename
required
string
content
required

Base64-encoded file content.

string
contentType

Detected from the filename if omitted.

string
contentId

For inline images. Reference it in your HTML as cid:<contentId>.

string
scheduledAt

Send later, up to 30 days ahead. Times in the past send immediately.

string format: date-time

Example

{
"from": "Acme <[email protected]>",
"to": [
],
"subject": "Your Acme order",
"html": "<p>Thanks for your order, Priya.</p>",
"tags": [
{
"name": "category",
"value": "receipt"
}
]
}

The email is queued (or scheduled).

Media typeapplication/json
object
id
required
string

Example

{
"id": "em_7hq2kv9xr4m1c8d3"
}
RateLimit-Limit
integer
Example
10

Requests allowed per second for this key.

RateLimit-Remaining
integer

Requests left in the current second.

RateLimit-Reset
integer

Seconds until the limit resets.

validation_error: the request is invalid. The message says which field and why.

Media typeapplication/json
object
error
required
object
type
required

Stable, machine-readable error type.

string
Allowed values: validation_error unauthorized forbidden not_found conflict rate_limited daily_quota_exceeded domain_not_verified invalid_from_address account_paused idempotency_conflict bad_request internal_error
message
required

Human-readable explanation, safe to show to developers.

string

Example

{
"error": {
"type": "validation_error",
"message": "to: \"priya@\" is not a valid email address."
}
}

unauthorized: the API key is missing, invalid or revoked.

Media typeapplication/json
object
error
required
object
type
required

Stable, machine-readable error type.

string
Allowed values: validation_error unauthorized forbidden not_found conflict rate_limited daily_quota_exceeded domain_not_verified invalid_from_address account_paused idempotency_conflict bad_request internal_error
message
required

Human-readable explanation, safe to show to developers.

string

Example

{
"error": {
"type": "validation_error"
}
}

domain_not_verified: the from domain is not verified for your team. account_paused: sending is paused for this account. forbidden: this key is limited to a different domain.

Media typeapplication/json
object
error
required
object
type
required

Stable, machine-readable error type.

string
Allowed values: validation_error unauthorized forbidden not_found conflict rate_limited daily_quota_exceeded domain_not_verified invalid_from_address account_paused idempotency_conflict bad_request internal_error
message
required

Human-readable explanation, safe to show to developers.

string

Example

{
"error": {
"type": "domain_not_verified",
"message": "acme.in is not verified yet. Check its DNS records."
}
}

idempotency_conflict: the Idempotency-Key was used with a different request.

Media typeapplication/json
object
error
required
object
type
required

Stable, machine-readable error type.

string
Allowed values: validation_error unauthorized forbidden not_found conflict rate_limited daily_quota_exceeded domain_not_verified invalid_from_address account_paused idempotency_conflict bad_request internal_error
message
required

Human-readable explanation, safe to show to developers.

string

Example

{
"error": {
"type": "validation_error"
}
}

rate_limited: more than 10 requests in one second (see the Retry-After header). daily_quota_exceeded: your team’s daily limit is used up; it resets at midnight IST.

Media typeapplication/json
object
error
required
object
type
required

Stable, machine-readable error type.

string
Allowed values: validation_error unauthorized forbidden not_found conflict rate_limited daily_quota_exceeded domain_not_verified invalid_from_address account_paused idempotency_conflict bad_request internal_error
message
required

Human-readable explanation, safe to show to developers.

string

Example

{
"error": {
"type": "validation_error"
}
}
Retry-After
integer

Seconds to wait before retrying (rate limits only).