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.
Error Handling
The SDK exposes error-related behavior through three main channels:
| Event | Purpose | Recommended use |
|---|
telnyx.error | Fatal or blocking SDK errors | Show actionable errors, retry, re-authenticate |
telnyx.warning | Non-fatal quality, connectivity, and token warnings | Show degraded-state UI, collect telemetry |
telnyx.notification | Call lifecycle updates and compatibility notifications | Drive call UI and hangup handling |
Use telnyx.ready to know when the client is authenticated and the gateway is ready. Do not treat readiness as a notification case.
Structured Errors (telnyx.error)
telnyx.error is the primary error surface. Listen for it to handle authentication failures, media errors, and connection issues.
Imports
import {
SwEvent,
TelnyxError,
TELNYX_ERROR_CODES,
isMediaRecoveryErrorEvent,
} from '@telnyx/webrtc';
Basic example
client.on(SwEvent.Error, (event) => {
if (isMediaRecoveryErrorEvent(event)) {
openPermissionsDialog({
deadline: event.retryDeadline,
onRetry: () => event.resume(),
onCancel: () => event.reject(),
});
return;
}
if (!(event.error instanceof TelnyxError)) {
showErrorMessage('An unknown SDK error occurred.');
return;
}
switch (event.error.code) {
case TELNYX_ERROR_CODES.NETWORK_OFFLINE:
showErrorMessage('You appear to be offline.');
break;
case TELNYX_ERROR_CODES.AUTHENTICATION_REQUIRED:
showErrorMessage('Session expired. Please authenticate again.');
break;
default:
showErrorMessage(event.error.message);
}
});
When mediaPermissionsRecovery.enabled is configured and getUserMedia() fails while answering a call, the error event includes recoverable: true with resume() and reject() callbacks:
const client = new TelnyxRTC({
login_token: jwt,
mediaPermissionsRecovery: {
enabled: true,
timeout: 10000,
},
});
client.on(SwEvent.Error, (event) => {
if (isMediaRecoveryErrorEvent(event)) {
// Show a dialog asking the user to grant microphone permission
// event.retryDeadline is the timestamp by which they must act
showPermissionDialog({
onGrant: () => event.resume(),
onDismiss: () => event.reject(),
});
}
});
Error Code Reference
SDP errors
| Code | Name | Typical trigger |
|---|
40001 | SDP_CREATE_OFFER_FAILED | createOffer() failed |
40002 | SDP_CREATE_ANSWER_FAILED | createAnswer() failed |
40003 | SDP_SET_LOCAL_DESCRIPTION_FAILED | setLocalDescription() failed |
40004 | SDP_SET_REMOTE_DESCRIPTION_FAILED | setRemoteDescription() failed |
40005 | SDP_SEND_FAILED | Invite/answer signaling could not be sent |
| Code | Name | Typical trigger |
|---|
42001 | MEDIA_MICROPHONE_PERMISSION_DENIED | Browser or OS denied microphone permission |
42002 | MEDIA_DEVICE_NOT_FOUND | Missing/disconnected device or invalid deviceId |
42003 | MEDIA_GET_USER_MEDIA_FAILED | getUserMedia() failed for another reason |
Call-control errors
| Code | Name | Typical trigger |
|---|
44001 | HOLD_FAILED | Hold request failed |
44002 | INVALID_CALL_PARAMETERS | Required call params were missing or invalid |
44003 | BYE_SEND_FAILED | BYE could not be sent |
44004 | SUBSCRIBE_FAILED | Verto subscribe failed |
WebSocket and transport errors
| Code | Name | Typical trigger |
|---|
45001 | WEBSOCKET_CONNECTION_FAILED | WebSocket connection failed |
45002 | WEBSOCKET_ERROR | Browser ws.onerror fired |
45003 | RECONNECTION_EXHAUSTED | Reconnect attempts exhausted |
45004 | GATEWAY_FAILED | Gateway reported FAILED or FAIL_WAIT |
Authentication and session errors
| Code | Name | Typical trigger |
|---|
46001 | LOGIN_FAILED | Login rejected or never reached ready state |
46002 | INVALID_CREDENTIALS | Client-side login validation failed |
46003 | AUTHENTICATION_REQUIRED | Request sent before auth or after auth was lost |
48001 | NETWORK_OFFLINE | Browser offline event fired |
49001 | UNEXPECTED_ERROR | Unclassified failure during peer/call setup |
Structured Warnings (telnyx.warning)
Warnings are not fatal. They describe degraded behavior, quality issues, or situations that may need user action before the session breaks.
Basic example
import { SwEvent, TELNYX_WARNING_CODES } from '@telnyx/webrtc';
client.on(SwEvent.Warning, ({ warning, callId }) => {
if (warning.code === TELNYX_WARNING_CODES.TOKEN_EXPIRING_SOON) {
refreshToken();
return;
}
if (warning.code === TELNYX_WARNING_CODES.PEER_CONNECTION_FAILED) {
showWarningBanner('Call is reconnecting');
return;
}
console.warn(`[${warning.code}] ${warning.name}: ${warning.message}`);
});
Warning code reference
Network quality warnings
| Code | Name | Typical trigger |
|---|
31001 | HIGH_RTT | RTT stayed above threshold |
31002 | HIGH_JITTER | Jitter stayed above threshold |
31003 | HIGH_PACKET_LOSS | Packet loss stayed above threshold |
31004 | LOW_MOS | MOS stayed below threshold |
Data-flow warnings
| Code | Name | Typical trigger |
|---|
32001 | LOW_BYTES_RECEIVED | Remote audio bytes stopped increasing |
32002 | LOW_BYTES_SENT | Local audio bytes stopped increasing |
Connectivity warnings
| Code | Name | Typical trigger |
|---|
33001 | ICE_CONNECTIVITY_LOST | ICE connection state became disconnected |
33002 | ICE_GATHERING_TIMEOUT | ICE gathering safety timeout fired |
33003 | ICE_GATHERING_EMPTY | No candidates were collected |
33004 | PEER_CONNECTION_FAILED | Peer connection state became failed |
33005 | ONLY_HOST_ICE_CANDIDATES | SDP contained only host ICE candidates |
Authentication and session warnings
| Code | Name | Typical trigger |
|---|
34001 | TOKEN_EXPIRING_SOON | JWT expires within 120 seconds |
35001 | SESSION_NOT_REATTACHED | Active call lost after reconnect |
Call Termination Data
When a call reaches hangup, inspect these fields on the Call object:
| Field | Type | Meaning |
|---|
cause | string | High-level cause (USER_BUSY, CALL_REJECTED, etc.) |
causeCode | number | Numeric cause code |
sipCode | number | SIP response code when available |
sipReason | string | SIP reason phrase when available |
Common causes:
| Cause | Meaning |
|---|
NORMAL_CLEARING | Expected call completion |
USER_BUSY | Remote party was busy |
CALL_REJECTED | Remote party rejected the call |
NO_ANSWER | Call timed out unanswered |
UNALLOCATED_NUMBER | Dialed number is invalid or does not exist |
Socket Events
telnyx.socket.close
Delivers the browser CloseEvent. During a forced safety cleanup, the SDK emits a synthetic abnormal close with code: 1006 and wasClean: false.
Useful close codes:
| Code | Meaning |
|---|
1000 | Normal closure |
1001 | Going away |
1006 | Abnormal closure |
1011 | Internal error |
telnyx.socket.error
Delivers { error: ErrorEvent, sessionId: string }. Browsers expose very little information for WebSocket errors. The SDK also emits telnyx.error with code 45002 (WEBSOCKET_ERROR) when ws.onerror fires.
Connection State Helpers
The browser session exposes WebSocket state helpers on client.connection:
| Getter | Meaning |
|---|
client.connection.connected | WebSocket is in OPEN |
client.connection.isAlive | CONNECTING or OPEN |
client.connection.isDead | CLOSING or CLOSED |
Example:
const placeCall = (destinationNumber) => {
if (!client.connection.connected) {
showErrorMessage('Still connecting to Telnyx. Please try again shortly.');
return;
}
client.newCall({ destinationNumber });
};
Reconnection Behavior
On telnyx.socket.close or telnyx.socket.error, the SDK clears subscriptions and resets gateway readiness state. If autoReconnect is enabled, the browser session schedules connect() after reconnectDelay (1000ms).
Gateway retry behavior
- UNREGED / NOREG: Up to 5 registration retries, each delayed 2-6 seconds randomly. After that,
LOGIN_FAILED (46001).
- FAILED / FAIL_WAIT:
GATEWAY_FAILED (45004) emitted on first detection. Up to 5 retries with 2-6 second random delay before RECONNECTION_EXHAUSTED (45003).
If keepConnectionAliveOnSocketClose is true, the SDK preserves active peer connections while signaling reconnects. Recovery can create a new Call object with recoveredCallId.
See Also