MailKite for Elixir
Email for every product you ship — receive email as a webhook, send over a verified domain, give an AI agent its own inbox.
The official MailKite library for Elixir.
Docs · Library guide · mailkite.dev · AI agents
Read-only mirror. This repo is a generated, release-time mirror of the MailKite monorepo (the private source of truth) — development doesn't happen here. Install from Hex and open issues against the MailKite docs.
Install
Add :mailkite to deps in mix.exs:
def deps do
[{:mailkite, "~> 0.13"}]
end
Then mix deps.get. The library has zero third-party runtime dependencies — HTTP is stdlib :httpc/:inets, crypto is stdlib :crypto/:public_key, and JSON uses the built-in JSON module on Elixir 1.18+ (falling back to Jason on older Elixir).
Quickstart
mk = MailKite.new(System.get_env("MAILKITE_API_KEY"))
{:ok, res} =
MailKite.Methods.send(mk, %{
"from" => "hello@myapp.ai",
"to" => "ada@example.com",
"subject" => "Your invoice #1042",
"html" => "<p>Thanks! Receipt attached.</p>"
})
Every method returns {:ok, value} on success (the parsed JSON response) or {:error, %MailKite.Error{}} on any non-2xx response — pattern-match to handle both:
case MailKite.Methods.send(mk, message) do
{:ok, res} -> IO.puts("queued #{res["id"]}")
{:error, %MailKite.Error{status: status, message: msg}} -> IO.puts("failed #{status}: #{msg}")
end
Authentication — API key or OAuth
The credential is always a Bearer token, so an OAuth access token works anywhere an API key does. Server-to-server code → API key; anything that renders on a public URL → OAuth (each user acts as themselves, not through a shared key).
# Server-to-server: a static API key (mk_live_…).
mk = MailKite.new(System.get_env("MAILKITE_API_KEY"))
# OAuth: a static access token…
mk = MailKite.Client.new(access_token: my_oauth_token)
# …or a get_token callback called before each request, so short-lived
# OAuth access tokens stay fresh:
mk = MailKite.Client.new(get_token: fn -> current_session_access_token() end)
Point at a custom base URL with MailKite.new(api_key, "https://api.mailkite.dev") or MailKite.Client.new(access_token: token, base_url: url).
Get an OAuth token from MailKite's authorization server (mcp.mailkite.dev, OAuth 2.1 + PKCE). For browser/native apps use the client-side libraries, which run the whole flow.
Verify inbound webhooks
MailKite.Webhook is entirely local — no network call. Verify the x-mailkite-signature header over the raw request body before trusting an inbound event, then return one of the reply bodies:
if MailKite.Webhook.verify_webhook(signature, raw_body, webhook_secret) do
# process the event…
MailKite.Webhook.reply_ok() # {"status":"ok"}
else
# reject
end
# Control-mode replies a handler can return:
MailKite.Webhook.reply_spam() # {"status":"spam"}
MailKite.Webhook.reply_drop() # {"status":"drop"}
MailKite.Webhook.reply_block_sender() # {"status":"ok","actions":[{"type":"block-sender"}]}
verify_webhook/4 rejects events older than a 5-minute replay window by default; pass a fourth argument (ms, or 0 to disable) to change it.
At-rest encryption
MailKite.Crypto encrypts to an RSA public key and decrypts with the private key. The envelope is byte-compatible with every other MailKite SDK and MailKite's own WebCrypto, so a value encrypted in one language decrypts in another.
envelope = MailKite.Crypto.encrypt("secret note", public_key_pem)
{:ok, plaintext} = MailKite.Crypto.decrypt(envelope, private_key_pem)
Attachments
Upload a file once and reference the returned URL on sends, instead of base64-inlining it every time. Provide the file as a url (re-hosted by MailKite), raw bytes, a local path, or base64 content:
{:ok, up} =
MailKite.Client.upload_attachment(mk, %{
"path" => "/tmp/receipt.pdf",
"filename" => "receipt.pdf"
})
MailKite.Methods.send(mk, %{
"from" => "billing@myapp.ai",
"to" => "ada@example.com",
"subject" => "Your receipt",
"text" => "Attached.",
"attachments" => [%{"filename" => up["filename"], "url" => up["url"]}]
})
API methods
Every endpoint is a function in MailKite.Methods, taking the client first. Names are snake_case (e.g. list_domains/1, get_template/2, send_broadcast/3). The full surface: send, upload_attachment, list_templates, list_base_templates, get_template, create_template, list_domains, create_domain, get_domain, delete_domain, verify_domain, set_webhook, delete_webhook, test_webhook, check_domain_availability, register_domain, list_routes, create_route, delete_route, agent, route, list_messages, get_message, retry_delivery, list_lists, create_list, get_list, update_list, delete_list, list_list_contacts, add_list_contacts, remove_list_contact, list_broadcasts, create_broadcast, get_broadcast, update_broadcast, delete_broadcast, send_broadcast, semantic_search, plus the local MailKite.Webhook and MailKite.Crypto helpers.
List endpoints take a keyword of pagination options:
{:ok, msgs} = MailKite.Methods.list_messages(mk, before: 1_750_000_000_000, limit: 50, search: "invoice")
Use it from an AI agent — MCP + Agent connectors
MailKite speaks the Model Context Protocol: every API method is a tool your AI assistant (Claude, Cursor, …) can call. Full guide: https://mailkite.dev/docs/ai-agents.
Hosted (recommended) — one-click OAuth, no key to copy:
claude mcp add --transport http mailkite https://mcp.mailkite.dev/mcp
Local (static key, offline / CI):
{ "mcpServers": { "mailkite": { "command": "npx", "args": ["-y", "@mailkite/mcp"], "env": { "MAILKITE_API_KEY": "mk_live_…" } } } }
All MailKite libraries
Same contract, every language — pick the one for your stack (full list: https://mailkite.dev/docs/libraries):
| Library | Repo | Distribution |
|---|---|---|
| MailKite for Node.js | mailkite-node | npm |
| MailKite for Python | mailkite-python | PyPI |
| MailKite for Ruby | mailkite-ruby | RubyGems |
| MailKite for Elixir (this repo) | mailkite-elixir | Hex |
| MailKite for Java | mailkite-java | Maven Central |
| MailKite for PHP | mailkite-php | Packagist |
| MailKite for Go | mailkite-go | Go modules |
| @mailkite/cli | mailkite-cli | npm |
| @mailkite/mcp | mailkite-mcp | npm |
Docs & links
- 📚 Documentation:https://mailkite.dev/docs
- 📦 This library's guide:https://mailkite.dev/docs/libraries
- 🤖 AI agents (MCP + inbox agents):https://mailkite.dev/docs/ai-agents
- 🌐 Website:https://mailkite.dev
Generated from the shared MailKite API contract. © MailKite. MIT licensed.