Skip to main content

Overview

The Reelevant API uses OAuth 2.0 for authentication. Three grant types are supported:
Grant TypeUse Case
authorization_codeBrowser-based login with PKCE (recommended for web apps)
passwordDirect username/password exchange (service accounts, scripts)
refresh_tokenRenew an expired access token without re-authenticating
All token operations use the endpoint POST https://api.reelevant.com/v2/auth/token. A client_id is required for every grant. Contact [email protected] to obtain one.

Authorization Code Flow (PKCE)

This is the recommended flow for web applications. It uses a browser redirect to authenticate the user, then exchanges an authorization code for tokens.

Step 1: Generate PKCE Challenge

Generate a random code_verifier and derive the code_challenge:
import { randomBytes, createHash } from 'crypto'

const codeVerifier = randomBytes(32).toString('base64url')
const codeChallenge = createHash('sha256')
  .update(codeVerifier)
  .digest('base64url')

Step 2: Redirect to Authorize

Redirect the user’s browser to the authorization endpoint:
GET https://api.reelevant.com/v2/oauth/authorize
  ?client_id=<client_id>
  &redirect_uri=<redirect_uri>
  &response_type=code
  &code_challenge=<code_challenge>
  &code_challenge_method=S256
  &state=<random_state>
  &lang=en
ParameterRequiredDescription
client_idYesYour OAuth client identifier
redirect_uriYesMust match a registered redirect URI for the client
response_typeYesMust be code for the authorization code flow
code_challengeYesBase64url-encoded SHA-256 hash of the code_verifier
code_challenge_methodNoOnly S256 is supported (default)
stateRecommendedOpaque value to prevent CSRF — returned unchanged in the callback
langNoLogin page language (en or fr)
The user sees a login page. After successful authentication, a consent screen is shown. Upon approval, the browser is redirected to your redirect_uri with an authorization code:
https://your-app.com/callback?code=<authorization_code>&state=<state>
Authorization codes are single-use and expire after 60 seconds. Exchange them immediately.

Step 3: Exchange Code for Tokens

curl -XPOST https://api.reelevant.com/v2/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "client_id": "<client_id>",
    "grant_type": "authorization_code",
    "code": "<authorization_code>",
    "redirect_uri": "<redirect_uri>",
    "code_verifier": "<code_verifier>"
  }'
The code_verifier must match the code_challenge sent in Step 2 (the server verifies SHA256(code_verifier) == code_challenge). Response:
{
  "access_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "refresh_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "expires_in": 3600,
  "token_type": "Bearer"
}
Some OAuth clients are configured with requireAuthorizationCodeFlow: true. For these clients, PKCE parameters are mandatory — the implicit flow is disabled entirely.

Password Grant

For service accounts and automation scripts where browser-based login is not practical.
curl -XPOST https://api.reelevant.com/v2/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "username": "[email protected]",
    "password": "your-password",
    "grant_type": "password",
    "client_id": "<client_id>"
  }'
Response:
{
  "access_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "refresh_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Two-Factor Authentication (OTP)

If the user has OTP enabled, include the x-otp-code field:
curl -XPOST https://api.reelevant.com/v2/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "username": "[email protected]",
    "password": "your-password",
    "grant_type": "password",
    "client_id": "<client_id>",
    "x-otp-code": "123456"
  }'

Refresh Token Grant

Exchange a valid refresh token for a new access token without re-authenticating:
curl -XPOST https://api.reelevant.com/v2/auth/token \
  -H "Content-Type: application/json" \
  -d '{
    "refresh_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
    "grant_type": "refresh_token",
    "client_id": "<client_id>"
  }'
Response:
{
  "access_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "refresh_token": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "expires_in": 3600,
  "token_type": "Bearer"
}

Using Access Tokens

Include the access token in every API request via the Authorization header:
Authorization: Bearer <access_token>

Token Lifecycle

Token TypeLifetimeRenewal
Access token1 hourUse refresh_token grant to obtain a new one
Refresh token30 days (rolling)Refreshed automatically each time it is used to generate a new access token
Authorization code60 secondsSingle-use — exchange immediately after receiving
Refresh tokens use a rolling expiry: the 30-day window resets each time you use the refresh token. If you refresh at least once a month, the token never expires.

Revoking Tokens

Revoke an access token or refresh token:
curl -XDELETE https://api.reelevant.com/v2/auth/token/<token_id>
Revoking a refresh token also revokes all access tokens derived from it.

SSO Authentication

Companies with SSO configured are automatically redirected to their identity provider during the OAuth authorize flow. If SSO is mandatory for the company, password-based login is disabled (except for service accounts).

Error Handling

ErrorHTTP StatusCause
invalid_client400Unknown or inactive client_id
invalid_redirect_uri400redirect_uri not in the client’s allowed list
invalid_request400Missing required parameters (e.g., code_challenge for PKCE)
invalid_credentials401Wrong username or password
too_many_attempts429Login attempts exceeded — wait before retrying
password_expired401Password must be changed before logging in
otp_required401OTP code required but not provided
invalid_code400Authorization code is invalid, expired, or already used
pkce_mismatch400code_verifier does not match the original code_challenge