WebRTC Call Reports
The Telnyx Android SDK automatically collects detailed call statistics during WebRTC calls and sends them to Telnyx for troubleshooting and monitoring purposes. This feature helps diagnose call quality issues, connection problems, and provides insights into call performance.
Overview
When enabled, the SDK collects:
- Call summary: Call identifiers, timestamps, duration, and device information
- Connection metrics: ICE states, DTLS states, signaling transitions
- Media statistics: Packet loss, jitter, round-trip time, audio levels
- Network information: Selected ICE candidates, transport details
The data is automatically uploaded to Telnyx when a call ends, and can also be accessed locally for debugging.
Enabling Call Reports
Call reports are automatically enabled when you connect to the Telnyx WebRTC service. The SDK handles data collection and upload transparently.
Call reports are sent automatically when a call ends. No additional configuration is required.
Accessing Local Call Reports
For debugging purposes, you can access the call report JSON file that is saved locally after each call:
// Get the path to the last generated call stats JSON file
val jsonPath = telnyxClient.getLastCallStatsJsonPath()
// Read and process the JSON file
jsonPath?.let { path ->
val file = File(path)
if (file.exists()) {
val jsonContent = file.readText()
// Process the call stats JSON
}
}
Call stats files are saved to: <cache_dir>/call_stats/call_stats_<callId>.json
Call Report JSON Structure
The call report JSON contains the following sections:
Top-Level Identifiers
{
"call_id": "uuid-of-the-call",
"call_report_id": "report-token-from-server",
"telnyx_leg_id": "uuid-of-telnyx-leg",
"telnyx_session_id": "uuid-of-telnyx-session",
"voice_sdk_id": "websocket-session-id"
}
Summary Section
Contains high-level call information:
{
"summary": {
"callId": "uuid-of-the-call",
"callerNumber": "+1234567890",
"destinationNumber": "+0987654321",
"direction": "outbound",
"durationSeconds": 120.5,
"startTimestamp": "2026-03-23T12:00:00.000Z",
"endTimestamp": "2026-03-23T12:02:00.500Z",
"sdkVersion": "3.5.0",
"state": "done",
"telnyxLegId": "uuid",
"telnyxSessionId": "uuid"
}
}
Stats Array
Contains interval-based statistics captured during the call. Each interval (typically 5 seconds) includes:
{
"stats": [
{
"audio": {
"inbound": {
"bytesReceived": 48000,
"packetsReceived": 500,
"packetsLost": 2,
"packetsDiscarded": 0,
"jitterAvg": 10.5,
"jitterBufferDelay": 50.0,
"concealedSamples": 100,
"concealmentEvents": 1,
"audioLevelAvg": 0.85
},
"outbound": {
"bytesSent": 48000,
"packetsSent": 500,
"audioLevelAvg": 0.78
}
},
"connection": {
"bytesReceived": 50000,
"bytesSent": 50000,
"packetsReceived": 520,
"packetsSent": 520,
"roundTripTimeAvg": 45.2
},
"ice": {
"local": {
"candidateType": "host",
"protocol": "udp",
"address": "192.168.1.100",
"port": 54321
},
"remote": {
"candidateType": "srflx",
"protocol": "udp",
"address": "203.0.113.50",
"port": 12345
},
"nominated": true,
"state": "succeeded"
},
"transport": {
"dtlsState": "connected",
"iceState": "connected",
"srtpCipher": "AEAD_AES_128_GCM",
"tlsVersion": "DTLS 1.2"
},
"intervalStartUtc": "2026-03-23T12:00:00.000Z",
"intervalEndUtc": "2026-03-23T12:00:05.000Z"
}
]
}
Android Extra Section
Contains Android-specific debugging information:
{
"android_extra": {
"deviceInfo": {
"userAgent": "TelnyxAndroidSDK/3.5.0",
"networkType": "WiFi",
"osVersion": "Android 14 (API 34)",
"deviceModel": "Google Pixel 8",
"selectedCodec": "audio/opus",
"permissions": {
"microphone": true,
"notifications": true
}
},
"connectionState": {
"lastIceGatheringState": "complete",
"lastIceConnectionState": "connected",
"lastDtlsState": "connected",
"lastSignalingState": "stable"
},
"connectionTimeline": [
{ "event": "ICE_CHECKING", "timestamp": "2026-03-23T12:00:00.100Z" },
{ "event": "ICE_CONNECTED", "timestamp": "2026-03-23T12:00:00.500Z" },
{ "event": "DTLS_CONNECTING", "timestamp": "2026-03-23T12:00:00.600Z" },
{ "event": "DTLS_CONNECTED", "timestamp": "2026-03-23T12:00:01.200Z" }
],
"iceCandidates": {
"total": 6,
"hostCount": 2,
"srflxCount": 2,
"relayCount": 2
}
}
}
Metrics Reference
Audio Inbound Metrics
| Metric | Description |
|---|
bytesReceived | Total bytes received |
packetsReceived | Total packets received |
packetsLost | Number of lost packets |
packetsDiscarded | Packets discarded by jitter buffer |
jitterAvg | Average jitter in milliseconds |
jitterBufferDelay | Jitter buffer delay in milliseconds |
concealedSamples | Number of concealed audio samples |
concealmentEvents | Number of concealment events |
audioLevelAvg | Average audio level (0.0 to 1.0) |
Audio Outbound Metrics
| Metric | Description |
|---|
bytesSent | Total bytes sent |
packetsSent | Total packets sent |
audioLevelAvg | Average outgoing audio level (0.0 to 1.0) |
Connection Metrics
| Metric | Description |
|---|
roundTripTimeAvg | Average round-trip time in milliseconds |
bytesReceived | Total transport bytes received |
bytesSent | Total transport bytes sent |
Troubleshooting with Call Reports
Call reports can help diagnose common issues:
High Packet Loss
Look at packetsLost in the audio inbound stats. Values above 1-2% may indicate network issues.
Audio Quality Issues
Check jitterAvg and concealmentEvents. High jitter (>30ms) or frequent concealment events indicate audio quality degradation.
Connection Failures
Review the connectionTimeline in android_extra. Look for:
ICE_FAILED - Network connectivity issues
DTLS_FAILED - TLS/security handshake failures
- Long gaps between
ICE_CONNECTED and DTLS_CONNECTED (>5 seconds)
One-Way Audio
Check if:
packetsReceived is 0 (not receiving audio)
audioLevelAvg is 0 (microphone not capturing)
- Review microphone permissions in
deviceInfo.permissions
Privacy & Data Handling
Call reports are sent securely to Telnyx and are used solely for:
- Troubleshooting call quality issues
- Monitoring service health
- Improving SDK performance
Call reports do not include actual audio content or personally identifiable information beyond call metadata.
See Also