MillionSend Docs

/emails

POST
/emails

Request Body

application/json
  1. body
from*string

Sender, "Name user@domain" or bare address; the domain must be verified for the team

to*|array<string>

Recipient address or list of up to 50

subject*string

Subject line

Length1 <= length <= 998
html?string

HTML body; at least one of html/text is required

text?string

Plain-text body; at least one of html/text is required

cc?|array<string>

Cc address or list

bcc?|array<string>

Bcc address or list

reply_to?|array<string>

Reply-To address or list

scheduled_at?string

Deliver later: ISO 8601 with offset, or relative like "in 2 hours" (an ISO 8601 datetime with offset (e.g. "2026-09-01T12:00:00Z") or a relative time like "in 5 mins", "in 2 hours", or "in 1 day"); max 30 days ahead

tags?array<>

Key/value labels attached to the email for filtering; names starting with millionsend_, in any letter case, are reserved

topic_id?string

Topic id: recipients opted out of the topic are skipped; a send to one address that is a contact also gets that contact's unsubscribe link

Formatuuid
attachments?array<>

Attachments with base64 content (no remote paths)

headers?

Extra message headers (transport headers are rejected)

template?unknown

Not supported: any value is a 422; an email takes html and/or text

Response Body

Email accepted

application/json
  1. response
id*string
Formatuuid
warning?

Only on an email the new domain limit holds for later. It is still accepted and goes out on its own.

Example Request
curl -X POST 'https://api.millionsend.com/emails' \  -H 'Content-Type: application/json' \  -d '{  "from": "string",  "to": "string",  "subject": "string"}'
Example Response
{  "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",  "warning": {    "code": "new_domain_limit",    "message": "string",    "sends_after": "string"  }}