Get your API key
Getting started

Authentication

Every request authenticates with a bearer token in the Authorization header. Your account key — one mk_live_… token — does everything: sending, domains, webhooks, and inbound. When code or an agent should reach less, mint a domain-scoped key confined to a single domain.

Account key — full scope

Your account has a single mk_live_… account key from the moment you sign up. It's scoped to all your domains and authenticates every endpoint: POST /v1/send and the whole management API (/api/*) — create & register domains, verify DNS, set webhooks, create routes, and read inbound. The same key works for your own code and for an AI agent, so there's nothing extra to provision.

Domain-scoped keys — one domain each

A domain-scoped key is also an mk_live_… token, but it can only touch one domain: send from it, manage it, and read its mail and routes — nothing else on the account, and it can't mint keys or change account-wide settings. Create one in the dashboard under API keys (pick the domain, give it a label), and revoke it anytime without disturbing the account key or other scoped keys. Use one per agent or per tenant in production — choosing an agent's reach walks through the full ladder, down to a single mailbox.

CredentialLooks likeUse it for
Account key mk_live_… Everything — sending and the full management API, from your server or your agent.
Domain-scoped key mk_live_… One domain only — send, manage, and read mail there. One per agent or tenant; revocable on its own.
Session token JWT (eyJ…) The dashboard's own browser session (email/password or Google sign-in). You rarely handle this directly.

Using your API key

Grab your key from the dashboard (it's on your first screen and under Settings → API key) and pass it to the client — it goes out as Authorization: Bearer mk_live_… on every request:

configure the client
import { MailKite } from "mailkite";
const mk = new MailKite(process.env.MAILKITE_API_KEY);
Install Docs →

Treat it like a password — store it in a secret manager or environment variable, never in client-side code or a git repo, and use it server-side only. Need a fresh one? Rotate the account key in the dashboard (rotating invalidates the old key immediately), or revoke any domain-scoped key on its own.

Session tokens (dashboard)

The dashboard signs in with email + password (or Sign in with Google) to get a short-lived JWT session token. You can use it against the management API too, but for scripts and agents prefer the mk_live_… key above. To get a token:

bash
curl https://api.mailkite.dev/api/auth/login \
-H "Content-Type: application/json" \
-d '{ "email": "you@example.com", "password": "••••••••" }'
response
{
"token": "eyJhbGci…",
"user": { "id": "usr_…", "email": "you@example.com", "isAdmin": false }
}

Send the token on subsequent management requests:

use the token
const mk = new MailKite("eyJhbGci…");
const domains = await mk.listDomains();
Install Docs →

To create an account programmatically, POST /api/auth/signup with { email, password } — it returns a token too.

Errors

A missing or invalid credential returns 401 Unauthorized. A valid credential that lacks access to a resource returns 403 Forbidden, and an unknown or non-owned resource returns 404 Not Found. See the API reference for the full list.

All requests must use HTTPS. Requests over plain HTTP are rejected (except http://localhost for local webhook testing).