Authentication API
sTvOS supports multiple authentication flows for end users, trainers, and partner staff.
Client User Authentication
All client user auth endpoints require the X-API-Key header.
Register POST /auth/register
Create a new user account under the client identified by the API key.
{
"email": "user@example.com",
"password": "securepassword",
"name": "Jane Doe",
"voucherCode": "STUDIO-ABC123",
"sessionId": "onboarding-session-id",
"coachId": 5,
"profile": {
"age": 28,
"gender": "female",
"fitnessLevel": "intermediate"
},
"settings": {
"notifications": true
}
}
Only email and password are required. All other fields are optional.
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"name": "Jane Doe",
"role": "user"
},
"accessToken": "eyJhbGciOi...",
"refreshToken": "eyJhbGciOi..."
}
}
Onboarding merge
If sessionId is provided, the pending onboarding profile is automatically merged into the new account. If voucherCode is provided, it is redeemed and the user is assigned to the voucher's partner client.
Login POST /auth/login
Authenticate a user with email and password.
{
"email": "user@example.com",
"password": "securepassword"
}
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"name": "Jane Doe",
"role": "user"
},
"accessToken": "eyJhbGciOi...",
"refreshToken": "eyJhbGciOi...",
"client": {
"id": 1,
"name": "Studio Name",
"branding": { }
}
}
}
Universal API key
When using the universal API key, the response includes a client object so the app knows which branding to apply. This enables a single mobile app to serve multiple studio clients.
Refresh Token POST /auth/refresh
Exchange a refresh token for a new access token.
{
"refreshToken": "eyJhbGciOi..."
}
{
"success": true,
"data": {
"accessToken": "eyJhbGciOi..."
}
}
Logout POST /auth/logout Bearer
Stateless logout. The server does not invalidate tokens -- the client should discard stored tokens.
{
"success": true,
"data": {
"message": "Logged out successfully"
}
}
Current User GET /auth/me
Get the current authenticated user. Requires both X-API-Key and Authorization: Bearer <token>.
{
"success": true,
"data": {
"user": {
"id": 1,
"email": "user@example.com",
"name": "Jane Doe",
"role": "user",
"profile": { },
"settings": { }
},
"client": {
"id": 1,
"name": "Studio Name"
}
}
}
Voucher Validation
Validate Code POST /auth/voucher/validate
Validate a voucher code before registration. Requires X-API-Key only (no bearer token).
{
"code": "STUDIO-ABC123"
}
{
"success": true,
"data": {
"valid": true,
"partner": {
"name": "Partner Name",
"clientId": 1
}
}
}
Trainer Authentication
Trainer auth endpoints accept either X-API-Key or X-Master-Trainer-Key.
Check Email POST /trainer-auth/check-email
Check if a trainer email is enabled for registration.
{
"email": "trainer@example.com"
}
{
"success": true,
"data": {
"exists": false,
"canRegister": true,
"trainer": { "id": 5, "name": "Coach Mike" }
}
}
Register Trainer POST /trainer-auth/register
Register a trainer as a user account. The trainer record must already exist (created by admin).
{
"email": "trainer@example.com",
"password": "securepassword"
}
{
"success": true,
"data": {
"user": {
"id": 10,
"email": "trainer@example.com",
"name": "Coach Mike",
"role": "trainer"
},
"accessToken": "eyJhbGciOi...",
"refreshToken": "eyJhbGciOi..."
}
}
Trainer Login POST /trainer-auth/login
Authenticate a trainer. Returns user tokens and trainer-specific information.
{
"email": "trainer@example.com",
"password": "securepassword"
}
{
"success": true,
"data": {
"user": {
"id": 10,
"email": "trainer@example.com",
"name": "Coach Mike",
"role": "trainer"
},
"trainer": {
"id": 5,
"name": "Coach Mike",
"specialisations": ["strength", "hiit"]
},
"accessToken": "eyJhbGciOi...",
"refreshToken": "eyJhbGciOi..."
}
}
Partner Staff Authentication
Partner auth endpoints do not require a client API key.
Login POST /partner-auth/login
Authenticate a partner staff member. Returns JWT tokens with 8-hour expiry.
{
"email": "staff@partner.com",
"password": "securepassword"
}
{
"success": true,
"data": {
"staff": {
"id": 1,
"email": "staff@partner.com",
"name": "Staff Name",
"role": "admin",
"clientId": 1
},
"accessToken": "eyJhbGciOi...",
"refreshToken": "eyJhbGciOi..."
}
}
Refresh POST /partner-auth/refresh
Refresh a partner staff access token.
{
"refreshToken": "eyJhbGciOi..."
}
{
"success": true,
"data": {
"accessToken": "eyJhbGciOi..."
}
}
Current Staff GET /partner-auth/me Partner JWT
Get the current authenticated partner staff member.
{
"success": true,
"data": {
"staff": {
"id": 1,
"email": "staff@partner.com",
"name": "Staff Name",
"role": "admin",
"clientId": 1,
"client": {
"id": 1,
"name": "Partner Studio"
}
}
}
}
Logout POST /partner-auth/logout Partner JWT
Stateless logout for partner staff. Discard stored tokens on the client side.
FAQ
How long do access tokens last?
Access tokens are short-lived JWTs. When a 401 response is received, call /auth/refresh with the stored refresh token to obtain a new access token.
What happens if a voucher code is invalid or expired?
The /auth/voucher/validate endpoint returns { "valid": false } with a reason. Registration with an invalid voucher code will be rejected with a 400 error.
Can a user belong to multiple clients?
No. Each user belongs to exactly one client. The client is determined at registration time by the API key (or voucher code for universal key flows).