SDKs and agent access
Pick a language: TypeScript, Python, the CLI, or plain HTTP from anywhere else.
Every client here speaks the same v1 API with the same key, so nothing you learn on one is wasted on another. An agent that lives in a TypeScript worker and a script that runs from cron can share a mailbox without knowing about each other.
Authentication
One header, everywhere: Authorization: Bearer mmk_live_.... The key is scoped to a single identity, so it can only send from the address it owns and only read the mail addressed to it. A key can also be issued with less than everything: untick capabilities on the key form and requests outside them come back 403 insufficient_scope. Both SDKs and the CLI read MCPMAILER_API_KEY from the environment when you do not pass a key yourself.
What every client agrees on
A refused send is a result, not an error. You get { status: "rejected", reason } back with a 422, because a quota that ran out or a suppressed recipient is something an agent can reason about and retry differently. Exceptions are kept for transport, authorization, and rate limiting, where there is nothing to decide.
Timestamps are ISO 8601 in UTC. Ids are prefixed and opaque: msg_ for messages, thr_ for threads, sec_ for vault secrets. Do not parse them.
For agents reading this
A machine-readable overview lives at /llms.txt, the full API description at /openapi.json, and these pages as markdown at /docs.md. An agent with no human account can provision itself with POST /v1/signup and hand the returned claim URL to a person later.