Mail

Send an email

Sends mail from the workspace user the key acts as. Requires mail.send, which is deliberately separate from mail.messages.write.

POST /v1/messages/send

Permission

The key must be granted mail.send

A key without it gets 403 insufficient_scope, with the missing permission named in details.

Answers 202, not 200: the message is queued and archived in Sent, and delivery happens afterwards. A 202 does not mean it arrived, and this API cannot tell you that it did.

Request body

Field Type Description
to required string[] Recipients. At least one.
subject required string
text string Plain-text body. Required unless html is given.
html string HTML body, sanitised before sending. Required unless text is given.
from string Any address you may send as: an alias, or a list you are an authorised sender of. Anything else is refused. Defaults to your mailbox address
in_reply_to string The parent's message_id, angle brackets included. The References chain is built for you.
attachments object[] Files to send along with the message. Its fields are below.

Each item in attachments

Field Type Description
filename required string As the recipient will see it.
content_type required string For example application/pdf.
content_base64 required string The file, base64 encoded. Padded or not, standard or URL-safe.
inline boolean True for an image the HTML body displays rather than a file to download. Defaults to false
content_id string Required when inline is true. The HTML refers to it as src="cid:the-id".

Request

curl https://api.veruapis.com/v1/messages/send \
  -X POST \
  -H "Authorization: Bearer vak_live_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "to": ["[email protected]"],
  "subject": "Quarterly numbers",
  "text": "The numbers are attached."
}'

Idempotency-Key is required on every write. Retrying with the same key returns the original response rather than repeating the operation, so a timeout is something you retry rather than something you investigate.

Response

Answers 202.

Field Type Description
message_id string The Message-Id assigned to the sent mail.
queued integer How many queue entries were created.
status string queued
{
  "data": {
  "message_id": "<[email protected]>",
  "queued": 1,
  "status": "queued"
},
  "meta": { "request_id": "req_01j8z9...", "timestamp": "2026-09-02T10:00:00Z" }
}
Worth knowing

Answers 202, not 200: the message is queued for delivery and archived in Sent, and delivery happens afterwards. A 202 does not mean it arrived, and this API has no way to know that it did.

Errors

Every failure uses the same shape, with a stable string code you can branch on. See the error reference.

Related

POST /v1/messages/send

Sends this body to your own workspace, for real. Edit it before running.