Skip to main content

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.

Debug Data & Call Quality Analysis

When calls have quality issues, the Telnyx WebRTC JS SDK provides multiple tools to diagnose the problem. This guide covers collecting debug data, interpreting results, and common troubleshooting patterns.

Data Collection Methods

MethodWhen to UseData Available
Call ReportsProduction monitoringRTT, jitter, packet loss, ICE state, audio levels
Debug ReportsDeep troubleshootingFull WebRTC stats, SDP, ICE candidates, timestamps
Console DebugDevelopmentSDK internal logs, WebSocket messages
Debug VisualizerVisual analysisCharts of call quality over time

Method 1: Call Reports (Production)

Enable call reports for production quality monitoring:
const client = new TelnyxRTC({
  login_token: jwt,
  enableCallReports: true,
  callReportInterval: 5000,
});
See Monitor Call Quality for the full guide.

Method 2: Debug Reports (Deep Troubleshooting)

Enable debug output for detailed troubleshooting data. Use debug: true with debugOutput to control where the data goes:
const client = new TelnyxRTC({
  login_token: jwt,
  enableCallReports: true,  // Collect call stats
  debug: true,              // Enable debug mode
  debugOutput: 'file',      // Write debug data to a file
});
Debug data includes:
  • Full ICE candidate list with timestamps
  • DTLS handshake state
  • SDP offer/answer with codec negotiation
  • Packet-level stats (bytes, packets, loss per direction)
  • Audio level measurements

Accessing debug data

Call report data is available via the Call Report Stats API after the call ends:
curl "http://voice-sdk-call-report-stats.query.prod.telnyx.io:4000/api/v1/calls/{user_id}/{call_id}"

Interpreting debug data

Key sections to check:
SectionWhat to Look For
ice_data.transportDTLS state, ICE state, SRTP cipher
ice_data.selected_pairWhich candidate pair is in use (host/srflx/relay)
ice_data.candidatesAll gathered candidates with timestamps
segmentsPeriodic RTT, jitter, packet loss measurements

Method 3: Console Debug (Development)

Enable debug: true to get verbose SDK logging in the browser console:
const client = new TelnyxRTC({
  login_token: jwt,
  debug: true,
});
This outputs SDK internal logs (WebSocket messages, ICE events, signaling) to the browser console. No additional configuration needed — debug: true enables console logging by default.

Method 4: Debug Visualizer

Send debug output to the Telnyx debug visualizer for graphical analysis:
const client = new TelnyxRTC({
  login_token: jwt,
  debug: true,
  debugOutput: 'socket',  // Send to visualizer
});
Open https://webrtc-debug.telnyx.com/ in another tab to see the live visualization. The visualizer shows:
  • Call timeline with state transitions
  • ICE candidate gathering progress
  • DTLS handshake status
  • Audio quality graphs (RTT, jitter, packet loss)
  • Media flow direction

Common Issues & Diagnosis

One-Way Audio

Check:
  1. Is DTLS connected? → ice_data.transport.dtls_state === "connected"
  2. Is audio being sent? → Check bytesSent in stats
  3. Is audio being received? → Check bytesReceived in stats
  4. Which candidate type? → ice_data.selected_pair shows host/srflx/relay
Common causes:
  • Asymmetric TURN relay (two nominated candidate pairs, one sending and one receiving)
  • Firewall blocks media in one direction
  • VPN interferes with ICE candidates
Diagnosis from debug data:
If dtls_state: "connecting" and ice_state: "connected"
→ DTLS handshake failing. Check for multiple NICs or asymmetric routing.

If bytesSent > 0 but bytesReceived = 0
→ Audio is being sent but not received. Check remote firewall.

If bytesSent = 0 and bytesReceived > 0
→ Audio is being received but not sent. Check local microphone permissions.

Call Doesn’t Connect

Check:
  1. WebSocket state → client.connection.connected
  2. ICE state → ice_data.transport.ice_state
  3. STUN accessibility → Any srflx candidates?
Common causes:
  • Firewall blocks rtc.telnyx.com:443 (signaling)
  • Firewall blocks stun.telnyx.com:3478 (STUN)
  • Firewall blocks turn.telnyx.com:443 (TURN)
  • No relay candidates and symmetric NAT

Choppy Audio

Check:
  1. Jitter → stats.jitter > 50ms is poor
  2. Packet loss → stats.packetLoss > 3% is poor
  3. RTT → stats.rtt > 300ms is poor
Common causes:
  • WiFi congestion (high jitter)
  • Network congestion (high packet loss)
  • Long routing path (high RTT)
  • VPN adding latency

Echo

Common causes:
  • Built-in speakers + mic without echo cancellation
  • Two audio elements playing the same stream
  • Headset echo cancellation not working
Fix:
  • Recommend headphones
  • Ensure only one audio element is active per call
  • Check browser echo cancellation settings

Quick Diagnostic Script

Run this in the browser console during a problematic call:
(async () => {
  const client = window.__telnyxClient; // Your client instance
  const calls = client.calls;

  console.log('=== Telnyx Call Diagnostic ===');
  console.log(`Active calls: ${calls.length}`);
  console.log(`Connected: ${client.connection.connected}`);

  for (const call of calls) {
    console.log(`
Call ${call.id}: state=${call.state}, direction=${call.direction}`);
    console.log(`  Remote: ${call.remotePartyNumber}`);

    const pc = call.peerConnection;
    if (pc) {
      const stats = await pc.getStats();
      stats.forEach(report => {
        if (report.type === 'candidate-pair' && report.nominated) {
          console.log(`  ICE: state=${report.state}, RTT=${report.currentRoundTripTime * 1000}ms`);
        }
        if (report.type === 'inbound-rtp' && report.kind === 'audio') {
          console.log(`  Audio In: packets=${report.packetsReceived}, lost=${report.packetsLost}, jitter=${report.jitter}`);
        }
        if (report.type === 'outbound-rtp' && report.kind === 'audio') {
          console.log(`  Audio Out: packets=${report.packetsSent}`);
        }
      });
    }
  }
})();

See Also