livqenoDocs

BackendAccess tokens

Tokens

How to make RTC and chat tokens on your backend, and what they allow.

A token is the only credential your app (browser or phone) ever gets. Think of it as a ticket: it names one user, says where they can go (one room, or some conversations), what they can do there, and when it expires. Your backend makes it with the API key; your app uses it to join.

Where this fits: project → API key → your backend makes tokens → your app joins. You'll write this code once, in a backend endpoint your app calls before joining.

New to the model? Read Authentication first.

There are two kinds, because calls and chat are separate systems: an RTC token for calls and live video, and a chat token for messaging. Each only works on its own system.

RTC tokens

On your backend, make an RTC token each time a user joins a call:

POST /v1/rooms/{roomId}/rtc-tokens
const token = await livqeno.tokens.create({
  room: roomId,
  identity: 'user-42',
  permissions: { join: true, subscribe: true, publish: true, publishAudio: true, publishVideo: true },
  expiresIn: 3600, // seconds, capped at 6 hours
});
// { token, endpoint, iceServers, expiresAt, ... }

identity is your id for this user (for example, their user id in your database). Other people in the room see it, and it must be unique in the room.

Reserved identities. Identities starting with egress-, relay-, capture-, transcriber- or agent- belong to Livqeno's own participants (recorders, relays, AI bots), which get no webhooks and aren't counted as your users. A mint with one of them is refused with 422 RAVEN_RESERVED_IDENTITY, and the message names the prefix. Prefix your own identities differently, for example user-agent-bob.

Metadata and attributes. Optionally, set the participant's starting metadata (an opaque string, at most 4 KiB) and attributes (string to string, at most 32 keys, keys up to 64 characters, values up to 1 KiB). Everyone in the room sees them. They are signed into the token, which travels in the signaling URL, so keep them small. A value over a limit is a 400. See Metadata and attributes for changing them during the call.

Permissions. There are seven:

join, subscribe, publish, publishAudio, publishVideo, publishData, updateOwnMetadata

  • updateOwnMetadata lets the participant change its own metadata and attributes from the app. Your backend can always change them.

  • Anything you don't turn on is off.

  • They are signed into the token. The server checks them; the app can't change them.

  • Details: Permissions.

A fresh token every time. Each call makes a new signed token. Livqeno doesn't store it. It does keep a record of the participant for auditing. Tokens are short-lived, so just make a new one each time a user joins. Don't cache tokens and hand the same one to different users.

Why short-lived? A token can't be taken back from someone who's already connected (see Revocation). A short lifetime is what limits the damage if one leaks.

Chat tokens

On your backend, make a chat token when a user opens chat. Before the user can use a conversation, they must be a member of it (add them with livqeno.chat.addMember):

POST /v1/chat/tokens
const token = await livqeno.chat.createToken({
  userId: 'alice',
  conversations: [conversation.publicId], // optional — omit for "any conversation this user belongs to"
  scopes: ['chat:read', 'chat:send'],      // optional — can only narrow the role's default, never widen it
  expiresIn: 3600,
});

What the user can do comes from two things:

  1. Their role in each conversation: MEMBER, MODERATOR, or ADMIN.
  2. The scopes you pass. These can only remove rights, never add them.

So asking for chat:moderate for a plain member gives them nothing extra. See Chat Overview.

The environment comes from the key

Every token carries the environment (development, staging, or production) of the API key that made it. The request can't choose it. So a test script on a laptop with a development key can never make a token that reaches your real users' production calls or messages. See Environments.

Revocation

Revoking means cancelling a credential before it expires, for example when a key leaks or you need to remove someone from a room.

WhatHowEffect
An API keylivqeno keys revoke <id>The key stops working. Tokens it made keep working until they expire.
One RTC tokenDELETE /v1/rooms/{roomId}/rtc-tokens/{tokenId} (use the id from the mint response)New connections with it fail with TOKEN_REVOKED, and sessions running on it are ended. Safe to call twice. Only works inside the key's own project and environment.
One participantPOST /v1/rooms/{roomId}/participants/{identity}/removeDisconnects that identity now (close 4003, don't reconnect). Doesn't revoke their token.
Everyone in a roomDELETE /v1/rooms/{roomId}Closes the room and disconnects everyone.

Details: RTC authentication → Revocation.

Next steps

  • Permissions: pick the right permissions for each kind of user (speaker, viewer, bot).
  • Quickstart: a token endpoint you can copy.