Code Examples
Copy-paste examples in Python, JavaScript, and curl. Python examples use the multimail SDK (pip install multimail). JavaScript uses native fetch.
Authentication
All authenticated endpoints require a Bearer token in the Authorization header. Your API key starts with mm_live_.
from multimail import MultiMail client = MultiMail(api_key="mm_live_YOUR_API_KEY") # Verify authentication account = client.get_account() print(account["name"], account["plan"])
const API_KEY = "mm_live_YOUR_API_KEY"; const BASE = "https://api.multimail.dev/v1"; // Verify authentication const res = await fetch(`${BASE}/account`, { headers: { "Authorization": `Bearer ${API_KEY}` } }); const account = await res.json(); console.log(account.name, account.plan);
curl https://api.multimail.dev/v1/account \
-H "Authorization: Bearer mm_live_YOUR_API_KEY"Send an Email
Send markdown-formatted email through a mailbox. In gated modes, the email is held for operator approval.
POST /v1/mailboxes/{mailbox_id}/send
result = client.send_email( mailbox_id="MAILBOX_ID", to=["[email protected]"], subject="Weekly report ready", markdown="Hi Alice,\n\nYour weekly report is attached.\n\n**Key metrics:**\n- Revenue: $42k\n- Growth: +12%", cc=["[email protected]"], idempotency_key="report-2026-w10" ) print(result["id"], result["status"]) # "pending_scan" — queued for threat scan, then approval or delivery
const res = await fetch(`${BASE}/mailboxes/MAILBOX_ID/send`, { method: "POST", headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ to: ["[email protected]"], subject: "Weekly report ready", markdown: "Hi Alice,\n\nYour weekly report is attached.\n\n**Key metrics:**\n- Revenue: $42k\n- Growth: +12%", cc: ["[email protected]"], idempotency_key: "report-2026-w10" }) }); const email = await res.json(); console.log(email.id, email.status);
curl -X POST https://api.multimail.dev/v1/mailboxes/MAILBOX_ID/send \ -H "Authorization: Bearer mm_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to": ["[email protected]"], "subject": "Weekly report ready", "markdown": "Hi Alice,\n\nYour weekly report is attached.\n\n**Key metrics:**\n- Revenue: $42k\n- Growth: +12%", "cc": ["[email protected]"], "idempotency_key": "report-2026-w10" }'
Check Inbox
List emails in a mailbox with optional filters for status, sender, date range, and direction.
GET /v1/mailboxes/{mailbox_id}/emails
emails = client.check_inbox( mailbox_id="MAILBOX_ID", status="unread", limit=10, direction="inbound" ) for e in emails["emails"]: print(f"{e['from']}: {e['subject']}")
const params = new URLSearchParams({ status: "unread", limit: "10", direction: "inbound" }); const res = await fetch( `${BASE}/mailboxes/MAILBOX_ID/emails?${params}`, { headers: { "Authorization": `Bearer ${API_KEY}` } } ); const { emails } = await res.json(); emails.forEach(e => console.log(e.from, e.subject));
curl "https://api.multimail.dev/v1/mailboxes/MAILBOX_ID/emails?status=unread&limit=10&direction=inbound" \ -H "Authorization: Bearer mm_live_YOUR_API_KEY"
Read an Email
Fetch a single email with its full markdown body, attachments, and delivery status. Automatically marks unread emails as read.
GET /v1/mailboxes/{mailbox_id}/emails/{email_id}
email = client.read_email( mailbox_id="MAILBOX_ID", email_id="EMAIL_ID" ) print(email["from"]) print(email["subject"]) print(email["markdown"]) # Check attachments for att in email.get("attachments", []): print(f" {att['name']} ({att['size']} bytes)")
const res = await fetch( `${BASE}/mailboxes/MAILBOX_ID/emails/EMAIL_ID`, { headers: { "Authorization": `Bearer ${API_KEY}` } } ); const email = await res.json(); console.log(email.from, email.subject); console.log(email.markdown); // Check attachments email.attachments?.forEach(att => console.log(` ${att.name} (${att.size} bytes)`) );
curl https://api.multimail.dev/v1/mailboxes/MAILBOX_ID/emails/EMAIL_ID \
-H "Authorization: Bearer mm_live_YOUR_API_KEY"Reply to an Email
Reply to an existing email. Automatically sets the recipient, subject line (Re: ...), and thread ID.
POST /v1/mailboxes/{mailbox_id}/reply/{email_id}
reply = client.reply_email( mailbox_id="MAILBOX_ID", email_id="EMAIL_ID", markdown="Thanks for the update. I'll process this and follow up by EOD." ) print(reply["id"], reply["status"], reply["thread_id"])
const res = await fetch( `${BASE}/mailboxes/MAILBOX_ID/reply/EMAIL_ID`, { method: "POST", headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ markdown: "Thanks for the update. I'll process this and follow up by EOD." }) } ); const reply = await res.json(); console.log(reply.id, reply.status, reply.thread_id);
curl -X POST https://api.multimail.dev/v1/mailboxes/MAILBOX_ID/reply/EMAIL_ID \ -H "Authorization: Bearer mm_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"markdown": "Thanks for the update. I'\''ll process this and follow up by EOD."}'
List Pending Approvals
Fetch all emails waiting for operator approval. Requires oversight or oversight_read scope.
GET /v1/oversight/pending
pending = client.list_pending() for e in pending["emails"]: print(f"{e['direction']} | {e['from']} -> {e['to']} | {e['subject']}") print(f" Body: {e['body_markdown'][:100]}...")
const res = await fetch(`${BASE}/oversight/pending`, { headers: { "Authorization": `Bearer ${API_KEY}` } }); const { emails } = await res.json(); emails.forEach(e => { console.log(`${e.direction} | ${e.from} -> ${e.to} | ${e.subject}`); console.log(` Body: ${e.body_markdown?.slice(0, 100)}...`); });
curl https://api.multimail.dev/v1/oversight/pending \
-H "Authorization: Bearer mm_live_YOUR_API_KEY"Approve or Reject an Email
Decide on a pending email. Approved outbound emails are sent immediately. Requires oversight scope.
POST /v1/oversight/decide
# Approve an email result = client.decide_email( email_id="EMAIL_ID", action="approve" ) print(result["status"]) # "approved_and_sent" or "approved" # Reject an email result = client.decide_email( email_id="EMAIL_ID", action="reject" ) print(result["status"]) # "rejected"
// Approve an email const res = await fetch(`${BASE}/oversight/decide`, { method: "POST", headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ email_id: "EMAIL_ID", action: "approve" }) }); const result = await res.json(); console.log(result.status); // "approved_and_sent"
# Approve curl -X POST https://api.multimail.dev/v1/oversight/decide \ -H "Authorization: Bearer mm_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"email_id": "EMAIL_ID", "action": "approve"}' # Reject curl -X POST https://api.multimail.dev/v1/oversight/decide \ -H "Authorization: Bearer mm_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{"email_id": "EMAIL_ID", "action": "reject"}'
Set Up a Webhook
Subscribe to events like incoming emails, deliveries, and bounces. Webhook payloads are signed with a unique secret.
POST /v1/webhooks
webhook = client.create_webhook( url="https://your-server.com/hooks/multimail", events=[ "message.received", "message.delivered", "message.bounced", "oversight.pending" ] ) print(f"Webhook ID: {webhook['id']}") print(f"Signing secret: {webhook['signing_secret']}") # Save the signing_secret to verify incoming webhook payloads
const res = await fetch(`${BASE}/webhooks`, { method: "POST", headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ url: "https://your-server.com/hooks/multimail", events: [ "message.received", "message.delivered", "message.bounced", "oversight.pending" ] }) }); const webhook = await res.json(); console.log(`Webhook ID: ${webhook.id}`); console.log(`Signing secret: ${webhook.signing_secret}`);
curl -X POST https://api.multimail.dev/v1/webhooks \ -H "Authorization: Bearer mm_live_YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://your-server.com/hooks/multimail", "events": [ "message.received", "message.delivered", "message.bounced", "oversight.pending" ] }'
Search Contacts
Search your contact list by name or email address. Returns matching contacts with tags.
GET /v1/contacts?q={query}
contacts = client.search_contacts(q="alice") for c in contacts["contacts"]: print(f"{c['name']} <{c['email']}> tags={c['tags']}")
const res = await fetch( `${BASE}/contacts?q=alice`, { headers: { "Authorization": `Bearer ${API_KEY}` } } ); const { contacts } = await res.json(); contacts.forEach(c => console.log(`${c.name} <${c.email}> tags=${c.tags}`) );
curl "https://api.multimail.dev/v1/contacts?q=alice" \ -H "Authorization: Bearer mm_live_YOUR_API_KEY"