API documentation
One endpoint, one auth header, JSON in and out. Base URL: https://mailfleet.dev
Quickstart
- Sign up (Google or email) and add a sending domain. The dashboard shows the DNS records to add — publish them at your DNS provider and click Check verification.
- Create an API key in the dashboard. Keys look like
mf_live_…and are shown once, at creation. - Send:
curl https://mailfleet.dev/api/v1/send \
-H "Authorization: Bearer mf_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <receipts@acme.com>",
"to": "customer@example.com",
"subject": "Your receipt",
"html": "<p>Thanks for your order!</p>"
}'Official SDK
Zero-dependency TypeScript client for Node 18+, serverless, edge, Bun and Deno. Typed errors with machine-readable codes.
npm install mailfleetimport { MailFleet } from "mailfleet";
const mailfleet = new MailFleet(process.env.MAILFLEET_API_KEY!);
const { id } = await mailfleet.send({
from: "Acme <hello@acme.com>",
to: "customer@example.com",
subject: "Your receipt",
html: "<p>Thanks for your order!</p>",
});Authentication
Pass your API key as a bearer token on every request:
Authorization: Bearer mf_live_xxxxxxxx- Keys are displayed once when created. Store them in a secret manager, not in code.
- Revoke a key at any time from the dashboard; revocation is immediate.
- Requests without a valid key return
401 invalid_api_key.
POST/api/v1/send
Sends one message to up to 50 recipients. Body is JSON.
Request fields
| Field | Type | Required | Description |
|---|---|---|---|
| from | string | required | Sender address. Must be on one of your verified domains. Supports a display name: "Acme <receipts@acme.com>". |
| to | string | string[] | required | Recipient address, or an array of addresses. Max 50 per request. |
| subject | string | required | Subject line. |
| html | string | html and/or text | HTML body. Provide html, text, or both. |
| text | string | html and/or text | Plain-text body. Recommended alongside html for deliverability. |
| reply_to | string | optional | Reply-To address. |
Success response
200 with the provider message id:
{ "id": "<message-id>" }Errors
Errors are JSON: { "error": "<code>" }, sometimes with extra fields noted below.
| Status | Code | Meaning |
|---|---|---|
| 401 | invalid_api_key | The Authorization header is missing, malformed, or the key has been revoked. |
| 422 | validation_error | The request body failed validation. A message field explains what is wrong. |
| 403 | domain_not_verified | The from domain is not one of your verified sending domains. |
| 403 | account_paused | Your account was paused for exceeding bounce or complaint thresholds. Contact hello@mailfleet.dev. |
| 429 | quota_exceeded | You hit your plan's monthly email quota. The response includes a limit field. Resets at the start of the next month. |
| 502 | send_failed | The upstream provider rejected the message. Nothing was sent; safe to retry. |
Domains & DNS
You can only send from domains you have verified. Adding a domain in the dashboard generates the exact records to publish at your DNS provider:
- DKIM — three CNAME records that cryptographically sign your mail. Required for verification.
- MAIL FROM — one MX and one TXT (SPF) record on a subdomain, so bounces return to us and SPF aligns with your domain.
- DMARC — a TXT record telling mailbox providers what to do with mail that fails authentication. Strongly recommended; start with
p=noneand tighten once reports look clean.
After the records propagate (usually minutes, sometimes up to 48 hours), click Check verification in the dashboard. Sending from an unverified domain returns 403 domain_not_verified.
Quotas & plans
Quotas are per calendar month. Each recipient counts as one email. When the quota is reached, sends return 429 quota_exceeded until the period resets or you upgrade.
| Plan | Price | Emails / month | Sending domains |
|---|---|---|---|
| Free | $0/mo | 3,000 | 1 |
| Starter | $10/mo | 50,000 | 3 |
| Pro | $29/mo | 200,000 | 10 |
| Business | $99/mo | 1,000,000 | Unlimited |
Deliverability & fair use
- MailFleet is for transactional email — receipts, magic links, alerts, notifications — to recipients who opted in. No cold outreach, no purchased lists.
- Hard bounces and spam complaints are recorded automatically; suppressed addresses are not sent to again.
- Accounts whose bounce or complaint rates exceed our thresholds are paused automatically and sends return
403 account_paused. - Full rules, thresholds and the abuse-report address are in the Acceptable Use Policy.
Examples
Node.js (fetch)
const res = await fetch("https://mailfleet.dev/api/v1/send", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.MAILFLEET_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "Acme <receipts@acme.com>",
to: ["customer@example.com"],
subject: "Your receipt",
html: "<p>Thanks for your order!</p>",
text: "Thanks for your order!",
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(`MailFleet: ${err.error}`);
}
const { id } = await res.json();curl
curl https://mailfleet.dev/api/v1/send \
-H "Authorization: Bearer mf_live_xxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"from": "Acme <receipts@acme.com>",
"to": "customer@example.com",
"subject": "Your receipt",
"html": "<p>Thanks for your order!</p>"
}'