Skip to content

API Authentication

All API requests require authentication via JSON Web Tokens (JWT). This guide covers how to obtain, use, and refresh tokens.

Overview

The API uses Bearer token authentication. After a successful login, the server issues a JWT that must be included in the Authorization header of every subsequent request. Tokens are short-lived and can be refreshed without re-entering credentials.


Getting a Token

Authenticate with your email and password to receive a JWT access token.

Endpoint: POST /api/v1/auth/login

Request body:

FieldTypeRequiredDescription
emailstringYesYour account email
passwordstringYesYour account password

Example:

bash
curl -X POST https://your-domain.com/api/v1/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "email": "user@example.com",
    "password": "your-password"
  }'

Success response (no 2FA):

json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "two_factor_required": false,
  "two_factor_setup_required": false,
  "two_factor_method": null,
  "temp_token": null
}

Use the access_token value for all authenticated requests.


Two-Factor Authentication (2FA) Flow

When 2FA is enabled on an account, the login endpoint does not return an access token directly. Instead, it returns a temporary token that must be exchanged by verifying a one-time code.

Step 1: Detect the 2FA challenge

The login response indicates a 2FA challenge when two_factor_required is true:

json
{
  "access_token": null,
  "token_type": "bearer",
  "two_factor_required": true,
  "two_factor_setup_required": false,
  "two_factor_method": "totp",
  "temp_token": "eyJhbGciOiJIUzI1NiIs..."
}

The two_factor_method field tells you which method the user has configured ("totp" or "email"). For the email method, the server automatically sends a code to the user's email address as part of the login call.

Step 2: Verify the code

Submit the temporary token along with the verification code from your authenticator app (TOTP) or email.

Endpoint: POST /api/v1/auth/verify-2fa

Request body:

FieldTypeRequiredDescription
temp_tokenstringYesThe temporary token from the login response
codestringYesThe 6-digit OTP or a one-time backup code

Example:

bash
curl -X POST https://your-domain.com/api/v1/auth/verify-2fa \
  -H "Content-Type: application/json" \
  -d '{
    "temp_token": "eyJhbGciOiJIUzI1NiIs...",
    "code": "123456"
  }'

Success response:

json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer",
  "two_factor_required": false,
  "two_factor_setup_required": false,
  "two_factor_method": null,
  "temp_token": null
}

Resending an email code

If the 2FA method is "email" and the user did not receive the code, you can request a new one.

Endpoint: POST /api/v1/auth/resend-2fa

bash
curl -X POST https://your-domain.com/api/v1/auth/resend-2fa \
  -H "Content-Type: application/json" \
  -d '{
    "temp_token": "eyJhbGciOiJIUzI1NiIs..."
  }'

Organization-enforced 2FA setup

If the login response has two_factor_setup_required: true instead, the user's organization requires 2FA but the user has not set it up yet. In this case, use the POST /api/v1/auth/2fa/setup-with-temp and POST /api/v1/auth/2fa/confirm-with-temp endpoints with the temp_token to complete setup before obtaining an access token.


Using the Token

Include the token in the Authorization header as a Bearer token on every API request:

Authorization: Bearer <access_token>

Example:

bash
curl https://your-domain.com/api/v1/users/me \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Refreshing a Token

Obtain a new access token without re-authenticating. The request must include a valid (non-expired) token in the Authorization header.

Endpoint: POST /api/v1/auth/refresh

Example:

bash
curl -X POST https://your-domain.com/api/v1/auth/refresh \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."

Response:

json
{
  "access_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
  "token_type": "bearer"
}

Replace your stored token with the new access_token value.


Token Expiration and Error Handling

Tokens have a limited lifetime. When a token expires or is otherwise invalid, the API responds with HTTP 401 Unauthorized.

Example 401 response:

json
{
  "detail": "Invalid or expired token"
}

Common 401 scenarios

Scenariodetail message
Token expiredInvalid or expired token
Malformed or missing tokenInvalid or expired token
Invalid login credentialsInvalid email or password
Account disabledAccount is disabled
Invalid 2FA codeInvalid code
Expired temporary tokenInvalid or expired token

Rate limiting on 2FA

The POST /api/v1/auth/verify-2fa endpoint enforces rate limiting. If too many failed verification attempts are made in a short period, the server responds with HTTP 429 Too Many Requests:

json
{
  "detail": "Too many attempts. Try again later."
}
  1. Store the access token securely after login.
  2. Include it in the Authorization header for every request.
  3. When you receive a 401 response, attempt a token refresh via POST /api/v1/auth/refresh.
  4. If the refresh also returns 401, redirect the user to log in again.
  5. Never store tokens in localStorage in browser environments; prefer httpOnly cookies or in-memory storage.

XC AI Content Automation