Send an email
POST /emails — send a single transactional email.
/emailsSend a single email from a verified domain. The from address must belong to a domain you have verified; provide at least one of html or text. Returns the created email's id.
Pass an optional Idempotency-Key header to make retries safe — see Idempotency keys.
Headers
AuthorizationstringrequiredBearer API key, e.g. Bearer mb_xxxxxxxxx.
Idempotency-KeystringoptionalOptional unique key so a retried request is processed only once (remembered 24h).
Body parameters
fromstringrequiredSender address on a verified domain. Accepts Name <addr@domain.com> or a bare address.
tostring | string[]requiredRecipient address(es). Between 1 and 50 recipients.
subjectstringrequiredThe email subject line.
htmlstringoptionalHTML body. Provide html or text (or both). Markdown-style [text](url) links and bare URLs (https://… / www.…) in the body text are converted to tracked hyperlinks automatically at send time; content already inside <a> tags, attribute values, and <pre>/<code> blocks is left untouched.
textstringoptionalPlain-text body. Provide text or html (or both).
preview_textstringoptionalInbox preview text (preheader) shown next to the subject in the recipient's inbox list. Injected as a hidden element at the top of the HTML body — never visible in the opened email, and excluded from the plain-text part. Max 150 characters.
ccstring | string[]optionalCarbon-copy recipient(s). Up to 50.
bccstring | string[]optionalBlind carbon-copy recipient(s). Up to 50.
reply_tostring | string[]optionalReply-To address(es).
headersobjectoptionalMap of custom MIME header name → value. See Custom headers.
attachmentsobject[]optionalFiles to attach (max 25 MB per file and 40 MB total per email, measured on the decoded bytes — base64 inflates the request body by roughly 33%). Each item is { filename, content | path, content_type, content_id }. See Attachments.
scheduled_atstringoptionalSchedule the email to be sent later. Natural language (e.g. in 1 min) or ISO 8601 (e.g. 2026-08-05T11:52:01.858Z). See Schedule email.
topic_idstringoptionalTopic ID for subscription handling. Each to/cc/bcc address is checked against the topic: recipients who are unsubscribed from the topic are skipped (removed from the recipient lists) and the message is sent to the rest. If every to recipient is skipped, the request is rejected with a validation_error. Addresses that are not contacts are kept unless they have unsubscribed from the topic themselves. An unknown topic_id returns a validation_error. Setting topic_id also marks the send as subscription mail, so MailBlastr adds a per-recipient unsubscribe footer and the RFC 8058 List-Unsubscribe headers; opting out removes that address from this topic only — it is not a suppression and does not affect your other email. A send without topic_id carries no unsubscribe link or header. See Unsubscribe links.
templateobjectoptionalSend using a published template instead of inline body: { id, variables }. id is the template id or alias; variables is an object of key/value pairs. When a template is set you cannot also send html/text; from, subject, and reply_to in the payload take precedence over the template defaults.
attachments[] properties
filenamestringoptionalName of the attached file.
contentstringoptionalContent of the attached file, passed as a Base64 string. Provide content or path.
pathstringoptionalURL where the attachment file is hosted; fetched at send time. Provide path or content.
content_typestringoptionalContent type for the attachment. Derived from filename when not set.
content_idstringoptionalEmbeds the file as an inline image: reference it in your HTML via <img src="cid:...">.
Idempotency-Key header should be unique per API request, has a maximum length of 255 characters, and expires after 24 hours.Request
import { Mailblastr } from 'mailblastr';
const mb = new Mailblastr('mb_xxxxxxxxx');
const { data, error } = await mb.emails.send({
"from": "Acme <hello@yourdomain.com>",
"to": ["delivered@mailblastr.dev"],
"subject": "Hello from MailBlastr",
"html": "<p>It works!</p>"
});
console.log({ data, error });Response
{
"id": "49a3999c-0ce1-4ea6-ab68-afcd6dc2e794"
}Errors
Returns missing_required_field if from, to, or subject is missing; validation_error if neither html nor text is provided, if to is outside 1–50 recipients, or if the from domain is not verified; invalid_from_address / invalid_to_address for malformed addresses; and 409 concurrent_idempotent_requests if a request with the same in-flight Idempotency-Key is already processing. See the error reference.