Changelog
2026-08-07
Documentation rewrite — full audit against current code
index.md is now a ground-up rewrite. The previous version (last touched 2026-06-29) described a service that no longer exists: public self-registration, no Zitadel, an orgs[] array in the JWT, no sessions, no invites, no licensing. Six weeks of undocumented work had moved AuthAPI to a fundamentally different architecture — this pass reconciled the docs against the actual handlers, services, and routes, endpoint by endpoint. Also added an OpenAPI spec. New/changed material below:
Login with company code
POST /login gained a company_code field (required for web, omitted by mobile) to resolve which org to authenticate against — resolved to a local org row, then a Zitadel org, then membership is verified before tokens are minted. The platform org is now seeded automatically at startup from AUTHAPI_ZITADEL_DEFAULT_ORG rather than requiring manual setup.
Org self-signup deferred to approval time
Self-signup no longer touches Zitadel at all — it stores the applicant's details on a pending org row and stops. The Zitadel org and admin user are created only when a platform admin approves the org, at which point a random temporary password is generated and the admin is forced to change it on first login. This eliminates orphaned Zitadel orgs/users from abandoned signups. The old public "join an existing org" signup endpoint is gone.
Both users and orgs now have independent status gates — see Account & Org State Machine. A pending org blocks login for every one of its members, distinct from a pending individual account.
Company code + on-prem licensing + move to GORM
New feature surface: company-code-based hosting-mode discovery, an on-prem phone-home/status handshake, and Ed25519-signed on-prem license keys with an expiry grace period that blocks auth once exceeded. Schema management moved from hand-written SQL migrations to GORM auto-migration — there are no more standalone .sql files to apply.
Sessions, SSE, invites, device info
- Refresh tokens now carry a stable session ID that survives rotation, plus device metadata (OS, browser, app version). Multiple concurrent logins are now distinguishable as separate sessions.
- New session-management endpoints: list sessions with device info, revoke one session, revoke all other sessions, and a live SSE stream that pushes a revocation event to a session the moment it's killed elsewhere.
- New invite-code flow: an admin can invite a user directly; the user activates their account with a one-time code on first login. Invite codes can be reissued if lost or expired.
- New reconciliation endpoint to repair drift between Zitadel and AuthAPI's own database, and to discover orgs/users created directly in Zitadel.
- Added JWKS and OIDC discovery endpoints for other services to verify AuthAPI-issued tokens.
JWT: single org claim, not an array
The access/refresh token payload changed from an orgs array to a single org object — each user now belongs to exactly one org. Anything still parsing the old array shape needs updating.
2026-06-29
Removed POST /api/v1/login/mobile. Added required PlayTelly-Platform header (web | mobile) to POST /api/v1/login — single endpoint now handles both client types.
2026-06-23
Initial AuthAPI documentation.