Mint access tokens
Twilio’s client-side SDKs (Voice, Video, Conversations and Sync) authenticate with Access Tokens: short-lived JWTs your server mints so a browser or phone can talk to Twilio directly, without ever holding your account credentials.
TwilioTokenService mints them.
import { Controller, Get, Query } from '@nestjs/common';import { TwilioTokenService } from 'nestjs-twilio';
@Controller('token')export class TokenController { constructor(private readonly tokens: TwilioTokenService) {}
@Get('voice') voice(@Query('identity') identity: string) { return { token: this.tokens.createVoiceToken({ identity, incomingAllow: true }), }; }}Credentials
Section titled “Credentials”Access Tokens are signed with an API key, never an auth token. The client
you mint from must be registered with apiKey and apiSecret:
TwilioModule.forRoot({ accountSid: process.env.TWILIO_ACCOUNT_SID, apiKey: process.env.TWILIO_API_KEY, // SK… apiSecret: process.env.TWILIO_API_SECRET,});Minting from a client configured with an authToken throws a
BadRequestException naming the client, rather than emitting a JWT that Twilio
would reject once it reached the browser.
Per-product helpers
Section titled “Per-product helpers”| Method | Grant | Key options |
|---|---|---|
createVoiceToken() |
Programmable Voice | incomingAllow, outgoingApplicationSid, outgoingApplicationParams |
createVideoToken() |
Programmable Video | room |
createChatToken() |
Conversations | serviceSid, pushCredentialSid |
createSyncToken() |
Sync | serviceSid |
Every helper accepts the shared JWT settings (identity, ttl, nbf and
region) alongside its grant-specific options.
this.tokens.createVideoToken({ identity: 'alice', room: 'daily-standup' });this.tokens.createChatToken({ identity: 'alice', serviceSid: 'ISxxxxxxxx' });this.tokens.createSyncToken({ identity: 'alice', serviceSid: 'ISxxxxxxxx' });TaskRouter, Playback and multi-grant tokens
Section titled “TaskRouter, Playback and multi-grant tokens”createToken() accepts grants you build yourself. Use it for products without
a dedicated helper, or to put several grants on one token:
import { jwt } from 'twilio';
this.tokens.createToken({ identity: 'alice', grants: [ new jwt.AccessToken.VideoGrant({ room: 'daily-standup' }), new jwt.AccessToken.ChatGrant({ serviceSid: 'ISxxxxxxxx' }), ],});A token with no grants is rejected. It could not access anything.
Named clients
Section titled “Named clients”Pass a client name as the second argument to sign with a named client’s own credentials. Subaccounts carry their own API keys, so a subaccount token must be signed by that subaccount:
this.tokens.createVoiceToken({ identity: 'alice' }, 'billing');Omit the name to use the default client.
Lifetime
Section titled “Lifetime”Tokens default to one hour. Twilio caps them at 24 hours and recommends the shortest lifetime your application can tolerate, since a leaked token is valid until it expires.
this.tokens.createVideoToken({ identity: 'alice', ttl: 600 }); // 10 minutesA ttl above 86400 is rejected at mint time. Twilio would otherwise reject the
token when the client tried to use it, far from the code that set it.
Identities
Section titled “Identities”The identity is how Twilio and your application identify the user, and it is
what other participants see.
Reference
Section titled “Reference”See TwilioTokenOptions for the
shared JWT settings (identity, ttl, nbf, region) every helper
accepts, and the Access Tokens reference
for the full token model.