Guide

Authentication

Every third-party call to Velora carries an OAuth 2.0 access token issued to a specific user for a specific set of scopes. This page walks the one flow that gets you that token — authorization code with PKCE— from generating a verifier to putting a Bearer header on a request.

Authorization code flow with PKCE

This flow is recommended for web and mobile applications where you need to act on behalf of a user. Four steps: you generate a secret, send the user to Velora, get a code back, and trade the code for a token.

01Generate a PKCE code verifier

Generate a cryptographically random code verifier (43–128 characters). Keep it in memory on the client that started the flow — you need it again in step 4.

JavaScript
// JavaScript example
function generateCodeVerifier() {
  const array = new Uint8Array(32);
  crypto.getRandomValues(array);
  return base64URLEncode(array);
}

function base64URLEncode(buffer) {
  return btoa(String.fromCharCode(...buffer))
    .replace(/\+/g, '-')
    .replace(/\//g, '_')
    .replace(/=/g, '');
}

02Generate the code challenge

Create a SHA-256 hash of the code verifier. This is the value you send to Velora; the verifier itself never leaves your app until the token exchange.

JavaScript
async function generateCodeChallenge(verifier) {
  const encoder = new TextEncoder();
  const data = encoder.encode(verifier);
  const hash = await crypto.subtle.digest('SHA-256', data);
  return base64URLEncode(new Uint8Array(hash));
}

03Redirect to the authorization URL

Redirect the user to the authorization page. They see which scopes you are asking for and approve or decline.

Redirect
https://velora.tv/oauth/authorize?
  client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.com/callback
  &response_type=code
  &scope=user:read stream:read
  &state=RANDOM_STATE_VALUE
  &code_challenge=YOUR_CODE_CHALLENGE
  &code_challenge_method=S256

04Exchange the code for a token

After the user authorizes, exchange the code for an access token.

Request — curl
curl -X POST https://api.velora.tv/api/developer/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "code": "AUTHORIZATION_CODE",
    "redirect_uri": "https://yourapp.com/callback",
    "code_verifier": "YOUR_CODE_VERIFIER"
  }'
Response 200
{
  "access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI...",
  "refresh_token": "dGhpcyBpcyBhIHJlZnJlc2ggdG9rZW4...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "scope": "user:read stream:read"
}

Using access tokens

Include the access token in the Authorization header on every request.

Request — curl
curl https://api.velora.tv/api/users/me \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN"

Refreshing tokens

Access tokens expire after 1 hour. Use the refresh token to get a new access token.

Request — curl
curl -X POST https://api.velora.tv/api/developer/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "refresh_token",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "YOUR_CLIENT_SECRET",
    "refresh_token": "YOUR_REFRESH_TOKEN"
  }'

The two flows

Velora supports two OAuth 2.0 flows. Unless your app never touches a user’s data, you want the first one.

Authorization Code with PKCE
For user authorization in web and mobile apps.
Client Credentials
For server-to-server requests (app-only access).

OAuth endpoints

Three URLs, and they are not on the same host: consent is served by the site, tokens and scopes by the API.

Authorization URL (user consent page)

https://velora.tv/oauth/authorize

Token URL (API endpoint)

https://api.velora.tv/api/developer/oauth/token

Scopes reference

https://api.velora.tv/api/developer/oauth/scopes

Available scopes

Scopes control what actions your application can perform. These are the most commonly used ones.

ScopeDescription
user:readRead user profile information
user:writeUpdate user profile
stream:readRead stream information
stream:writeUpdate stream settings
stream:keyAccess stream key and ingest URLs
chat:readRead chat messages
chat:writeSend chat messages
chat:moderateModerate chat (timeout, ban, delete)

View all 16 available scopes →

Next steps