LiveKit rooms require a WebSocket URL and a participant JWT to join. This document covers how to obtain those credentials in C++ and how that relates to in-session token refresh.
Initial connect vs. in-session refresh
These are separate mechanisms:
| Initial connect | In-session token refresh |
| When | Before or at Room::connect | While already connected |
| Who provides the JWT | Your app, backend, or token server | LiveKit server (signal channel) |
| C++ API | Room::connect(url, token, …) | RoomDelegate::onTokenRefreshed (informational) |
| Rust / FFI | JWT passed once via connectAsync | Handled internally; C++ receives a TokenRefreshed event |
Token sources are for initial connection only. After a successful connect, the Rust core owns the session JWT. The SDK applies server-pushed token updates internally (for reconnect). Your token endpoint is not called again unless you invoke Room::connect again (for example after a full disconnect).
If you need the latest JWT after a server refresh, implement RoomDelegate::onTokenRefreshed and store TokenRefreshedEvent::token in your application.
Cross-platform background: LiveKit authentication docs.
Generating Tokens for Quick Development
For local development against livekit-server --dev, install livekit-cli and mint a token:
export LIVEKIT_URL=ws://localhost:7880
export LIVEKIT_TOKEN=$(lk token create \
--api-key devkey \
--api-secret secret \
-i my-participant \
--join \
--valid-for 24h \
--room my-room \
--grant '{"canPublish":true,"canSubscribe":true,"canPublishData":true}' \
--token-only)
For integration tests that need two participants, see testing.md and the helper script under .token_helpers/.
Direct connect (URL + token)
When you already have credentials, pass them directly — no token source required:
#include "livekit/livekit.h"
if (!room.
connect(url, token, options)) {
}
Represents a LiveKit room session.
Definition room.h:132
bool connect(const std::string &url, const std::string &token, const RoomOptions &options)
Connect to a LiveKit room using the given URL and token, applying the supplied connection options.
LIVEKIT_API bool initialize(const LogLevel &level=LogLevel::Info)
Initialize the LiveKit SDK.
Top-level room connection options.
Definition room.h:72
Use this for prototypes, tests, or when your app fetches the JWT outside the SDK.
Token sources (initial connect)
Token sources are C++ helpers that call fetch() to produce a TokenSourceResponse. Pass server_url and participant_token to Room::connect; optional room_name and participant_name response fields are informational metadata for application UI/logging when a token server provides them:
#include <livekit/token_source.h>
auto source = ;
auto credentials = source->fetch(request_options).get();
if (!credentials ||
!room.
connect(credentials.value().server_url, credentials.value().participant_token, options)) {
}
For a fixed source such as LiteralTokenSource, call fetch() without request options.
Room does not retain the token source after connect. Calling fetch() again only happens when your application invokes it again.
Fixed vs. configurable
| Base class | fetch signature | Use when |
TokenSourceFixed | fetch() | Credentials are fully determined without per-call options |
TokenSourceConfigurable | fetch(options) | Room, identity, agent dispatch, etc. vary per connect |
Token source types
| Type | Class | Typical use |
| Literal | LiteralTokenSource | Static URL + JWT, or lazy async provider |
| Endpoint | EndpointTokenSource | Production: HTTP token server on your backend |
| Sandbox | SandboxTokenSource | Development: LiveKit Cloud sandbox token server |
| Custom | CustomTokenSource | Your own async credential logic |
| Caching | CachingTokenSource | Decorator: JWT-aware cache around a configurable source |
Literal
Static credentials you already have, or credentials loaded asynchronously (keychain, secure storage, your auth service):
#include <livekit/token_source.h>
auto credentials = source->fetch().get();
if (!credentials ||
!room.
connect(credentials.value().server_url, credentials.value().participant_token, options)) {
return 1;
}
return std::async(std::launch::async, [] {
});
});
static std::unique_ptr< LiteralTokenSource > create(std::string server_url, std::string participant_token)
Create a token source from a static server URL and participant token.
static Result success(U &&value)
Construct a successful result containing a value.
Definition result.h:44
Credentials produced by a token source and consumed by Room::connect.
Definition token_source.h:43
std::string server_url
WebSocket URL of the LiveKit server. Use this to establish the connection.
Definition token_source.h:45
std::string participant_token
JWT token containing participant permissions and metadata. Required for authentication.
Definition token_source.h:48
Endpoint
Recommended for production. Keeps API keys on your server; the SDK POSTs (or GETs) to your token endpoint with optional room, participant, and agent fields.
Request and response formats follow the standard token server contract.
endpoint_options.
method =
"POST";
endpoint_options.
headers[
"Authorization"] =
"Bearer your-api-token";
"https://your-backend.example.com/token",
std::move(endpoint_options));
auto credentials = source->fetch(request).get();
if (!credentials ||
!room.
connect(credentials.value().server_url, credentials.value().participant_token, options)) {
return 1;
}
static std::unique_ptr< EndpointTokenSource > create(std::string endpoint_url, TokenEndpointOptions options={})
Create a token source that fetches credentials from endpoint_url.
HTTP options for EndpointTokenSource.
Definition token_source.h:128
std::map< std::string, std::string > headers
Additional request headers.
Definition token_source.h:133
std::string method
HTTP method (default POST).
Definition token_source.h:130
Per-call options sent to configurable token sources (endpoint, sandbox, custom).
Definition token_source.h:68
std::optional< std::string > room_name
Target room name encoded into the token request.
Definition token_source.h:75
std::optional< std::string > participant_identity
Stable participant identity encoded into the JWT.
Definition token_source.h:88
Sandbox (development only)
Uses the LiveKit Cloud sandbox token server. Do not use in production.
auto credentials = source->fetch(request).get();
if (!credentials ||
!room.
connect(credentials.value().server_url, credentials.value().participant_token, options)) {
return 1;
}
static std::unique_ptr< SandboxTokenSource > create(const std::string &sandbox_id, const SandboxTokenServerOptions &options={})
Create a token source backed by the LiveKit Cloud sandbox token server.
std::optional< std::string > agent_name
Name of a registered LiveKit agent to dispatch into the room.
Definition token_source.h:111
See sandbox token server docs.
Custom
Integrate an existing auth system without adopting the standard endpoint wire format:
std::promise<livekit::Result<livekit::TokenSourceResponse, livekit::TokenSourceError>> promise;
promise.set_value(
return promise.get_future();
});
static std::unique_ptr< CustomTokenSource > create(std::function< std::future< Result< TokenSourceResponse, TokenSourceError > >(const TokenRequestOptions &)> provider)
Create a token source that delegates fetching to provider.
Lightweight success-or-error return type for non-exceptional API failures.
Definition result.h:40
Caching
Wraps another configurable source and reuses a cached JWT when options match and the token is still valid. Call invalidate() to drop the cached credentials so the next fetch() re-queries the inner source — useful when calling Room::connect again, not for server-pushed refresh during an active session. cachedResponse() returns the currently cached credentials, if any.
auto credentials = source->fetch(request).get();
if (!credentials ||
!room.
connect(credentials.value().server_url, credentials.value().participant_token, options)) {
return 1;
}
static std::unique_ptr< CachingTokenSource > create(std::unique_ptr< TokenSourceConfigurable > inner)
Wrap inner with JWT-aware caching.
In-session token refresh
During an active session, the LiveKit server may push an updated JWT over the signal connection so the client can reconnect if the original join token expires. The Rust core stores and applies this token automatically.
C++ surfaces an optional notification:
public:
}
};
Interface for receiving room-level events.
Definition room_delegate.h:33
virtual void onTokenRefreshed(Room &, const TokenRefreshedEvent &)
Called when the server refreshes the session access token.
Definition room_delegate.h:146
Fired when the server refreshes the session access token.
Definition room_event_types.h:598
This event is informational. It does not invoke your token source or token endpoint. Automatic reconnect/resume while connected uses the internally stored JWT only.