Authentication and sessions
Bearer tokens, session lifetime, and working across several organizations.
A session belongs to one account and one organization. An account that belongs to several organizations holds several live sessions at once — switching does not revoke the one you were using.
Endpoints
- POST /api/auth/email-code/start — email a six-digit code and a sign-in link to { email }. Always 202, account or not.
- POST /api/auth/email-code/verify — exchange { email, code } for a token; with two-step sign-in on, for a challenge to answer at POST /api/auth/mfa/verify; for an address with no account, for a single-use signupTicket.
- POST /api/auth/register — create an account from { signupTicket, name, username? }. There is no password; the address is the one the ticket proved, so it is confirmed from the start. A Kemble Circle account starts in Home.
- POST /api/auth/deletion-pending/continue — while an account is waiting to be deleted, signing in answers 409 with the code auth.deletion_pending, the date and a single-use proof instead of a token. Send { proof } here within 10 minutes, from the same browser, to keep the account: the deletion is cancelled and the token is answered. Not sending it changes nothing.
- GET /api/auth/me — the account, its organizations, and the active one.
- POST /api/auth/switch-organization — get a token for another organization you belong to.
- GET /api/auth/sessions — every live session, with device and last-seen.
- DELETE /api/auth/sessions/:session — end one; DELETE /api/auth/sessions ends the rest.
- Retired: POST /api/auth/login, /api/auth/password/forgot, /reset and /change answer 410 with the code auth.password_retired. Kemble doesn’t use passwords; scripts should use an app’s token.
A 401 means the session is gone rather than that the request was malformed. Clear the stored token when you see one; retrying with a dead credential is how a client ends up in a loop.