Authentication API
Endpoints are grouped by access level: public, authenticated, and admin.
Public Endpoints
These endpoints are accessible without authentication.
Sign In
Initiates the authentication process for existing users.
Endpoint: POST /auth/sign-in
Request Body:
{
"email": "jane.doe@example.com"
}
Success Response (SSO): 200 OK
{
"authData": {
"authMethod": "sso",
"redirectURL": "https://api.workos.com/sso/authorize?client_id=...",
"state": "a_random_state_string_for_security"
}
}
Success Response (Magic Auth): 200 OK
{
"authData": {
"authMethod": "magic_auth"
}
}
Error Response: 400 Bad Request
{
"code": 400,
"message": "Bad request"
}
Dev Sign In
This endpoint is for development and testing purposes only. Do not use in production.
Endpoint: POST /auth/dev-sign-in
Request Body:
{}
Success Response: 200 OK
{
"user": {
"id": "user_01HCNYK4PEV6Y1EDZ8EAZG1A1B",
"email": "admin@cazzi.com"
}
}
Sign Up
Creates a new user account.
Endpoint: POST /auth/sign-up
Request Body:
{
"email": "new.user@example.com"
}
Success Response: 201 Created
{
"code": 201,
"message": "Created"
}
Finalize OAuth
Completes the OAuth authentication flow.
Endpoint: POST /auth/finalize-oauth
Request Body:
{
"code": "FHN398YTN3904T309M"
}
Success Response: 200 OK
{
"user": {
"id": "user_01HCNYK4PEV6Y1EDZ8EAZG1A1B",
"email": "johndoe@abc.com",
"firstName": "John",
"lastName": "Doe",
"avatarURL": "https://example.com/avatar.png"
}
}
Resend Magic Auth
Resends the magic authentication code to the user's email.
Endpoint: POST /auth/resend-magic-auth
Request Body:
{
"email": "user.with.magic.auth@example.com"
}
Success Response: 200 OK
{
"code": 200,
"message": "OK"
}
Finalize Magic Auth
Completes the magic link authentication flow.
Endpoint: POST /auth/finalize-magic-auth
Request Body:
{
"email": "user.with.magic.auth@example.com",
"code": "123456"
}
Success Response (Single Organization): 200 OK
{
"user": {
"id": "user_01HCNYK4PEV6Y1EDZ8EAZG1A1B",
"email": "johndoe@abc.com",
"firstName": "John",
"lastName": "Doe",
"avatarURL": "https://example.com/avatar.png"
}
}
Success Response (Multiple Organizations): 200 OK
When a user belongs to multiple organizations, they must select one to continue.
{
"user": {
"id": "user_01JY16X8FCYMX981HC4GYQ6S01",
"email": "123@gmail.com",
"pendingAuthenticationToken": "uMc1tPo4wDjpsnb2mEZlOv8KD",
"organizations": [
{
"id": "org_01K2Z1R2MEJK6B41WW7428G9YC",
"name": "MASADAS"
},
{
"id": "org_01K3BK4YS5SDH22RV4P9QYJR7Z",
"name": "TAUNTA SCRE"
}
]
}
}
Continue with Google
Initiates Google OAuth authentication flow.
Endpoint: POST /auth/continue-with-google
Request Body: None
Success Response: 200 OK
{
"authData": {
"redirectURL": "https://yourapp.com/redirecturl",
"state": "xyz123stateToken"
}
}
Continue with Microsoft
Initiates Microsoft OAuth authentication flow.
Endpoint: POST /auth/continue-with-microsoft
Request Body: None
Success Response: 200 OK
{
"authData": {
"redirectURL": "https://yourapp.com/redirecturl",
"state": "xyz123stateToken"
}
}
Select Organization
Selects an organization after authentication when user belongs to multiple organizations.
Endpoint: POST /auth/select-organization
Request Body:
{
"pendingAuthenticationToken": "KcFtu30FfyJUfyeeaTwKwU02P",
"organizationId": "org_01K3BK4YS5SDH22RV4P9QYJR7Z"
}
Success Response: 200 OK
{
"user": {
"id": "user_01HCNYK4PEV6Y1EDZ8EAZG1A1B",
"email": "johndoe@abc.com",
"firstName": "John",
"lastName": "Doe",
"avatarURL": "https://example.com/avatar.png"
}
}
Switch Organization
Switches the active organization for an authenticated user.
Endpoint: POST /auth/switch-organization
Request Body:
{
"email": "johndoe@abc.com",
"organizationId": "org_01K2Z1R2MEJK6B41WW7428G9YC"
}
Success Response: 200 OK
{
"user": {
"id": "user_01HCNYK4PEV6Y1EDZ8EAZG1A1B",
"email": "johndoe@abc.com",
"firstName": "John",
"lastName": "Doe",
"avatarURL": "https://example.com/avatar.png"
}
}
Protected Endpoints
These endpoints require authentication. Include a valid session token in the request.
Sign Out
Signs out the authenticated user.
Endpoint: POST /auth/sign-out
Request Body: None
Success Response: 200 OK
{
"authData": {
"redirectURL": "https://api.workos.com/user_management/sessions/logout?return_to=...&session_id=session_01JZG38PH9VWFRMCXZB8M5B6SR"
}
}
Avatar Upload Ticket
Generates a presigned URL for direct avatar upload to R2 storage.
Endpoint: POST /auth/avatar/upload-ticket
Request Body:
{
"contentType": "image/webp"
}
Allowed Content Types:
image/jpegimage/pngimage/webp
Success Response: 200 OK
{
"code": 200,
"message": "OK",
"data": {
"uploadUrl": "https://<account>.r2.cloudflarestorage.com/bucket/tmp/user123/abc.webp?X-Amz-Algorithm=...",
"tmpKey": "tmp/user123/550e8400-e29b-41d4-a716-446655440000.webp",
"expiresInSeconds": 120
}
}
Error Responses:
| Status | Condition |
|---|---|
| 400 | Unsupported content type |
| 401 | Missing or invalid authentication |
| 422 | Request validation failed |
| 500 | Failed to generate presigned URL |
Notes:
After receiving the presigned URL, upload the image directly to R2 using a PUT request:
curl -X PUT "<uploadUrl>" \
-H "Content-Type: image/webp" \
--data-binary @avatar-image.webp
Avatar Finalize
Validates and promotes an uploaded avatar to permanent storage, updates user profile.
Endpoint: POST /auth/avatar/finalize
Request Body:
{
"tmpKey": "tmp/user123/550e8400-e29b-41d4-a716-446655440000.webp"
}
Success Response: 200 OK
{
"code": 200,
"message": "OK",
"avatarUrl": "https://avatars.qubital.space/avatars/user123/550e8400-e29b-41d4-a716-446655440000.webp"
}
Error Responses:
| Status | Condition |
|---|---|
| 400 | Invalid image (corrupt, wrong format, wrong dimensions) |
| 401 | Missing or invalid authentication |
| 403 | tmpKey doesn't belong to authenticated user |
| 404 | Upload not found (expired or never uploaded) |
| 422 | Request validation failed |
| 500 | Internal error (R2 operation failed, WorkOS update failed) |
LiveKit Room Authorization
Generates an access token for joining a LiveKit room.
Endpoint: POST /api/v1/livekit/room-auth
Request Body:
{
"username": "Jane Doe",
"roomId": "room123"
}
Success Response: 200 OK
{
"token": "livekitToken"
}
Start Recording
Starts recording a LiveKit room session.
Endpoint: POST /api/v1/livekit/start-recording
Request Body:
{
"roomName": "test-room",
"conferenceTopic": "Weekly Sync Meeting",
"zoneId": "1",
"participants": "alice,bob,charlie"
}
Success Response: 200 OK
{
"egressId": "egress-456789",
"timestamp": 1752486896
}
Stop Recording
Stops an active LiveKit room recording.
Endpoint: POST /api/v1/livekit/stop-recording
Request Body:
{
"roomName": "test-room",
"egressId": "egress-456789",
"zoneId": "1"
}
Success Response: 200 OK
{
"egressId": "egress-456789",
"timestamp": 1752486896
}