Skip to main content
The auth endpoints handle the full authentication lifecycle: email verification, account creation, token management, and password reset. Endpoints marked requires auth expect a valid Bearer token in the Authorization header.

POST /api/v1/auth/request-verification

Send a verification email to begin the email-based signup flow. The token expires after 24 hours and the same email address is limited to 3 requests per hour.
curl -X POST https://app.nexrex.ai/api/v1/auth/request-verification \
  -H "Content-Type: application/json" \
  -d '{"email": "runner@example.com"}'

Request body

email
string
required
The email address to verify. Must be a valid email format and not already registered.

Response

{
  "message": "Verification email sent",
  "expires_in": 86400
}
message
string
Confirmation that the email was sent.
expires_in
integer
Seconds until the verification token expires. Currently 86400 (24 hours).

POST /api/v1/auth/verify-token

Check whether a verification token is still valid and return the associated email address. Use this to prefill the registration form before the user submits their password.
curl -X POST https://app.nexrex.ai/api/v1/auth/verify-token \
  -H "Content-Type: application/json" \
  -d '{"token": "abc123..."}'

Request body

token
string
required
The verification token from the email link.

Response

{
  "valid": true,
  "email": "runner@example.com"
}
valid
boolean
true if the token exists and has not expired, false otherwise.
email
string
The email address associated with the token. Only present when valid is true.
error
string
Human-readable reason the token is invalid. Only present when valid is false.

POST /api/v1/auth/complete-signup

Finish registration by consuming a valid verification token and setting a password. The token is deleted after a successful call — it cannot be reused.
curl -X POST https://app.nexrex.ai/api/v1/auth/complete-signup \
  -H "Content-Type: application/json" \
  -d '{
    "token": "abc123...",
    "password": "MySecure1"
  }'

Request body

token
string
required
The verification token from the email link.
password
string
required
The user’s chosen password. Must be at least 8 characters and contain at least one uppercase letter, one lowercase letter, and one digit.

Response 201 Created

{
  "user_id": "uid_abc123",
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_at": "2026-04-24T10:00:00Z",
  "credentials": {
    "user_id": "uid_abc123",
    "email": "runner@example.com",
    "is_verified": false,
    "is_active": true,
    "roles": ["user"],
    "created_at": 1745395200000,
    "updated_at": 1745395200000
  },
  "profile": {
    "user_id": "uid_abc123",
    "email": "runner@example.com",
    "username": "runner",
    "status": "active",
    "membership_role": "athlete",
    "subscription": {
      "tier": "free",
      "status": "active"
    }
  },
  "is_new_user": true,
  "success": true
}
user_id
string
The Firebase UID assigned to the new user.
access_token
string
JWT access token for subsequent authenticated requests.
token_type
string
Always "Bearer".
expires_at
string
ISO 8601 timestamp when the access token expires.
credentials
object
Account-level credentials record including roles and verification status.
profile
object
Full user profile document created for the new account.
is_new_user
boolean
Always true for this endpoint.

POST /api/v1/auth/signup

Create or update a user account using a Firebase ID token. If the user already exists (for example they previously signed up on the mobile app), their membership role is updated instead of creating a duplicate account.
curl -X POST https://app.nexrex.ai/api/v1/auth/signup \
  -H "Content-Type: application/json" \
  -d '{
    "firebase_id_token": "<firebase_id_token>",
    "username": "coach_sam",
    "profile_data": {
      "membership_role": "coach",
      "display_name": "Sam Lee",
      "first_name": "Sam",
      "last_name": "Lee"
    }
  }'

Request body

firebase_id_token
string
required
A valid Firebase ID token obtained from Firebase Authentication on the client.
username
string
Desired username. 3–30 characters, letters, numbers, and underscores only. Auto-generated from the email prefix if omitted.
profile_data
object
Optional profile fields to set on the new account. Only the fields listed below are accepted — any other fields are silently ignored.
FieldTypeDescription
display_namestringPublic display name
first_namestringFirst name
last_namestringLast name
membership_rolestring"athlete" or "coach"
notification_settingsobjectNotification preferences
platformstringClient platform identifier
preferencesobjectUser preferences (timezone, language, unit system, etc.)

Response 200 OK (existing user) / 201 Created (new user)

Same shape as complete-signup above, plus an is_new_user boolean indicating whether an account was created (true) or updated (false).

POST /api/v1/auth/token/refresh

Requires auth. Exchange the current access token for a new one. Call this before the current token expires to maintain a continuous session.
curl -X POST https://app.nexrex.ai/api/v1/auth/token/refresh \
  -H "Authorization: Bearer <current_access_token>"

Response

{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "Bearer",
  "expires_at": "2026-04-24T12:00:00Z"
}
access_token
string
The new JWT access token.
token_type
string
Always "Bearer".
expires_at
string
ISO 8601 timestamp when the new token expires.

GET /api/v1/auth/me

Requires auth. Return the authenticated user’s account credentials.
curl https://app.nexrex.ai/api/v1/auth/me \
  -H "Authorization: Bearer <access_token>"

Response

{
  "user_id": "uid_abc123",
  "email": "runner@example.com",
  "roles": ["user"],
  "is_verified": true,
  "is_active": true,
  "last_login": "2026-04-23T08:30:00Z"
}
user_id
string
The user’s unique ID.
email
string
The user’s email address.
roles
array
List of roles assigned to the account (e.g. ["user"], ["user", "coach"]).
is_verified
boolean
Whether the user’s email address has been verified.
is_active
boolean
Whether the account is active.
last_login
string
ISO 8601 timestamp of the last login.

POST /api/v1/auth/logout

Requires auth. Signal that the current session has ended. Because the API uses stateless JWTs, the server does not invalidate the token — the client is responsible for discarding it.
curl -X POST https://app.nexrex.ai/api/v1/auth/logout \
  -H "Authorization: Bearer <access_token>"

Response

{
  "message": "Successfully logged out"
}

POST /api/v1/auth/password-reset

Request a password reset email. Always returns a success message regardless of whether the email is registered, to prevent user enumeration.
curl -X POST https://app.nexrex.ai/api/v1/auth/password-reset \
  -H "Content-Type: application/json" \
  -d '{"email": "runner@example.com", "source": "app"}'

Request body

email
string
required
The email address associated with the account.
source
string
Origin of the request. "app" or "web". Defaults to "web". Controls which email template is sent.

Response

{
  "message": "Password reset email sent"
}

POST /api/v1/auth/password-reset/confirm

Set a new password using the reset token from the email link.
curl -X POST https://app.nexrex.ai/api/v1/auth/password-reset/confirm \
  -H "Content-Type: application/json" \
  -d '{
    "token": "reset_token_from_email",
    "new_password": "NewSecure1"
  }'

Request body

token
string
required
The password reset token from the email link.
new_password
string
required
The new password. Must be at least 8 characters long.

Response

{
  "message": "Password reset successfully"
}