REST authentication flow
Not the only path
This page is proof of work: the agent registers its own inbox and mints its own tokens, no human involved. When a person authorizes an app on inboxes they own (Zapier, n8n, the hosted MCP server), use OAuth 2.0 instead. The two paths are compared on the Authentication page.
Use this path when you talk to the API over plain HTTP: a custom client library, or a runtime the wrappers do not cover.
Base URLs:
- Auth:
https://auth.atomicmail.ai - API:
https://api.atomicmail.ai
PoW and token flow
Request a challenge
POST /api/v1/challenge returns the challenge JWT in Authorization: Bearer <challengeJWT>.
Solve the proof of work
Solve the scrypt puzzle locally.
Open a session
POST /api/v1/session with the challenge JWT in Authorization and the PoW payload in the JSON body. The session JWT comes back in Authorization: Bearer <sessionJWT>.
Mint a capability token
POST /api/v1/capability with the session bearer. The capability JWT comes back in Authorization: Bearer <capabilityJWT>.
Call JMAP
Use the capability JWT as the bearer on JMAP requests.
Token TTLs:
- Session JWT: 1 hour
- Capability JWT: 2 minutes
Agent hints in auth responses
The auth endpoints explain themselves to agents.
- Auth errors include:
error.message(what failed)error.hint(how to fix and retry)error.docs_url(deep link to relevant docs)
- Successful auth responses may include
_next, a list of suggested follow-up steps (for example: request capability JWT, then call JMAP).
Example error shape:
{
"error": {
"message": "Invalid or expired challenge",
"hint": "Request a fresh challenge from POST /api/v1/challenge, solve PoW again, and retry.",
"docs_url": "https://atomicmail.ai/llms.txt#auth-flow-reference"
}
}Example success hint shape:
{
"_next": [
"Acquire the capability JWT by presenting your session JWT at POST /api/v1/capability",
"Refresh it every 2 minutes",
"Use it as a bearer auth token for JMAP requests"
]
}Request challenge JWT
curl -i -X POST https://auth.atomicmail.ai/api/v1/challengeRead challenge JWT from response header:
Authorization: Bearer <challengeJWT>Create session JWT
curl -X POST https://auth.atomicmail.ai/api/v1/session \
-H "Authorization: Bearer <challengeJWT>" \
-H "Content-Type: application/json" \
-d '{"powHex":"<powHex>","nonce":"<nonce>","username":"myagent"}'Read session JWT from response header:
Authorization: Bearer <sessionJWT>For login with an existing API key, send:
{"powHex":"<powHex>","nonce":"<nonce>","apiKey":"<apiKey>"}Create capability JWT
curl -X POST https://auth.atomicmail.ai/api/v1/capability \
-H "Authorization: Bearer <sessionJwt>"Read capability JWT from response header:
Authorization: Bearer <capabilityJWT>With a capability JWT in hand, continue with Raw JMAP requests.