Skip to main content
Daily meeting tokens can be used to set options and permissions for users joining a Daily room. Examples of what a token can grant include:
  • Access to a private room
  • A preset user name
  • Permission to initiate screen sharing or recording
  • Automatic ejection after a set duration

What is a Daily meeting token?

Daily meeting tokens are JSON Web Tokens (JWTs) — strings made up of three base64-encoded parts separated by periods:
  • Header: algorithm and token type
  • Payload: claims like expiry, issue time, and room privileges
  • Signature: the header and payload signed with a secret
The JWT standard is detailed in RFC 7519. An example JWT:
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuYmYiOjE1NDg3MjE1NjksImV4cCI6MTg2NDA4MTUzOCwiciI6ImhlbGxvIiwibyI6dHJ1ZSwic3MiOnRydWUsImVyIjoibG9jYWwiLCJkIjoiMjVkZjUwNTctZWYwZC00ZDk3LWJkZTYtMGNmMjg3Mjc2Y2JiIiwiaWF0IjoxNTQ4NzIxODMxfQ.mvVciAengBR4xCblhFpo4mKYftQv1skYO4Y6IKr9Zgo
The above token decodes to the following JSON payload:
{
  "nbf": 1548721569,
  "exp": 1864081538,
  "r": "hello",
  "o": true,
  "ss": true,
  "er": "local",
  "d": "25df5057-ef0d-4d97-bde6-0cf287276cbb",
  "iat": 1548721831
}
Self-signed tokens use abbreviated field names. See token property abbreviations for the full list.

Getting a Daily meeting token

A Daily meeting token can be obtained either through the REST API, or by self-signing a JWT with your Daily API key.

Via the REST API

Make a POST request to https://api.daily.co/v1/meeting-tokens with your chosen token properties:
# Create a token for the room specified by DAILY_ROOM_NAME, with an expiry of 1 hour.
curl -H "Content-Type: application/json" \
     -H "Authorization: Bearer $DAILY_API_KEY" \
     -XPOST -d \
     '{"properties":{"room_name":"'`expr $DAILY_ROOM_NAME`'","exp":'`expr  $(date +%s) + 3600`'}}' \
     https://api.daily.co/v1/meeting-tokens

Via self-signing

Tokens can also be self-signed using a JWT library. Example using jsonwebtoken:
import * as jwt from 'jsonwebtoken';

function generateMeetingToken() {
  const payload = {
    r: 'daily-room-name',
    d: 'daily-domain-uuid',
  };
  try {
    const token = jwt.sign(payload, DAILY_API_KEY, { expiresIn: '1h' });
    return token;
  } catch (e) {
    throw new Error(`failed to create self-signed JWT: ${e.toString()}`);
  }
}
Refer to token property abbreviations when composing your payload.

Security considerations

We recommend narrowing the scope and lifetime of your token as much as possible:
  • Always set an expiry. A token without exp is valid forever.
  • Specify a room name. A token without r is valid for every room on your domain.
If a Daily-signed token is compromised, the only way to revoke it is to delete the room it was generated for (if you specified one). If a self-signed token is compromised, you can revoke it by regenerating your API key in the Daily dashboard.

Using a Daily meeting token

Pass the token as part of the join() call:
const call = Daily.createCallObject();
call.join({
  token: DAILY_MEETING_TOKEN,
  url: DAILY_ROOM_URL,
});
If a meeting token is invalid, no error is emitted at join time. Privileged operations will simply fail when attempted.

Validating a Daily meeting token

To validate a token via the REST API, make a GET request to https://api.daily.co/v1/meeting-tokens/[DAILY_MEETING_TOKEN]:
curl -H "Content-Type: application/json" \
     -H "Authorization: Bearer $DAILY_API_KEY" \
     https://api.daily.co/v1/meeting-tokens/$DAILY_MEETING_TOKEN
A 200 response includes an object with the token’s properties. If the token is invalid, an error is returned. If you’re using a self-signed token, you can validate claims and signature locally using a JWT library without making an API request.