Agents and humans, one platform. A transactional API for your stack, a shared inbox for your team, and their own inboxes for your agents. Send, receive, and auto-reply across unlimited domains, free.
Transactional API ·Team inbox ·Agent inboxes ·Deliverability built in
Loading…
Received 17:42:10 · replied 17:42:11 — no human in the loop.
prompt Check support@ and reply to Ada confirming the refund cleared.
agent Replied to Ada — refund for #1042 confirmed as cleared. ✓
Send and receive from your app in a few lines — Next.js, Nuxt, Node, Python, PHP, Go, Ruby, and more. One shape everywhere, plus CLI, REST, SMTP, and IMAP.
import { MailKite } from "mailkite";
const mk = new MailKite(process.env.MAILKITE_API_KEY);
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
}); import { MailKite } from "mailkite";
const mk = new MailKite(process.env.MAILKITE_API_KEY);
export async function POST() {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return Response.json({ id, status });
} import { MailKite } from "mailkite";
const mk = new MailKite(process.env.MAILKITE_API_KEY);
export async function action() {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return Response.json({ id, status });
} import { MailKite } from "mailkite";
const mk = new MailKite(process.env.MAILKITE_API_KEY);
export default defineEventHandler(async () => {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return { id, status };
}); import express from "express";
import { MailKite } from "mailkite";
const app = express();
const mk = new MailKite(process.env.MAILKITE_API_KEY);
app.post("/send", async (_req, res) => {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
res.json({ id, status });
}); import { Hono } from "hono";
import { MailKite } from "mailkite";
const app = new Hono();
app.post("/send", async (c) => {
const mk = new MailKite(c.env.MAILKITE_API_KEY);
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return c.json({ id, status });
});
export default app; import type { APIRoute } from "astro";
import { MailKite } from "mailkite";
const mk = new MailKite(import.meta.env.MAILKITE_API_KEY);
export const POST: APIRoute = async () => {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return Response.json({ id, status });
}; import { MailKite } from "mailkite";
const mk = new MailKite(Bun.env.MAILKITE_API_KEY);
Bun.serve({
async fetch() {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return Response.json({ id, status });
},
}); // wrangler.jsonc → "compatibility_flags": ["nodejs_compat"]
import { MailKite } from "mailkite";
export default {
async fetch(_req: Request, env: Env) {
const mk = new MailKite(env.MAILKITE_API_KEY);
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return Response.json({ id, status });
},
}; import { MailKite } from "mailkite";
const mk = new MailKite(process.env.MAILKITE_API_KEY);
// Deploys as a Vercel Function — same code on Netlify or any Node runtime.
export async function POST() {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return Response.json({ id, status });
} import { MailKite } from "mailkite";
const mk = new MailKite(process.env.MAILKITE_API_KEY);
export const handler = async () => {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return { statusCode: 200, body: JSON.stringify({ id, status }) };
}; import { MailKite } from "npm:mailkite";
const mk = new MailKite(Deno.env.get("MAILKITE_API_KEY"));
Deno.serve(async () => {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return Response.json({ id, status });
}); import { MailKite } from "npm:mailkite";
const mk = new MailKite(Deno.env.get("MAILKITE_API_KEY"));
Deno.serve(async () => {
const { id, status } = await mk.send({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
});
return Response.json({ id, status });
}); import os
from mailkite import MailKite
mk = MailKite(os.environ["MAILKITE_API_KEY"])
res = mk.send({
"from": "hello@myapp.ai",
"to": "ada@example.com",
"subject": "Your invoice #1042",
"html": "<p>Thanks! Receipt attached.</p>",
}) import os
from django.http import JsonResponse
from mailkite import MailKite
mk = MailKite(os.environ["MAILKITE_API_KEY"])
def send(request):
res = mk.send({
"from": "hello@myapp.ai",
"to": "ada@example.com",
"subject": "Your invoice #1042",
"html": "<p>Thanks! Receipt attached.</p>",
})
return JsonResponse(res) import os
from flask import Flask, jsonify
from mailkite import MailKite
app = Flask(__name__)
mk = MailKite(os.environ["MAILKITE_API_KEY"])
@app.post("/send")
def send():
res = mk.send({
"from": "hello@myapp.ai",
"to": "ada@example.com",
"subject": "Your invoice #1042",
"html": "<p>Thanks! Receipt attached.</p>",
})
return jsonify(res) import os
from fastapi import FastAPI
from mailkite import MailKite
app = FastAPI()
mk = MailKite(os.environ["MAILKITE_API_KEY"])
@app.post("/send")
def send():
return mk.send({
"from": "hello@myapp.ai",
"to": "ada@example.com",
"subject": "Your invoice #1042",
"html": "<p>Thanks! Receipt attached.</p>",
}) <?php
$mk = new \MailKite\Client(getenv('MAILKITE_API_KEY'));
$res = $mk->send([
'from' => 'hello@myapp.ai',
'to' => 'ada@example.com',
'subject' => 'Your invoice #1042',
'html' => '<p>Thanks! Receipt attached.</p>',
]); <?php
use MailKite\Client;
Route::post('/send', function () {
$mk = new Client(env('MAILKITE_API_KEY'));
$res = $mk->send([
'from' => 'hello@myapp.ai',
'to' => 'ada@example.com',
'subject' => 'Your invoice #1042',
'html' => '<p>Thanks! Receipt attached.</p>',
]);
return response()->json($res);
}); <?php
use MailKite\Client;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\Routing\Attribute\Route;
class SendController
{
#[Route('/send', methods: ['POST'])]
public function send(): JsonResponse
{
$mk = new Client($_ENV['MAILKITE_API_KEY']);
return new JsonResponse($mk->send([
'from' => 'hello@myapp.ai',
'to' => 'ada@example.com',
'subject' => 'Your invoice #1042',
'html' => '<p>Thanks! Receipt attached.</p>',
]));
}
} require "mailkite"
mk = Mailkite::Client.new(ENV["MAILKITE_API_KEY"])
res = mk.send(
"from" => "hello@myapp.ai",
"to" => "ada@example.com",
"subject" => "Your invoice #1042",
"html" => "<p>Thanks! Receipt attached.</p>"
) class SendsController < ApplicationController
def create
mk = Mailkite::Client.new(ENV["MAILKITE_API_KEY"])
res = mk.send(
"from" => "hello@myapp.ai",
"to" => "ada@example.com",
"subject" => "Your invoice #1042",
"html" => "<p>Thanks! Receipt attached.</p>"
)
render json: res
end
end require "sinatra"
require "mailkite"
mk = Mailkite::Client.new(ENV["MAILKITE_API_KEY"])
post "/send" do
res = mk.send(
"from" => "hello@myapp.ai",
"to" => "ada@example.com",
"subject" => "Your invoice #1042",
"html" => "<p>Thanks! Receipt attached.</p>"
)
content_type :json
res.to_json
end mk := mailkite.New(os.Getenv("MAILKITE_API_KEY"))
res, err := mk.Send(mailkite.Message{
From: "hello@myapp.ai",
To: "ada@example.com",
Subject: "Your invoice #1042",
HTML: "<p>Thanks! Receipt attached.</p>",
}) MailKite mk = new MailKite(System.getenv("MAILKITE_API_KEY"));
Object res = mk.send(Map.of(
"from", "hello@myapp.ai",
"to", "ada@example.com",
"subject", "Your invoice #1042",
"html", "<p>Thanks! Receipt attached.</p>"
)); @RestController
public class SendController {
private final MailKite mk = new MailKite(System.getenv("MAILKITE_API_KEY"));
@PostMapping("/send")
public Object send() {
return mk.send(Map.of(
"from", "hello@myapp.ai",
"to", "ada@example.com",
"subject", "Your invoice #1042",
"html", "<p>Thanks! Receipt attached.</p>"
));
}
} npm i -g @mailkite/cli && mailkite login
mailkite send --from hello@myapp.ai --to ada@example.com \
--subject "Your invoice #1042" --html "<p>Thanks! Receipt attached.</p>"
mailkite messages tail # watch inbound arrive curl https://api.mailkite.dev/v1/send \
-H "Authorization: Bearer $MAILKITE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"from": "hello@myapp.ai",
"to": "ada@example.com",
"subject": "Your invoice #1042",
"html": "<p>Thanks! Receipt attached.</p>"
}' wget -qO- https://api.mailkite.dev/v1/send \
--header "Authorization: Bearer $MAILKITE_API_KEY" \
--header "Content-Type: application/json" \
--post-data '{
"from": "hello@myapp.ai",
"to": "ada@example.com",
"subject": "Your invoice #1042",
"html": "<p>Thanks! Receipt attached.</p>"
}' // No SDK — one POST with the built-in fetch.
const res = await fetch("https://api.mailkite.dev/v1/send", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.MAILKITE_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
from: "hello@myapp.ai",
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
}),
});
const { id, status } = await res.json(); # No SDK — one POST with requests.
import os, requests
res = requests.post(
"https://api.mailkite.dev/v1/send",
headers={"Authorization": f"Bearer {os.environ['MAILKITE_API_KEY']}"},
json={
"from": "hello@myapp.ai",
"to": "ada@example.com",
"subject": "Your invoice #1042",
"html": "<p>Thanks! Receipt attached.</p>",
},
)
print(res.json()) # { "id": "msg_…", "status": "queued" } # Point WordPress, a CRM, or any app that speaks SMTP at the relay.
SMTP_HOST=smtp.mailkite.dev
SMTP_PORT=587 # STARTTLS · 465 for implicit TLS
SMTP_USER=mailkite # any username works
SMTP_PASS=mk_live_… # your MailKite API key — not a separate SMTP password
SMTP_FROM=you@your-verified-domain.dev import nodemailer from "nodemailer";
const tx = nodemailer.createTransport({
host: "smtp.mailkite.dev",
port: 587, // STARTTLS · use 465 for implicit TLS
auth: {
user: "mailkite", // any username works
pass: process.env.MAILKITE_API_KEY, // your mk_live_… key
},
});
await tx.sendMail({
from: "hello@myapp.ai", // an address on a verified domain
to: "ada@example.com",
subject: "Your invoice #1042",
html: "<p>Thanks! Receipt attached.</p>",
}); import os
EMAIL_HOST = "smtp.mailkite.dev"
EMAIL_PORT = 587 # STARTTLS · 465 for implicit TLS
EMAIL_USE_TLS = True
EMAIL_HOST_USER = "mailkite" # any username works
EMAIL_HOST_PASSWORD = os.environ["MAILKITE_API_KEY"] # your mk_live_… key
DEFAULT_FROM_EMAIL = "hello@myapp.ai" # an address on a verified domain
# Anywhere in your app:
# from django.core.mail import send_mail
# send_mail("Your invoice #1042", "Thanks! Receipt attached.",
# "hello@myapp.ai", ["ada@example.com"]) MAIL_MAILER=smtp
MAIL_HOST=smtp.mailkite.dev
MAIL_PORT=587 # STARTTLS · 465 for implicit TLS
MAIL_USERNAME=mailkite # any username works
MAIL_PASSWORD=mk_live_… # your MailKite API key
MAIL_ENCRYPTION=tls
MAIL_FROM_ADDRESS=hello@myapp.ai # an address on a verified domain
# Then Mail::to('ada@example.com')->send(new InvoiceMail) just works. config.action_mailer.delivery_method = :smtp
config.action_mailer.smtp_settings = {
address: "smtp.mailkite.dev",
port: 587, # STARTTLS · 465 for implicit TLS
user_name: "mailkite", # any username works
password: ENV["MAILKITE_API_KEY"], # your mk_live_… key
enable_starttls_auto: true,
}
# Action Mailer now sends from any address on a verified domain. # Read your MailKite inbox from any IMAP client or library — over IMAPS,
# with a scoped app-password (Settings → IMAP), never your API key.
import imaplib
M = imaplib.IMAP4_SSL("imap.mailkite.dev", 993)
M.login("agent@yourdomain.com", "mk_imap_…") # your IMAP app-password
M.select("INBOX")
typ, data = M.search(None, "UNSEEN") /plugin marketplace add mailkite/claude-code
/plugin install mailkite@mailkite claude mcp add --transport http mailkite https://mcp.mailkite.dev/mcp claude mcp add mailkite \
-e MAILKITE_API_KEY=mk_live_3a9f… \
-- npx -y @mailkite/mcp claude mcp add --transport http mailkite https://mcp.mailkite.dev/mcp \
--header "Authorization: Bearer mk_live_3a9f…" npx skills add mailkite/agent-skills Install the MailKite agent skill. Download
https://github.com/mailkite/claude-code/releases/latest/download/mailkite.zip
and unzip it into ~/.claude/skills/ (user-wide) or .claude/skills/ (this project), then load it. {
"mcpServers": {
"mailkite": {
"type": "http",
"url": "https://mcp.mailkite.dev/mcp"
}
}
} {
"mcpServers": {
"mailkite": {
"command": "npx",
"args": ["-y", "@mailkite/mcp"],
"env": { "MAILKITE_API_KEY": "mk_live_3a9f…" }
}
}
} {
"mcpServers": {
"mailkite": {
"type": "http",
"url": "https://mcp.mailkite.dev/mcp"
}
}
} {
"mcpServers": {
"mailkite": {
"command": "npx",
"args": ["-y", "@mailkite/mcp"],
"env": { "MAILKITE_API_KEY": "mk_live_3a9f…" }
}
}
} {
"servers": {
"mailkite": {
"type": "stdio",
"command": "npx",
"args": ["-y", "@mailkite/mcp"],
"env": { "MAILKITE_API_KEY": "mk_live_3a9f…" }
}
}
} {
"mcpServers": {
"mailkite": {
"serverUrl": "https://mcp.mailkite.dev/mcp"
}
}
} {
"mcpServers": {
"mailkite": {
"command": "npx",
"args": ["-y", "@mailkite/mcp"],
"env": { "MAILKITE_API_KEY": "mk_live_3a9f…" }
}
}
} {
"mcpServers": {
"mailkite": {
"httpUrl": "https://mcp.mailkite.dev/mcp"
}
}
} {
"mcpServers": {
"mailkite": {
"command": "npx",
"args": ["-y", "@mailkite/mcp"],
"env": { "MAILKITE_API_KEY": "mk_live_3a9f…" }
}
}
} [mcp_servers.mailkite]
command = "npx"
args = ["-y", "@mailkite/mcp"]
env = { MAILKITE_API_KEY = "mk_live_3a9f…" } Connect to the MailKite MCP server (Streamable HTTP) at
https://mcp.mailkite.dev/mcp and authenticate in the browser when prompted.
Then use the mailkite_* tools to send, read inbound, and reply to email. {
"mcpServers": {
"mailkite": {
"type": "http",
"url": "https://mcp.mailkite.dev/mcp"
}
}
} {
"mcpServers": {
"mailkite": {
"command": "npx",
"args": ["-y", "@mailkite/mcp"],
"env": { "MAILKITE_API_KEY": "mk_live_3a9f…" }
}
}
} Marketers, support, and developers work the same inbox @yourdomain — every address in one place, tagged and triaged, reply as any of them. No per-seat tax on support@ or billing@.
Loading…
Give any agent a real catch-all inbox — it receives, reads, and replies over MCP, an AI skill, or plain REST. Turn on auto-reply and it triages, answers, filters spam, tags, and escalates on its own.
Every message goes out authenticated — SPF, DKIM, and DMARC configured for you — and routed across tier-1 networks to the highest-deliverability tier your sending earns. You ship features; we keep you out of the spam folder.
Auto-routed across Cloudflare · Amazon SES + more — AI-tuned per domain, promoted to the highest tier your sending earns.
Authorizes MailKite's servers to send for your domain. Receivers check the sending host against your published record — we keep it aligned.
Every message is cryptographically signed with a key on your domain, so receivers can prove it wasn't altered in transit. We publish and rotate the keys.
Ties SPF and DKIM to the From: address recipients actually see, and tells inboxes to trust aligned mail. Configured and monitored for you.
New domains start on shared IP pools we've already warmed, with an established reputation — so your very first send lands. No weeks-long warm-up, no reputation to babysit.
Your mail rides Cloudflare, Amazon SES, Postmark, and other tier-1 networks. MailKite routes every message down the path most likely to land it — and reroutes if one degrades, so delivery never rides on a single provider.
MailKite learns how each domain sends and promotes it to the highest-deliverability tier its sending earns — AI-tuned as you go. Inbox placement gets better with nothing to configure.
Switched from SendGrid, inbox placement went from ~92% to ~99% in two weeks.
Mark — AdRender.app
One domain setup covers every email job — for code, for people, and for agents.
Add the MX, SPF, and DKIM records we generate. We verify them and your whole domain goes live — send and receive, both directions.
Send a webhook, open the shared inbox, or hand an address to an agent — pick per address. Grab an API key for your code.
Transactional mail, your team's inbox, and your agents' inboxes — one platform, one bill, one domain setup.
Developers, humans, and agents — send, receive, and auto-reply on one domain. Unlimited domains, free to start.
Compliant by design