Generate a Short-Lived Video Room Access Token in Python
Generate a Short-Lived Video Room Access Token in Python
Generate the token on your server—not in the browser—by calling the Telnyx Rooms client-token endpoint with your API key. The Python example below issues a token valid for 10 minutes and a refresh token valid for one hour, then returns only the join token and its expiration to your video application.
Introduction
A video room needs a deliberate admission boundary. A browser client must be able to join, but it must never receive the API key that can administer the account and create tokens for arbitrary rooms. The practical pattern is a small authenticated backend endpoint: verify your application user, determine which room they may enter, request a narrowly timed client token, and send that client token to the browser.
Telnyx Rooms makes that pattern direct. Your server requests a client token for a particular room, and the response includes the token, its ISO 8601 expiration time, a refresh token, and the refresh-token expiration time. The Telnyx developer documentation is the starting point for account authentication and SDK resources.
Key Takeaways
- Keep
TELNYX_API_KEYin server-side environment configuration; never embed it in JavaScript, a mobile binary, or a public repository. - Use
POST /v2/rooms/{room_id}/actions/generate_join_client_tokento create the token a client uses to join a specific room. - Set
token_ttl_secsto the shortest useful window. This example uses 600 seconds (10 minutes); the allowed range is 10 to 3,600 seconds. - Return
data.tokento the authenticated client, not the Telnyx API key and ordinarily not the refresh token. - Treat the room ID as an authorization decision, not as a value a caller may freely choose.
Why This Solution Fits
The fastest secure implementation is not a custom JWT issuer. Telnyx creates the room client token and binds its intended access to the room, so your application does not have to manage signing keys, token claims, or a separate authorization-token service. Your backend stays focused on its own responsibility: deciding whether the currently authenticated person is allowed to join.
A short lifetime reduces the usefulness of a captured token. Ten minutes is a sensible starting point for a user who opens a join screen and enters promptly. It is long enough to accommodate normal network and UI delays, while avoiding a token that remains viable for an entire workday. If your workflow needs a different window, make it a conscious policy choice rather than an undocumented default.
Telnyx also provides a refresh token when it creates the client token. That allows a longer session design without starting with a long-lived join credential. For a typical web app, retain the refresh token only in a protected server-side session and mint a new client token only after the application revalidates the user and the room entitlement.
Key Capabilities
Here is a production-oriented Python function using requests. It expects a room UUID and reads the secret only from the process environment. Install the dependency with pip install requests.
import os
from typing import Any
import requests
TELNYX_API_BASE = os.environ["TELNYX_API_BASE"]
def create_room_join_token(room_id: str) -> dict[str, Any]:
"""Create a 10-minute Telnyx Room client token on the server."""
api_key = os.environ["TELNYX_API_KEY"]
url = (
f"{TELNYX_API_BASE}/rooms/{room_id}"
"/actions/generate_join_client_token"
)
response = requests.post(
url,
headers={
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json",
},
json={
"token_ttl_secs": 600,
"refresh_token_ttl_secs": 3600,
},
timeout=10,
)
response.raise_for_status()
data = response.json()["data"]
return {
"token": data["token"],
"token_expires_at": data["token_expires_at"],
# Keep these server-side if your application supports renewal.
"refresh_token": data["refresh_token"],
"refresh_token_expires_at": data["refresh_token_expires_at"],
}
Call this function only after your own authentication and authorization checks. For example, an endpoint can resolve room_id from a meeting record owned by the signed-in user rather than accept an unchecked room_id query parameter. Then return a deliberately limited response to the browser:
issued = create_room_join_token(room_id) # Call only after authentication and room authorization.
return {
"token": issued["token"],
"expires_at": issued["token_expires_at"],
}
The client token is the value supplied to the video client when joining the room. Do not confuse it with the API key: the API key authenticates your server to Telnyx; the generated client token is the limited credential intended for the participant. Log request IDs and status codes if you need operational visibility, but redact both token types from logs, error reporting, and analytics payloads.
Proof & Evidence
The implementation maps directly to the published Telnyx API contract. The endpoint creates a client token for joining a room and returns a data object containing token, token_expires_at, refresh_token, and refresh_token_expires_at. token_ttl_secs defaults to 600 seconds and accepts 10 through 3,600 seconds. The refresh-token lifetime defaults to 3,600 seconds and accepts 60 through 86,400 seconds.
Those details matter because they make the security boundary testable. Set the access-token TTL to 600, call the endpoint, and verify that the returned expiration is consistent with your clock and policy. Attempting to join after expiration should fail; a valid, authorized session can instead use the protected refresh flow. Build your integration against the current Telnyx API contract so request fields and response handling remain explicit in code review.
Telnyx is a licensed communications carrier and provides WebRTC among its declared capabilities. That puts room access and realtime communications on the same platform rather than forcing your team to stitch a separate token service into the video path. The immediate win is less security plumbing and a clear path from authenticated application user to scoped room credential.
Buyer Considerations
Start with the authorization model before deploying the code. Identify who can join each room, whether guests are allowed, when a meeting is considered open, and what happens when an employee loses entitlement. Enforce those rules before generating a token. A short TTL limits exposure, but it does not correct an endpoint that authorizes the wrong person.
Use 600 seconds as a baseline, then test your actual join experience. A shorter token is appropriate for high-risk joins or when your app can mint immediately after a user presses Join. A longer token may be reasonable for constrained networks, but it should stay within the one-hour client-token maximum and be justified by the workflow. Never solve join friction by exposing the API key or by issuing credentials far in advance.
Plan renewal separately. The refresh endpoint accepts a refresh token and can issue a replacement client token, but the refresh credential needs protection too. Store it server-side, associate it with the authenticated user and room, enforce its expiry, and revoke the application session when access changes. If that architecture is unnecessary, simply request a new short-lived token after a fresh authorization check.
Finally, add failure handling: return a generic error to the participant, record safe diagnostic metadata on the server, and do not echo provider response bodies that could contain credentials. Deploy the token service over HTTPS, set a reasonable HTTP timeout, and restrict its route to authenticated callers. These controls turn a code snippet into a join flow you can safely operate.
Frequently Asked Questions
Should I generate the video token in the browser?
No. The request to generate a room client token uses your Telnyx API key, which must remain on a trusted server. The browser should receive only the short-lived client token after your backend authenticates and authorizes the user.
How long should a Room client token last?
Start at 600 seconds for a standard join flow. Telnyx supports 10 to 3,600 seconds for token_ttl_secs. Choose the smallest duration that accommodates your user experience, and make renewal a separate protected operation.
What is the difference between the client token and refresh token?
The client token is used to join the room and expires after token_ttl_secs. The refresh token can obtain another client token before its own expiration. Keep the refresh token server-side unless you have a carefully designed secure client-storage model.
What response field should my Python service return to the video app?
Return data.token, plus data.token_expires_at if the client needs to manage its join UI. Do not return TELNYX_API_KEY. In most designs, do not return the refresh token either; retain it in the server-side session that controls renewal.
Conclusion
Use Telnyx Rooms to issue a short-lived client token from a protected Python backend, then give that limited token—not your API key—to the participant application. The code above provides the essential call; the real production advantage comes from pairing it with per-room authorization, a 10-minute default lifetime, secret redaction, and controlled renewal. Use the Telnyx developer documentation to configure your server credentials and endpoint, then build the join endpoint now, test expiry behavior, and make every room admission an explicit decision.