REST API
The whole surface over plain HTTPS, with the same API keys.
Everything the MCP server does is also available over plain HTTPS, for stacks without MCP support. The base is https://mcpmailer.com and every endpoint takes an Authorization: Bearer mmk_... header. Bodies and responses are JSON unless noted.
Messages
/v1/messagesSend. Same body as send_email.
/v1/messages?unread_only=true&thread_id=&include_archived=&limit=
/v1/messages/:idFull message, and marks it read.
/v1/messages/:id/reply-all{ body }
/v1/messages/:id/forward{ to, body?, mode? }
/v1/messages/:id/archive{ archived?, unread? }
/v1/messages/:id/attachments/:filenameOne attachment.
/v1/threadsConversations, newest first.
/v1/threads/:idEvery message in one conversation.
/v1/search?q= ranked full-text search.
Identity
/v1/identityHandle, filter mode, rules.
/v1/identity{ handle?, display_name?, description?, filter_mode? }
/v1/identity/rulesFilter rules.
/v1/identity/rules{ match, value, action }
/v1/identity/rules/:idRemoves a rule.
Contacts
/v1/contacts?q= search, ?lookup= reverse lookup. Accept: text/vcard exports all.
/v1/contactsOne contact, or { vcard } to bulk import.
/v1/contacts/duplicatesPairs that look like the same person.
/v1/contacts/duplicates{ survivor_id, loser_id } merges them.
/v1/contacts/:idFull contact. Accept: text/vcard returns a vCard.
/v1/contacts/:idMerge patch.
/v1/contacts/:id{ fact } remembers something about them.
/v1/contacts/:idDeletes the contact.
/v1/contacts/import{ csv, list_name? | list_id? } pasted CSV or address lines become contacts, optionally all on one list. Or send the text as text/csv with ?list_name=.
/v1/contacts/listsEvery list with its member count.
/v1/contacts/lists{ name, description? } creates a list.
/v1/contacts/lists/:idThe list and a page of members. ?limit= ?offset=, page until next_offset is null.
/v1/contacts/lists/:id{ name?, description? }
/v1/contacts/lists/:idDeletes the list, keeps the contacts.
/v1/contacts/lists/:id/members{ contact_ids } adds contacts to the list.
/v1/contacts/lists/:id/members{ contact_ids } removes them from the list.
Notes, knowledge, secrets, and signup
/v1/notes?q= to search.
/v1/notes{ title?, body }
/v1/notes/:idPATCH merge patches it, DELETE removes it.
/v1/knowledgeThe summary; ?q= returns ranked passages instead.
/v1/knowledge/pages/:idOne indexed page in full.
/v1/knowledge/sourcesEvery source with its status.
/v1/knowledge/sources{ kind: site | page, url } or { kind: text, body }. Sites and pages index in the background.
/v1/knowledge/sources/:idPOST fetches it again, DELETE removes it and its pages.
/v1/secretsMetadata for granted secrets. No values.
/v1/secrets/:idOpens a granted secret and returns its value. No key to pass.
/v1/mailboxesEvery inbox here, with the plan allowance.
/v1/mailboxes{ handle, domain_id? } creates one.
/v1/domainsDomains, with records a pending one still needs.
/v1/domains{ domain } returns the DNS records to publish.
/v1/domains/{id}/verifyChecks the records now and reports whether the domain can send yet.
/v1/domains?id=Removes a custom domain.
/v1/webhooksEndpoints. Secrets are not listed.
/v1/webhooks{ url, events, mailbox_id?, headers?, template? } returns the secret once.
/v1/webhooks?id=Changes an endpoint in place. rotate_secret returns a new secret once.
/v1/webhooks?id=Removes an endpoint.
/v1/webhooks/deliveriesWhat each attempt got back. webhook_id, limit, and before narrow it.
/v1/webhooks/deliveries{ webhook_id } sends a test; { delivery_id } replays a stored one.
/v1/signup{ handle, email? } provisions a workspace and a key.