These docs are a work in progress and may not be fully up to date. Some pages may contain internal notes for our team.
Skip to Content

API — Auth

Registration, login, 2FA, logout, and the authenticated “me” endpoint. All routes are prefixed with the API base URL (NEXT_PUBLIC_API_URL).

Unauthenticated endpoints

POST /register

Register a new user account.

Body: { name, email, password, password_confirmation }

Response 201: { token, user: { id, name, email, role, subscription_tier, ... } }

POST /register/{token}

Register using an invite token (pre-fills email and workspace association).

Params: token — invite token from GET /register/{token}

Body: { name, password, password_confirmation }

GET /register/{token}

Verify an invite token is valid before showing the registration form.

Response 200: { email, workspace_name } if valid. 404 if expired or not found.

POST /login

Authenticate an existing user.

Body: { email, password }

Response 200: { token, user } on success, or { two_factor_required: true, challenge_token } if 2FA is enabled.

POST /login/2fa

Complete a 2FA login challenge.

Body: { challenge_token, code }code is either a TOTP code or an email OTP code.

Response 200: { token, user }

Authenticated endpoints

All endpoints below require Authorization: Bearer <jwt> plus the auth:api and auth_session middleware.

GET /me

Return the authenticated user’s profile and billing state.

Response 200:

{ "id": 1, "name": "Jane Smith", "email": "jane@example.com", "role": "user", "subscription_status": "active", "subscription_tier": "bronze" }

JWT claims (role, subscription_status, subscription_tier) are embedded in the token and read client-side without a round-trip; this endpoint is used for full profile hydration and post-login sync.

PUT /me

Update profile fields (name, email, password). Partial updates are supported.

Body: { name?, email?, current_password?, password?, password_confirmation? }

Response 200: Updated user object.

POST /logout

Invalidate the current JWT (adds to blacklist).

Response 204

POST /me/2fa/totp/setup

Initiate TOTP authenticator setup. Returns a secret and QR code URI.

POST /me/2fa/totp/confirm

Confirm TOTP setup with a test code. Activates TOTP 2FA.

DELETE /me/2fa/totp

Disable TOTP 2FA.

POST /me/2fa/email/enable / DELETE /me/2fa/email

Enable or disable email-based 2FA challenge.

POST /me/2fa/recovery-codes

Regenerate recovery codes.

GET /me/sessions

List active JWT sessions (jti tracking).

DELETE /me/sessions

Revoke all sessions except the current one.

DELETE /me/sessions/{id}

Revoke a specific session.

DELETE /me

Soft-delete the account. Requires { password, confirmation: "DELETE MY ACCOUNT" } in the body.

Token shape

JWTs carry three custom claims beyond the standard payload:

ClaimValues
roleadmin or user
subscription_statusactive, trialing, past_due, canceled, or none
subscription_tiernone, free, bronze, premium, or custom

TTL: 20,160 minutes (14 days). No refresh endpoint — the frontend re-authenticates on 401.