Misar Docs
MisarMailMisar.BlogMisarReachMisarPostMisar.DevMisar PlatformMisar IdentityMisar Posts API
Api Reference

Send Email

Send transactional and marketing emails via POST /v1/send

Authentication

POST /v1/send requires Authorization: Bearer msk_… with the send, send:transactional, or send:marketing scope. Base URL: https://api.misar.io/mail.

POST/mail/v1/send

Send a transactional or marketing email. Either html or text is required — supplying both is strongly recommended, as many clients render only plain text.

Request body

from.emailstringbodyrequired

Sender address. Must be a verified domain owned by the API key.

from.namestringbody

Display name shown in the recipient's email client.

toArray<{email, name?}>bodyrequired

Up to 100 recipients.

ccArray<{email, name?}>body

Up to 50 CC recipients.

bccArray<{email, name?}>body

Up to 50 BCC recipients.

reply_to{email, name?}body

Reply-to address.

subjectstringbodyrequired

Max 998 characters.

htmlstringbody

HTML email body. Required unless text is provided.

textstringbody

Plain-text fallback. Required unless html is provided.

alias_idUUIDbody

Route via a specific SMTP pool.

idempotency_keystringbody

Prevent duplicate sends (max 128 chars).

tagsstring[]body

Up to 10 tags for tracking.

metadataRecord<string, string>body

Custom key-value data.

Response fields

successboolean

true when the message was accepted for delivery.

message_idstring

Unique identifier for the sent message. Use it for delivery tracking.

providerstring

Delivery provider — smtp, sandbox, etc.

timestampstring

ISO-8601 acceptance time.

curl https://api.misar.io/mail/v1/send \
  -H "Authorization: Bearer msk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "from":    { "email": "[email protected]", "name": "Misar" },
    "to":      [{ "email": "[email protected]", "name": "User" }],
    "subject": "Welcome to Misar!",
    "html":    "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
    "text":    "Welcome! Thanks for signing up."
  }'
{
  "success":    true,
  "message_id": "msg_abc123",
  "provider":   "smtp",
  "timestamp":  "2026-02-17T12:00:00.000Z"
}
{
  "success": false,
  "queued":  true,
  "message": "Email queued for retry"
}
{
  "success":    false,
  "suppressed": true,
  "error":      "Send suppressed — recipient unsubscribed or bounced"
}

Status codes

  • 200 — Sent. Message accepted and handed to the provider.
  • 202 — Queued for retry. The primary SMTP provider was briefly unavailable; the email retries automatically. Do not treat 202 as an error.
  • 422 — Suppressed. The recipient previously unsubscribed or hard-bounced, so the send was intentionally blocked to protect deliverability. Do not retry — remove them from your send list or check their status via the Contacts API.

Sandbox Mode

Append the X-MisarMail-Sandbox: true header to store the send in the sandbox_sends table without delivering to the real recipient. Useful for integration testing and CI pipelines.

curl https://api.misar.io/mail/v1/send \
  -H "Authorization: Bearer msk_your_key_here" \
  -H "Content-Type: application/json" \
  -H "X-MisarMail-Sandbox: true" \
  -d '{
    "from":    { "email": "[email protected]", "name": "Misar" },
    "to":      [{ "email": "[email protected]" }],
    "subject": "Sandbox test",
    "text":    "This will not be delivered."
  }'

Sandbox response:

{
  "success":    true,
  "message_id": "sandbox_msg_xyz789",
  "provider":   "sandbox",
  "timestamp":  "2026-02-17T12:00:00.000Z"
}

Requires the sandbox scope on your API key. Sandbox sends count against rate limits but not against your monthly plan quota.

Examples

curl https://api.misar.io/mail/v1/send \
  -H "Authorization: Bearer msk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "from":    { "email": "[email protected]", "name": "Misar" },
    "to":      [{ "email": "[email protected]", "name": "User" }],
    "subject": "Welcome to Misar!",
    "html":    "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
    "text":    "Welcome! Thanks for signing up."
  }'
const res = await fetch("https://api.misar.io/mail/v1/send", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.MISARMAIL_API_KEY}`,
    "Content-Type": "application/json",
    "X-Source-App": "MyApp",
  },
  body: JSON.stringify({
    from:    { email: "[email protected]", name: "Misar" },
    to:      [{ email: "[email protected]", name: "User" }],
    subject: "Welcome to Misar!",
    html:    "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
    text:    "Welcome! Thanks for signing up.",
    idempotency_key: `welcome-${userId}`,
  }),
});

const data = await res.json();

if (!res.ok && !data.queued) {
  throw new Error(data.error || "Failed to send email");
}
import os, requests

response = requests.post(
    "https://api.misar.io/mail/v1/send",
    headers={
        "Authorization": f"Bearer {os.environ['MISARMAIL_API_KEY']}",
        "Content-Type": "application/json",
        "X-Source-App": "MyApp",
    },
    json={
        "from":    {"email": "[email protected]", "name": "Misar"},
        "to":      [{"email": "[email protected]", "name": "User"}],
        "subject": "Welcome to Misar!",
        "html":    "<h1>Welcome!</h1><p>Thanks for signing up.</p>",
        "text":    "Welcome! Thanks for signing up.",
        "idempotency_key": f"welcome-{user_id}",
    },
)

data = response.json()
if not response.ok and not data.get("queued"):
    raise Exception(data.get("error", "Failed to send email"))

Idempotency

Use idempotency_key to prevent duplicate emails when retrying failed requests:

{
  "idempotency_key": "welcome-usr_abc123"
}

If a request with the same key was already delivered within 24 hours, the API returns the original result without re-sending:

{
  "success":    true,
  "message_id": "msg_abc123",
  "provider":   "smtp",
  "idempotent": true,
  "timestamp":  "2026-02-17T12:00:00.000Z"
}

Use a unique key per logical send event (e.g., welcome-<userId>, invoice-<invoiceId>).

SMTP Pool Routing

By default, emails are routed through the best available SMTP pool. To force a specific pool (e.g., transactional vs. promotional), pass alias_id:

{
  "alias_id": "550e8400-e29b-41d4-a716-446655440000"
}

Find alias IDs in Settings → SMTP Pools or via the API Keys settings page.