livqenoDocs

ConceptsToken

Token

An app's short-lived pass for one room or conversation. Made by your backend.

A token is a short-lived pass your app uses to join a call or a chat. Your backend makes it with the API key and sends it to the app. It's the only Livqeno credential an app ever gets.

Tokens are the link between your backend and your app:

Project → API key → your backend mints a token → your app joins with it → webhooks.

Why it exists

An API key can do everything in a project. Your app needs much less, and it can't be trusted with the key, because anyone can read an app's code. A token is the small, safe version. It holds:

  • one identity (the user, like alice)
  • one room, or a named list of conversations
  • a fixed set of permissions (what the user may do)
  • an expiry time

How a token is used

1. alice clicks "Join"         → your app calls YOUR backend
2. your backend checks login   → asks Livqeno for a token (with the API key)
3. Livqeno returns a grant     → { token, endpoint, iceServers, ... }
4. your backend returns it     → to alice's app, unchanged
5. alice's app joins           → Livqeno checks the token, lets her in

The whole response in step 3 is called the grant. It has the token plus the addresses the app needs. Send the whole grant to the app, not just the token.

Two kinds

RTC tokenChat token
Use it forVideo and audio callsChat
Allowsjoin / publish / subscribe in one roomread / send / moderate / manage in named conversations
Default lifetime600s (10 min)3600s (1 hour)
Maximum lifetime21600s (6h)21600s (6h)
Used withThe signaling socket, and telemetryThe chat socket, and the chat REST API
Made withlivqeno.tokens.create()livqeno.chat.createToken()

An RTC token doesn't work for chat, and a chat token doesn't work for calls. An app that does both (a call with a chat panel) gets two tokens.

What's inside

An RTC token holds the token id, the user's identity, the project, the environment, the room id and name, the permissions, and the expiry.

  • Everything is signed, so nobody can change it without breaking it.
  • Anyone holding the token can read it. That's fine: nothing inside is secret.

Expiry keeps it safe

Tokens are short-lived on purpose. There's no such thing as a token that never expires. If a token leaks, it stops working soon.

Make a new token each time a user joins. By default expiry only matters when joining (and reconnecting): a user who joined with a valid token isn't kicked out when it expires mid-call. Where the server enforces expiry, give the SDK a refreshToken callback so long calls get a new token in place.

Revoking early:

  • RTC token: call DELETE /v1/rooms/{roomId}/rtc-tokens/{tokenId}. It can't be used to join again. A call that's already connected keeps going. See RTC authentication → Revocation.
  • Chat token: your backend calls DELETE /v1/chat/tokens/{tokenId} with the API key. New connections with it then fail with TOKEN_REVOKED. A connection that's already open stays open. There's no server-SDK method or CLI command for this yet.

Example

On your backend, make a token for a viewer who can watch and listen, but not send video:

const credentials = await livqeno.tokens.create({
  room: room.id,
  identity: 'user-42',
  permissions: { join: true, subscribe: true },
});

This token can join and watch. It can't publish, and the app can't change that.

Common mistakes

MistakeWhat you'll seeFix
Reusing one old token for every joinTOKEN_EXPIREDMake a fresh token per join.
Taking identity from the request bodyUsers can join as someone elseTake it from your own login session.
Sending only token to the app, not the whole grantCalls fail on mobile networksForward the whole grant, including iceServers.
Using an RTC token for chatChat rejects itMake a separate chat token.

Next steps

  1. Mint a token: the working code, in TypeScript, Python, Go, Java and PHP.
  2. Permissions: what each permission allows.
  3. Access tokens: the full API for making tokens.