Skip to content

Authentication

Every request to the Tele API carries a JWT signed by your backend with your API secret:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9…

There are two kinds of token:

User token Service token
Acts as One of your users (sub) Your backend
Used by Your web and mobile apps Your backend only
Max lifetime 1 hour 10 minutes
Can Create calls as host, preview invites, join, read and post chat in their calls Everything for your consumer: manage any call, join on a user's behalf, read sessions and usage

Never ship your API secret

The secret signs tokens. Anyone who has it can act as any of your users and run up usage on your account. Keep it on your backend. Apps should ask your backend for a user token.

Token format

HS256 JWT, signed with your API secret as the HMAC key (the secret string, UTF-8):

{
  "iss": "TK3f9QpX2mLk8VbN0aZr",
  "sub": "user-123",
  "iat": 1760000000,
  "nbf": 1760000000,
  "exp": 1760000900,
  "name": "Rahim Uddin",
  "team": "sales",
  "tele": { "scope": "user" }
}
Claim Required Notes
iss yes Your API key.
exp yes At most 1 h (user) or 10 min (service) after now.
tele.scope yes "user" or "service".
sub user tokens Your user_id, ≤128 characters. Service tokens omit it.
iat, nbf recommended If iat is present, exp − iat must also respect the lifetime limit.
name no Display name, ≤64 characters. Updates the stored name when present.
team no Billing attribution, ≤64 characters. Updates the stored team when present.

Tele allows 30 seconds of clock skew. Algorithms other than HS256, including none, are rejected.

Signers

import "github.com/cloudguys-io/tele-go/teletoken" // go get github.com/cloudguys-io/tele-go@v0.2.0

signer := teletoken.Signer{APIKey: key, APISecret: secret}

userTok, err := signer.UserToken(teletoken.User{ID: "user-123", Name: "Rahim", Team: "sales"}, 15*time.Minute)
svcTok, err := signer.ServiceToken(5 * time.Minute)
import { TeleSigner } from "@tele/node"; // zero dependencies, Node ≥ 23.6

const signer = new TeleSigner({ apiKey, apiSecret });
const userTok = signer.userToken({ id: "user-123", name: "Rahim", team: "sales" }, 900); // seconds
const svcTok = signer.serviceToken(300);
from tele_fastapi import TeleSigner, TeleUser  # pip install "tele-fastapi @ git+https://github.com/cloudguys-io/tele-fastapi@v0.2.0"

signer = TeleSigner(api_key, api_secret)
user_tok = signer.user_token(TeleUser(id="user-123", name="Rahim", team="sales"), ttl=900)  # seconds
svc_tok = signer.service_token(ttl=300)
import time, jwt

now = int(time.time())
token = jwt.encode(
    {"iss": API_KEY, "sub": "user-123", "iat": now, "nbf": now, "exp": now + 900,
     "name": "Rahim", "team": "sales", "tele": {"scope": "user"}},
    API_SECRET, algorithm="HS256")

A token endpoint in your backend

Your apps need a way to get a user token. Add an endpoint behind your own authentication:

// Next.js route handler: app/api/tele-token/route.ts
export async function POST(req: Request) {
  const user = await requireSession(req);          // your auth
  const token = signer.userToken({ id: user.id, name: user.displayName, team: user.department }, 900);
  return Response.json({ token });
}

Apps should treat the token as short-lived. Fetch a fresh one when it expires and whenever they rejoin a call.

Key rotation and revocation

  • You can hold two active keys at once. Deploy the new key, then ask the Tele team to revoke the old one.
  • A revoked key stops working within 30 seconds.