Your first LiveKit connection

Before we build the agent, let us understand the plumbing. LiveKit organises audio and video streams into rooms. A room is a logical space where participants publish and subscribe to tracks. Your frontend joins a room, your Python agent joins the same room, and LiveKit relays audio between them with sub-second latency.

To join a room, every participant needs an access token. The token is a signed JWT that says who they are and what they can do. Your backend generates tokens using the LiveKit API key and secret. The client uses the token to connect.

router.py
python
from livekit import api
from datetime import timedelta

def create_access_token(room_name: str, identity: str, name: str) -> str:
    token = api.AccessToken(LIVEKIT_API_KEY, LIVEKIT_API_SECRET) \
        .with_identity(identity) \
        .with_name(name) \
        .with_grants(api.VideoGrants(
            room_join=True,
            room=room_name,
            can_publish=True,
            can_subscribe=True,
            can_publish_data=True,
        )) \
        .with_ttl(timedelta(minutes=15))
    return token.to_jwt()

The access token locks the user into one specific room, gives them permission to publish and subscribe to audio, and expires in fifteen minutes. Never expose your API secret to the browser. Mint tokens on the server.

You could, in theory. But you would be writing WebRTC signalling, ICE, TURN servers, and media relays yourself. LiveKit handles all of that and adds recording, multiple participants, and permissions on top. You focus on the agent, not on the transport layer.

Quiz: Quiz

Loading practice…