Skip to content
View as Markdown

The dialer session

ProjectBlueDialer is one calling session for one line. Create it with a tokenProvider, call start(), and keep it alive for as long as the user can place or receive calls.

On this page

Options

tokenProvider() => Promise<TokenResponse | ErrorBody | string>Required
Called whenever the SDK needs a token: at start(), before expiry, and before a token's call limit is reached. Must call your own server. Return the mint response body as-is (recommended), or just the token string. To surface a refusal, throw mintErrorFromResponse(status, body) — or return the error body with its HTTP status added.
refreshLeadSecondsnumberdefault: 60
Refresh the token this many seconds before it expires. Minimum 5. Tokens live 15 minutes, so keep it well under that.
loggerconsole-like | nulldefault: console (warn/error only)
Where the SDK logs. Pass an object with debug/info/warn/error, or null to silence it entirely.
edgestring | string[]
Preferred media region, e.g. "ashburn" or ["ashburn", "roaming"]. Leave unset unless you have measured a reason to pin one.
playIncomingRingtonebooleandefault: true
Play a ringtone in the browser when an inbound call arrives. Set false to render your own.

Writing the tokenProvider

It runs whenever the SDK needs a token: at start(), about a minute before the current token expires, and before a token has been used for its tenth call. It must call your server, never the mint directly.

Return the mint body unchanged. To report a refusal, throw mintErrorFromResponse(res.status, body) — it returns null on a 2xx and the matching typed error otherwise, so the three-line pattern in the rail is the whole thing. If you would rather return the error body, add status to it first; without it the SDK reports 402 for a cap refusal and 400 for everything else.

Methods

Method
Returns
Notes
start()
Promise<void>
Fetches the first token and connects. Resolves once calls can be placed. Calling it twice is a no-op.
call(to)
Promise<DialerCall>
Places an outbound call. to must be E.164 with the leading +; spaces, dashes and parentheses are stripped, but a country code is never guessed. One call at a time — a second call() while one is active throws invalid_state.
refreshToken()
Promise<void>
Forces a refresh now. Usually unnecessary; concurrent calls share one in-flight refresh.
destroy()
Promise<void>
Hangs up any call, stops refreshing, releases the microphone, and removes all listeners. Idempotent. Call it on logout or unmount.
isReady()
boolean
Started, not destroyed, and holding a token.

Getters

Property
Type
Notes
allowance
DialerAllowance | null
The latest allowance the server sent with a token. Null before start().
inboundEnabled
boolean
Whether the current token lets this session receive calls.
activeCall
DialerCall | null
The call in progress, if any.

Events

Subscribe with dialer.on(event, handler); off and once work the same way.

Event
Payload
When
ready
{ inboundEnabled }
Calls can be placed. Fires again after every successful token refresh, with the current inbound state.
allowance
DialerAllowance
A fresh allowance arrived with a token. Warn users on state: "soft".
capReached
DialerCapReachedError
The workspace or line hit its cap. No new tokens until periodEnd; a call in progress continues.
incoming
DialerCall
Someone is calling the line this session is scoped to. Call accept() or reject().
tokenRefreshFailed
DialerError
A background refresh failed. The session keeps its current token until it expires and retries with backoff.
error
DialerError
Session-level error, e.g. inbound registration failed. Calls carry their own error events.
destroyed
—
destroy() completed.

Token refresh, in detail

You never manage tokens directly, but knowing the schedule explains what your server will see. The session refreshes 60 seconds before expiry by default, immediately before the call that would exceed maxCallsPerToken, and whenever the voice service reports the token invalid. A failed refresh emits tokenRefreshFailed and retries after 5, 15, then 45 seconds; the current token keeps working until it expires.

A cap_reached refusal is different: the session emits capReached, stops retrying, and wakes itself one second after periodEnd. A call that is already up is never cut off — caps apply at mint time only.

API reference