{"name":"login","version":"v1","what":"Email in, bearer token out. No password, no magic-link email, no OAuth, no refresh tokens.","auth":{"header":"Authorization: Bearer <token>","note":"Required on GET /v1/me and POST /v1/logout. Not used on POST /v1/login."},"errors":{"shape":{"error":"string","code":"string"},"codes":["bad_request","unauthorized","not_found"]},"kv":{"user:{email}":"{ id, email, created }","session:{token}":"{ id, email, created, expires } TTL ~7 days"},"routes":[{"method":"OPTIONS","path":"*","use":"CORS preflight. Returns 204. Allow-Origin *, methods GET, POST, OPTIONS, headers Content-Type, Accept, Authorization.","authorization":false,"body":null,"response":"204 empty"},{"method":"GET","path":"/","use":"This document. Self-describing JSON meta.","authorization":false,"body":null,"response":"200 this object"},{"method":"GET","path":"/v1","use":"This document. Self-describing JSON meta.","authorization":false,"body":null,"response":"200 this object"},{"method":"POST","path":"/v1/login","use":"Create or reuse a user by email, mint a session token. Extra JSON keys ignored.","authorization":false,"body":{"email":"string"},"response":"201 { token, id, email, expires }. 400 { error, code: bad_request } if email missing, empty after trim, not a string, over 200 chars, not JSON, or not an email (must contain @ and a dot in the domain)."},{"method":"GET","path":"/v1/me","use":"Return the session owner.","authorization":true,"body":null,"response":"200 { id, email, created, expires }. 401 { error, code: unauthorized } if missing, invalid, or expired token."},{"method":"POST","path":"/v1/logout","use":"Delete the session. Token cannot be reused.","authorization":true,"body":null,"response":"200 { ok: true }. 401 { error, code: unauthorized } if missing or invalid token."}],"example":{"request":{"method":"POST","path":"/v1/login","headers":{"Content-Type":"application/json"},"body":{"email":"simon@each.app"}},"response":{"status":201,"body":{"token":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","id":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","email":"simon@each.app","expires":"2026-09-04T00:00:00.000Z"}}}}