Documentation Index
Fetch the complete documentation index at: https://developers.telnyx.com/llms.txt
Use this file to discover all available pages before exploring further.
Reconnection & Call Recovery
Network interruptions happen — Wi-Fi drops, VPNs reconnect, laptops sleep. The Telnyx WebRTC JS SDK automatically handles reconnection so your users experience minimal disruption.
How Reconnection Works
When the WebSocket connection to rtc.telnyx.com drops:
- SDK detects the disconnect via WebSocket
close or error event
- SDK attempts reconnection with exponential backoff (1s, 2s, 4s, 8s, 16s, 32s…)
- On successful reconnect, the SDK re-authenticates and re-attaches to existing calls
- If reconnection fails after exhausting retries, the
RECONNECTION_EXHAUSTED error is emitted
No manual intervention required. The SDK handles this automatically.
When Calls Survive Reconnection
Calls can survive a brief WebSocket disconnect if:
| Condition | Required |
|---|
Call was in active state | |
keepConnectionAliveOnSocketClose is true | |
| PeerConnection is still alive | |
| Reconnect happens within timeout | |
Configuration:
const client = new TelnyxRTC({
login_token: jwt,
keepConnectionAliveOnSocketClose: true, // Keep PeerConnection alive
});
When keepConnectionAliveOnSocketClose is enabled:
- The PeerConnection (WebRTC media) stays alive even when the WebSocket (signaling) drops
- Audio continues flowing during the reconnection attempt
- On reconnect, the SDK re-attaches the existing call to the new WebSocket
- The call ID may change — use
recoveredCallId to correlate
recoveredCallId
After a successful reconnection, the call may have a new ID. The previous ID is available as recoveredCallId:
client.on('telnyx.notification', (notification) => {
if (notification.type === 'callUpdate') {
const call = notification.call;
if (call.recoveredCallId) {
console.log(`Call ${call.recoveredCallId} recovered as ${call.id}`);
}
}
});
When Calls Don’t Survive
| Scenario | Why |
|---|
Call was in ringing or requesting state | Not yet fully established |
keepConnectionAliveOnSocketClose is false (default) | PeerConnection closed immediately |
| Reconnect took too long | PeerConnection timed out |
| Network changed completely | DTLS fingerprint no longer matches |
When a call doesn’t survive reconnection, the SDK emits a hangup state for that call.
Handling Reconnection in Your UI
Show reconnection status
let isReconnecting = false;
client.on('telnyx.socket.close', () => {
isReconnecting = true;
showReconnectingBanner();
});
client.on('telnyx.ready', () => {
if (isReconnecting) {
isReconnecting = false;
hideReconnectingBanner();
}
});
client.on('telnyx.error', (error) => {
if (error.code === TELNYX_ERROR_CODES.RECONNECTION_EXHAUSTED) {
showDisconnectedMessage();
}
});
Handle recovered calls
client.on('telnyx.notification', (notification) => {
if (notification.type === 'callUpdate') {
const call = notification.call;
if (call.recoveredCallId) {
// Update your UI state to use the new call ID
updateCallInUI(call.recoveredCallId, call.id);
}
}
});
Inbound Calls After Reconnection
After a WebSocket reconnect, the browser may need to re-acquire microphone permissions to receive inbound calls. This is a browser security requirement, not an SDK limitation.
Handle microphone permission failures for inbound calls with a recoverable error pattern. When enabled and getUserMedia fails while answering, the SDK emits a recoverable telnyx.error event with resume() and reject() callbacks so your app can prompt the user to fix permissions before the call fails:
import { TelnyxRTC, isMediaRecoveryErrorEvent } from '@telnyx/webrtc';
const client = new TelnyxRTC({
login_token: jwt,
mediaPermissionsRecovery: {
enabled: true,
timeout: 20000, // Wait up to 20s for user to fix permissions
onSuccess: () => console.log('Media recovered'),
onError: (err) => console.error('Recovery failed', err),
},
});
client.on('telnyx.error', (event) => {
if (isMediaRecoveryErrorEvent(event)) {
showPermissionDialog({
onContinue: () => event.resume(),
onCancel: () => event.reject?.(),
});
}
});
How it works:
- An inbound call arrives and the user tries to answer
getUserMedia() fails (permission denied, device busy, etc.)
- Instead of immediately failing the call, SDK emits a recoverable error with
resume() and reject() callbacks
- Your app shows a UI prompting the user to grant permissions
- If the user fixes permissions and you call
resume(), the SDK retries getUserMedia()
- If the user declines or
timeout expires, the call is terminated
mediaPermissionsRecovery only works for inbound calls. Recovery is attempted only when the initial getUserMedia call fails while answering.
Explicit Disconnect
When a user intentionally disconnects (e.g., signs out), you want to prevent automatic reconnection:
// Bad — may auto-reconnect
client.disconnect();
// Good — prevent auto-reconnect
client.clearReconnectToken();
client.disconnect();
clearReconnectToken() removes the session token that the SDK uses for automatic reconnection. After calling it, the SDK will not attempt to reconnect.
Common Issues
Rapid reconnection loops
Symptom: WebSocket connects and immediately disconnects, repeating rapidly.
Cause: Usually an authentication issue — the JWT has expired or the credential has been revoked.
Fix:
- Check that the JWT is still valid
- Verify the credential still exists in the Telnyx Portal
- Check for
telnyx.error events with AUTH_FAILED code
RECONNECTION_EXHAUSTED
Symptom: SDK stops trying to reconnect after multiple failures.
Cause: All reconnection attempts have been exhausted (exponential backoff capped).
Fix:
- Check network connectivity
- Verify
rtc.telnyx.com is reachable
- Offer a manual “Reconnect” button in the UI:
client.on('telnyx.error', (error) => {
if (error.code === TELNYX_ERROR_CODES.RECONNECTION_EXHAUSTED) {
showManualReconnectButton();
}
});
// Manual reconnect
reconnectButton.addEventListener('click', () => {
client.connect();
});
Calls die after network change (Wi-Fi → Cellular)
Symptom: Call drops when switching networks, even with keepConnectionAliveOnSocketClose.
Cause: The PeerConnection’s ICE candidates are tied to the old network. The new network has different candidates that weren’t part of the original negotiation.
Fix: This is a WebRTC limitation. The SDK attempts ICE restart, but it may not always succeed. The user will need to place a new call.
Configuration Summary
| Option | Location | Default | Description |
|---|
keepConnectionAliveOnSocketClose | IClientOptions | false | Keep PeerConnection alive during WebSocket reconnect |
mediaPermissionsRecovery | IClientOptions | — | Auto-recover media permissions for inbound calls |
clearReconnectToken() | TelnyxRTC method | — | Prevent auto-reconnection on disconnect |
See Also