10 · MailMarco API
Mailboxes
Real mailboxes your customers log into — IMAP, SMTP, calendar and contacts — provisioned through the API.
The model
Four resources, in the order you create them. Each one only makes sense once the one above it exists.
| Resource | What it is |
|---|---|
mailbox-domain | A domain whose MX points at MailMarco, so mail for it lands here. Must be verified before it can hold mailboxes. |
mailbox | An account with a password, a quota and a message store. This is the thing a person logs into. |
alias | A second address that delivers into an existing mailbox. No password, no quota of its own. |
forwarder | A rule that sends arriving mail on to an external address, with or without keeping a copy. |
Hosting domains
Adding a domain returns the MX record to publish. Nothing can be created inside it until verification sees that record in DNS.
/v1/mailbox-domainsRegister a hosting domain and get its MX record.
Body
domainstringrequired | Lower-cased and trimmed. Same grammar as a sending domain. |
curl -X POST https://api.mailmarco.com/v1/mailbox-domains \
-H "authorization: Bearer $MAILMARCO_ACCESS_TOKEN" \
-H "content-type: application/json" \
-d '{"domain":"mail.example.com"}'{
"id": "9a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"domain": "mail.example.com",
"status": "pending",
"mxHost": "mail.mailmarco.com",
"mxPriority": 10,
"catchAllMailboxId": null,
"verifiedAt": null,
"dnsRecord": {
"host": "mail.example.com",
"recordType": "MX",
"value": "10 mail.mailmarco.com",
"ttl": 3600
}
}/v1/mailbox-domains/:id/verifyRe-check DNS and flip the domain to verified.
Path parameters
iduuidrequired | The domain id. |
{ "id": "9a1b2c3d-…", "status": "verified", "verifiedAt": "2026-07-31T09:12:44.000Z" }DNS caches. A record published seconds ago may not be visible yet, and the answer is to wait and call verify again rather than to re-create the domain.
Catch-all
A catch-all points every address in the domain that matches nothing else at one mailbox. It is off by default, because a catch-all receives every typo and every dictionary attack aimed at the domain.
/v1/mailbox-domains/:id/catch-allSet or clear the catch-all mailbox.
Body
catchAllMailboxIduuid | nullrequired | A mailbox in this domain, or null to clear it. |
Mailboxes
/v1/mailboxesProvision a mailbox. The plaintext password is in the response and never again.
Body
mailboxDomainIduuidrequired | Must be a VERIFIED hosting domain. |
localPartstringrequired | The part before the @. Lower-cased; letters, digits and . _ + - only. |
passwordstringrequired | 12–256 characters. See the note below on why the bar is higher here. |
displayNamestringoptionaldefault "" | Up to 200 chars. |
quotaBytesintegeroptionaldefault 1073741824 | 1 GiB by default. 0 means unlimited. Maximum 1 TiB. |
curl -X POST https://api.mailmarco.com/v1/mailboxes \
-H "authorization: Bearer $MAILMARCO_ACCESS_TOKEN" \
-H "content-type: application/json" \
-d '{
"mailboxDomainId": "9a1b2c3d-4e5f-4061-8273-8495a6b7c8d9",
"localPart": "info",
"displayName": "Info Desk",
"password": "correct-horse-battery-staple"
}'{
"id": "1f2e3d4c-5b6a-4978-8695-a4b3c2d1e0f9",
"address": "[email protected]",
"displayName": "Info Desk",
"quotaBytes": 1073741824,
"status": "active",
"provisioned": true,
"password": "correct-horse-battery-staple"
}Mailbox passwords have a higher minimum than dashboard passwords (12 characters) because they are typed into third-party mail clients and used over IMAP and SMTP, where there is no MFA, no session concept and no rate-limit UI. A compromise hands over the whole mail history and an authenticated relay.
provisioned is not decoration
A mailbox exists in two places: a record here and an account in the mail server itself. If the second write fails, provisioned is false and syncError carries the reason — the address will not accept mail yet. Reconciliation retries it; a mailbox that stays unprovisioned is a fault to surface, not a state to hide.
Delete, restore, purge
Deleting is reversible for 30 days. Purging is not, and is refused until the recovery window has elapsed — there is no force flag, so no single call can go from a live mailbox to destroyed mail.
| Call | Effect |
|---|---|
DELETE /v1/mailboxes/:id | Logins stop. Mail is untouched. Sets purgeAfter 30 days out. |
POST /v1/mailboxes/:id/restore | Undoes the above, within the window. |
DELETE /v1/mailboxes/:id/purge | IRREVERSIBLE. Destroys the account and every message. 409 before the window elapses. |
Aliases
An alias is another address that delivers into an existing mailbox. Only the local part is accepted: the domain is taken from the target mailbox, so an alias can only ever be minted inside a domain you have already proven you own.
/v1/aliasesAdd an alias to a mailbox.
Body
mailboxIduuidrequired | The target mailbox. |
localPartstringrequired | Same grammar as a mailbox local part. The domain is not accepted. |
{ "id": "…", "mailboxId": "1f2e3d4c-…", "address": "[email protected]" }Forwarding
A forwarder sends arriving mail on to an external address. The one decision that matters is whether a copy stays behind.
| keepCopy | Behaviour |
|---|---|
true | Default. The message is forwarded AND stored in the mailbox. The mailbox keeps consuming quota. |
false | Forward only. The message is not stored here at all — if the destination rejects it, the mail is gone. |
/v1/forwardersForward a mailbox's mail to an external address.
Body
mailboxIduuidrequired | The source mailbox. |
destinationstringrequired | An external email address, up to 320 characters. |
keepCopybooleanoptionaldefault true | Whether the message also stays in the mailbox. |
{
"id": "…",
"mailboxId": "1f2e3d4c-…",
"destination": "[email protected]",
"keepCopy": true,
"enabled": true,
"status": "active"
}PATCH /v1/forwarders/:id toggles enabled or keepCopy; DELETE /v1/forwarders/:id removes the rule.
Connecting a client
Mailboxes are reached with standard protocols, so any mail, calendar or contacts client works. The dashboard shows these per mailbox with copy buttons; the values are below for reference. The username is always the full address.
| Protocol | Host | Port | Security |
|---|---|---|---|
| IMAP | mail.mailmarco.com | 993 | SSL/TLS |
| IMAP (STARTTLS) | mail.mailmarco.com | 143 | STARTTLS |
| SMTP submission | mail.mailmarco.com | 465 | SSL/TLS |
Calendar and contacts
Every mailbox gets a calendar and an address book when it is created. Most clients need only the server URL and will discover the rest; the direct collection URLs are there for clients that ask for a collection address.
Server URL https://mail.mailmarco.com/
Username [email protected]
CalDAV (direct) https://mail.mailmarco.com/dav/cal/info%40mail.example.com/default/
CardDAV (direct) https://mail.mailmarco.com/dav/card/info%40mail.example.com/default/The address is percent-encoded in the path — it contains an @, and un-encoded the URL's authority is ambiguous.
Endpoints
| Method | Path | Purpose |
|---|---|---|
| POST | /v1/mailbox-domains | Add a hosting domain |
| GET | /v1/mailbox-domains | List hosting domains |
| GET | /v1/mailbox-domains/:id | Retrieve one |
| POST | /v1/mailbox-domains/:id/verify | Re-check DNS |
| POST | /v1/mailbox-domains/:id/suspend | Stop accepting mail |
| PATCH | /v1/mailbox-domains/:id/catch-all | Set or clear catch-all |
| DELETE | /v1/mailbox-domains/:id | Remove a hosting domain |
| POST | /v1/mailboxes | Provision a mailbox |
| GET | /v1/mailboxes | List mailboxes |
| GET | /v1/mailboxes/:id | Retrieve one |
| PATCH | /v1/mailboxes/:id | Rename, re-quota, suspend, reset password |
| DELETE | /v1/mailboxes/:id | Soft-delete (30-day recovery) |
| POST | /v1/mailboxes/:id/restore | Undo a soft-delete |
| DELETE | /v1/mailboxes/:id/purge | Destroy the mailbox and its mail |
| POST | /v1/aliases | Add an alias |
| GET | /v1/aliases?mailboxId= | List aliases |
| DELETE | /v1/aliases/:id | Remove an alias |
| POST | /v1/forwarders | Add a forwarding rule |
| GET | /v1/forwarders?mailboxId= | List forwarding rules |
| PATCH | /v1/forwarders/:id | Toggle enabled / keepCopy |
| DELETE | /v1/forwarders/:id | Remove a forwarding rule |