Server-side login & register
Two ways to authenticate from a server — pick by whose account you act as. In both, register is unified with login: a new user is created and signed in as part of the same flow.
A · Your own account
One MailKite account behind your app. Email + password → token. No redirect.
B · Your users' accounts
Multi-tenant. OAuth 2.1 + PKCE — each user signs into their own account.
A · Your own account (email + password)
When your app sends from a single MailKite account, just register or log in
with email and password and keep the returned token — it's a bearer credential that works
exactly like an mk_live_… API key. Signup
also provisions your API key and sends a welcome email.
// Register a new account (or log in if it already exists), then use the token.
const base = "https://api.mailkite.dev";
let res = await fetch(`${base}/api/auth/signup`, {
method: "POST", headers: { "content-type": "application/json" },
body: JSON.stringify({ email: "you@example.com", password: process.env.MK_PASSWORD }),
});
if (res.status === 409) { // already registered → log in
res = await fetch(`${base}/api/auth/login`, {
method: "POST", headers: { "content-type": "application/json" },
body: JSON.stringify({ email: "you@example.com", password: process.env.MK_PASSWORD }),
});
}
const { token } = await res.json();
const mk = new MailKite(token); // the session token works like an API keyimport os, requests
from mailkite import MailKite
base = "https://api.mailkite.dev"
r = requests.post(f"{base}/api/auth/signup", json={"email": "you@example.com", "password": os.environ["MK_PASSWORD"]})
if r.status_code == 409: # already registered → log in
r = requests.post(f"{base}/api/auth/login", json={"email": "you@example.com", "password": os.environ["MK_PASSWORD"]})
mk = MailKite(r.json()["token"])# Register (signup) — returns { token, user }. Use /api/auth/login if the account exists.
curl https://api.mailkite.dev/api/auth/signup \
-H "Content-Type: application/json" \
-d '{ "email": "you@example.com", "password": "••••••••" }' POST /api/auth/signup returns 201 { token, user } (or
409 if the email exists). POST /api/auth/login returns
{ token, user }. Google sign-in is also available at
POST /api/auth/google.
B · Your users' accounts (OAuth 2.1 + PKCE)
For multi-tenant apps, send each user to MailKite's hosted page to sign in or create an account, then exchange the returned code for a token that is that user. This is the same flow the client SDKs use, run from your server. No password ever touches your app.
1 · Register a client (once)
# Once per app — dynamically register a public client, cache the client_id.
curl https://api.mailkite.dev/oauth/register \
-H "Content-Type: application/json" \
-d '{
"client_name": "My App",
"redirect_uris": ["https://app.example.com/callback"],
"grant_types": ["authorization_code", "refresh_token"],
"response_types": ["code"]
}'
# → { "client_id": "mkc_…" } 2 · Send the user to log in or register
Create a PKCE pair, store the verifier against a random state, and redirect:
// Build the URL you redirect the user to. They LOG IN OR REGISTER on MailKite's
// hosted page, then come back to your redirect_uri with a one-time ?code=.
const url = new URL("https://api.mailkite.dev/oauth/authorize");
url.search = new URLSearchParams({
response_type: "code",
client_id, // from /oauth/register
redirect_uri: "https://app.example.com/callback",
scope: "mcp", // full account — the only scope today
state, // random; store with the PKCE verifier
code_challenge, // base64url(sha256(verifier))
code_challenge_method: "S256",
}).toString();
res.redirect(url.toString()); 3 · Handle the callback & exchange the code
// On your /callback route, exchange the code for a token that IS the user.
const tok = await fetch("https://api.mailkite.dev/oauth/token", {
method: "POST", headers: { "content-type": "application/x-www-form-urlencoded" },
body: new URLSearchParams({
grant_type: "authorization_code",
code,
redirect_uri: "https://app.example.com/callback",
client_id,
code_verifier, // the PKCE verifier you stored for this state
}).toString(),
});
const { access_token, refresh_token } = await tok.json();
const mk = new MailKite(access_token); // now act as that user; store refresh_token to renew Full runnable examples
Every server SDK ships an end-to-end server-login example (both flows) in its
repo's examples/ folder — e.g.
Node and
Python.
Browser & mobile apps should use the client libraries, which
handle PKCE, token storage, and refresh for you.