Everything you need to integrate MX Forwarder into your application.
Building an integration with an AI coding assistant? These machine-readable formats are optimized for LLMs:
Tip: paste the content of /docs/api.md into your AI assistant, or use the MCP server for direct tool integration.
Sign up at mx-forwarder.com and generate an API key from the dashboard.
POST /api/addresses to get a unique address like invoices@mx-forwarder.com.
Emails sent to your address are parsed and POSTed to your webhook URL as signed JSON.
All API requests require a Bearer token. Generate one from Dashboard > API Keys.
curl -H "Authorization: Bearer mf_live_your_api_key" \ https://mx-forwarder.com/api/addresses
Base URL: https://mx-forwarder.com
/api/addresses— List all forwarding addresses/api/addresses— Create a new forwarding addressRequest Body (JSON)
local_partstring— Local part of the email (e.g. "invoices"). Random if omitted.webhook_urlstring— URL to forward emails towebhook_format"json" | "raw"— Payload format (default: json)webhook_method"POST" | "GET" | "PUT" | "PATCH"— HTTP method (default: POST)attachment_mode"url" | "inline"— "url" for signed R2 links, "inline" for base64simulationboolean— Enable test mode (no actual forwarding)store_attachmentsboolean— Store attachments in R2Response
{
"address": { "id": "01J...", "local_part": "invoices", "email": "invoices@mx-forwarder.com" },
"webhook_secret": "a1b2c3d4-..."
}/api/addresses/{id}— Get a single address/api/addresses/{id}— Update address configurationRequest Body (JSON)
webhook_urlstring— New webhook URLwebhook_format"json" | "raw"— Payload formatwebhook_method"POST" | "GET" | "PUT" | "PATCH"— HTTP methodattachment_mode"url" | "inline"— Attachment delivery modesimulationboolean— Test modestore_attachmentsboolean— R2 storageis_activeboolean— Enable/disable the address/api/addresses/{id}— Delete an address and all associated data/api/emails— List received emails with pagination and filteringQuery Parameters
qstring— Full-text search queryaddress_idstring— Filter by address IDlimitnumber— Results per page (default 50, max 100)cursorstring— Pagination cursor from previous responseResponse
{
"emails": [{ "id": "01J...", "subject": "Invoice #1234", "from_addr": "sender@example.com", ... }],
"next_cursor": "2026-04-29T09:00:00Z"
}/api/emails/{id}— Get full email with attachments and delivery historyResponse
{
"email": { "id": "01J...", "subject": "...", "text_body": "...", "html_body": "..." },
"attachments": [{ "id": "01J...", "file_name": "invoice.pdf", "content_type": "application/pdf", "size_bytes": 54321 }],
"deliveries": [{ "id": "01J...", "status": "delivered", "http_status": 200, "attempt_count": 1 }]
}/api/emails/{id}/raw— Download original RFC822 .eml file (binary, not JSON)/api/emails/{id}/retry— Re-queue email for webhook delivery/api/deliveries— List webhook delivery logsQuery Parameters
address_idstring— Filter by address IDemail_idstring— Filter by email IDstatus"pending" | "delivered" | "failed"— Filter by statuslimitnumber— Results per page (default 50, max 100)cursorstring— Pagination cursorResponse
{
"deliveries": [{ "id": "01J...", "status": "delivered", "http_status": 200, "attempt_count": 1 }],
"next_cursor": "2026-04-29T09:00:00Z"
}/api/usage— Current billing period usage and plan limitsResponse
{
"plan": "starter", "month": "2026-04",
"email_count": 142, "email_limit": 25000,
"attachment_bytes": 10485760, "attachment_limit": 2147483648,
"addresses_used": 3, "addresses_limit": 25
}/api/reseller/sub-accounts— List all sub-accountsResponse
{
"sub_accounts": [{ "id": "01J...", "email": "feeder-abc123@newsletter.acme.com", "plan": "free", "external_id": "usr_abc123", "created_at": "..." }],
"total": 1
}/api/reseller/sub-accounts— Create sub-account. Email is an identifier (can be synthetic). Returns API key (once).Request Body (JSON)
emailstringrequired— Identifier (can be synthetic, e.g. feeder-{userId}@your-domain.com)planstring— Plan for address/retention limits (default: "free")external_idstring— Your own customer ID for mappingResponse
{
"sub_account": { "id": "01J...", "email": "feeder-abc123@newsletter.acme.com", "plan": "free", "external_id": "usr_abc123", "created_at": "..." },
"api_key": "mf_live_abc123..."
}/api/reseller/sub-accounts/{id}— Update sub-account plan or external_idRequest Body (JSON)
planstring— New plan for the sub-accountexternal_idstring— Update your customer reference/api/reseller/sub-accounts/{id}— Delete sub-account and all its data/api/reseller/usage— Aggregate usage across all sub-accountsQuery Parameters
monthstring— Billing month in YYYY-MM format (default: current)Response
{
"month": "2026-04",
"aggregate": { "email_count": 15420, "attachment_bytes": 52428800 },
"limits": { "emails_per_month": 1000000, "attachment_storage_bytes": 107374182400 },
"sub_accounts": [{ "user_id": "01J...", "email": "alice@acme.com", "email_count": 8200, "attachment_bytes": 30000000 }]
}Every email is POSTed to your webhook URL with an HMAC-SHA256 signature in the X-MailForwarder-Signature header.
{
"id": "01JQWX...",
"envelope": {
"from": "sender@example.com",
"to": "invoices@mx-forwarder.com"
},
"headers": { "subject": "Invoice #1234", "from": "...", "to": "...", "date": "..." },
"plain": "Please find attached...",
"html": "...",
"attachments": [
{
"file_name": "invoice.pdf",
"content_type": "application/pdf",
"size": 12345,
"url": "https://signed-r2-url..."
}
],
"spf": { "result": "pass" },
"dkim": { "result": "pass" },
"dmarc": { "result": "pass" }
}List endpoints use cursor-based pagination. The response includes a next_cursor field. Pass it as the cursor query parameter to get the next page. When next_cursor is null, there are no more results. Max limit is 100.
All errors return a consistent JSON structure:
{ "error": "Descriptive error message", "status": 401 }400Invalid request401Unauthorized403Plan limit exceeded404Not found409Conflict (address taken)500Server errorConnect AI agents (Claude, Cursor, etc.) directly to your MX Forwarder account using the Model Context Protocol.
For Claude Desktop, Claude Code, Cursor:
{
"mcpServers": {
"mx-forwarder": {
"command": "npx",
"args": ["@mx-forwarder/mcp"],
"env": { "MX_FORWARDER_API_KEY": "mf_live_your_api_key" }
}
}
}For MCP clients with OAuth support:
https://mx-forwarder.com/api/mcphttps://mx-forwarder.com/.well-known/oauth-authorization-serverlist_addresses— List forwarding addressescreate_address— Create a new addressupdate_address— Update address configdelete_address— Delete an addresslist_emails— List and search emailsget_email— Get email detailsretry_email_delivery— Retry failed deliverylist_deliveries— List delivery logsget_usage— Get usage statslist_sub_accounts— List reseller sub-accountscreate_sub_account— Create a sub-accountget_reseller_usage— Aggregate reseller usageBuild email-to-webhook functionality into your own SaaS product. The reseller plan lets you create sub-accounts for your customers, track their usage individually, and get billed for aggregate consumption.
POST /api/reseller/sub-accounts with each customer's emailGET /api/reseller/usagecurl -X POST https://mx-forwarder.com/api/reseller/sub-accounts \ -H "Authorization: Bearer mf_live_your_reseller_key" \ -H "Content-Type: application/json" \ -d "text-amber-300">'{"email": "customer@acme.com"}' "text-[#52525b]"># Response: "text-[#52525b]"># { "sub_account": { "id": "01J...", "email": "customer@acme.com" }, "text-[#52525b]"># "api_key": "mf_live_abc123..." }
Create your free account and set up your first address in under a minute.
Create free account