Overview
The API uses two authentication mechanisms depending on who is making the request:User authentication (JWT)
Users log in via the web app. On successful login the API returns a signed JWT. The web app stores this and sends it with every subsequent request. Login endpoint:POST /api/auth/login
remember_me & refresh tokens
Whenremember_me: true is passed, the API issues a refresh token alongside the access token. The refresh token lives for 12 hours. Use it to get a new access token without re-entering credentials:
Refresh endpoint: GET /api/auth/refresh-token
Send the refresh token as a bearer token. Returns a fresh access token.
Without remember_me, the session ends when the browser tab closes (no refresh token issued).
Magic link (passwordless)
Users can also authenticate without a password via a magic link sent to their email.POST /api/auth/request-magic-link— sends the linkPOST /api/auth/validate-magic-link— exchanges the token in the link for a JWT
OAuth2
The web app supports OAuth2 for third-party identity providers. The OAuth2 flow follows the standard authorisation code pattern:- Redirect the user to the provider’s authorisation URL
- Provider redirects back with an authorisation code
- The API exchanges the code for an access token and returns a Kair Voice JWT
Guest access
Participants joining a session without an account receive a guest token scoped to that session only. Guest login endpoint:POST /api/auth/guest
Device authentication (API key)
Physical devices authenticate with a device-scoped API key obtained during the pairing flow. See Devices for the full pairing process. Protected device endpoints:POST /api/devices/{device_id}/heartbeatPOST /api/devices/{device_id}/session/startPOST /api/devices/{device_id}/session/stopPOST /api/sessions/{session_id}/upload-audio
expires_at. The device must call POST /api/devices/pair/claim-auth again to get a fresh key.
Roles
Endpoints that don’t require authentication
POST /api/auth/loginPOST /api/auth/guestPOST /api/devices/pairing-codes(device publishes pairing code)GET /api/devices/pair/status(device polls pairing status)GET /api/health