Returns the full per-leg audio quality analysis of a single call. This backs the per-call view in the portal, where support can see which party had the problem and in which direction.
Scope, verdicts, finding codes and thresholds are described on Call audio quality.
| URL | https://api.telecomx.dk/pbx/cdr/CDR-ID/quality | ||
|---|---|---|---|
| Method | GET | ||
| Access level | ADMIN, or RESELLER_ADMIN with the TELE employee feature. TX staff only - see Call audio quality. | ||
| Param | CDR-ID | Id | Id of the CDR to analyse (24 hex-char string). |
https://api.telecomx.dk/pbx/cdr/5d035c832d357b369b6f7aff/quality
| JSON object | ||
|---|---|---|
| cdrId | String | Id of the CDR that was analysed. |
| verdict | String | Worst verdict across the calls legs. |
| measured | Boolean | True when at least one leg could be judged. |
| severity | Number | Numeric rank of verdict, for sorting only. |
| reason | String | Why nothing could be judged, when measured is false. Null otherwise. |
| worst | Object | The single worst finding, for a one-line summary. Null when there is nothing to report. |
| legs | Array | One entry per RTP leg. Empty when the call has no usable stats. |
| findings | Array | Leg findings plus the call-level cross-checks, worst first. |
| worst object | ||
|---|---|---|
| code | String | Code of the worst finding. |
| role | String | caller or callee. |
| party | Object | The party it concerns, so a list row can name the phone rather than the role. |
| direction | String | INBOUND or OUTBOUND. |
| percentMissing | Number | Percentage of that partys audio that never reached us, when the finding is delivery- or loss-related. |
| legs[] object | ||
|---|---|---|
| channelId | String | Asterisk channel id. Correlates with syslog and packet captures - technical panel only. |
| role | String | caller (the party who started the call) or callee (a party who was called). |
| party | Object | How to name this party: kind, name, number, model, raw. Identity comes from the CDRs caller/callee - see Call audio quality. |
| source | String | live if the counters were read as the call ended, sampled if this is the newest mid-call sample. |
| mediaSeconds | Number | Seconds of media the counters cover, from when this leg was answered. |
| verdict | String | Worst of this legs directions. |
| measured | Boolean | True when at least one direction of this leg could be judged. |
| reason | String | Why nothing on this leg could be judged, when measured is false. |
| inbound | Object | Their microphone reaching us (see below). Always locally measured, so always meaningful. |
| outbound | Object | What we sent to their speaker (see below). Needs RTCP from the far end to say anything at all. |
| rtt | Number | Round-trip time in seconds, when the far end reported usable RTCP timestamps. Null otherwise. |
| rttVerdict | String | Verdict for the round-trip time, NOT_MEASURED when no usable RTT was reported. |
| findings | Array | Findings for this leg. |
| inbound / outbound object | ||
|---|---|---|
| measured | Boolean | True when this direction could be judged. False means unknown, not OK. |
| reason | String | Why it could not be judged, when measured is false. |
| verdict | String | Verdict for this direction alone. |
| pps | Number | Packets per second actually observed. Display only. |
| referencePps | Number | Packets per second of this legs own outbound stream. Inbound only - the reference the delivery ratio is measured against, never a quality signal in itself. |
| deliveryRatio | Number | Inbound packets divided by this legs own outbound packets. About 1.0 is healthy, about 0.5 is every second frame, 0 is dead. |
| lossRatio | Number | Fraction of packets lost. |
| jitter | Number | Jitter in seconds. |
| mes | Number | Media Experience Score, 0-100, higher is better. |
| findings[] object | ||
|---|---|---|
| code | String | Machine-readable finding code. |
| verdict | String | How serious this observation is. |
| channelId | String | Which leg it concerns. Null for call-level findings. |
| role | String | Role of that leg. Null for call-level findings. |
| direction | String | INBOUND or OUTBOUND. Null when not direction-specific. |
| values | Object | The measured values behind the finding, so the caller can phrase it in the users language. |
{ "cdrId": "5d035c832d357b369b6f7aff", "verdict": "DEGRADED", "measured": true, "severity": 2, "reason": null, "worst": { "code": "INBOUND_DELIVERY_LOW", "role": "caller", "party": { "kind": "SIP_PHONE", "model": "Mitel-6867i", "raw": "SIPPHONE/Mitel-6867i" }, "direction": "INBOUND", "percentMissing": 16 }, "legs": [ { "channelId": "1787253742.97114", "role": "caller", "party": { "kind": "SIP_PHONE", "name": null, "number": null, "model": "Mitel-6867i", "raw": "SIPPHONE/Mitel-6867i" }, "source": "sampled", "mediaSeconds": 183, "verdict": "DEGRADED", "measured": true, "reason": null, "inbound": { "measured": true, "reason": null, "verdict": "DEGRADED", "pps": 41.2, "referencePps": 49.1, "deliveryRatio": 0.84, "lossRatio": 0.021, "jitter": 0.031, "mes": 74.2 }, "outbound": { "measured": false, "reason": "NO_RTCP_FROM_FAR_END", "verdict": "NOT_MEASURED", "pps": 49.1 }, "rtt": null, "rttVerdict": "NOT_MEASURED", "findings": [ ... ] }, { "channelId": "1787253742.97115", "role": "callee", "party": { "kind": "EXTENSION", "name": "Reception", "number": "1234", "raw": "5f2b1c9e4a7d3b8e6c1a0d92" }, "source": "live", "mediaSeconds": 183, "verdict": "OK", "measured": true, "inbound": { "measured": true, "verdict": "OK", "pps": 50, "referencePps": 50, "deliveryRatio": 1, "lossRatio": 0, "jitter": 0.001, "mes": 88 }, "outbound": { "measured": false, "reason": "NO_RTCP_FROM_FAR_END", "verdict": "NOT_MEASURED", "pps": 50 }, "rtt": null, "rttVerdict": "NOT_MEASURED", "findings": [] } ], "findings": [ { "code": "INBOUND_DELIVERY_LOW", "verdict": "DEGRADED", "channelId": "1787253742.97114", "role": "caller", "direction": "INBOUND", "values": { "deliveryRatio": 0.84, "percentMissing": 16, "pps": 41.2, "referencePps": 49.1 } } ] }
A call that was never answered by the callee, that predates the rtpStats rollout, or that consists
only of Local/ legs comes back with measured: false, a reason, and no OK anywhere:
{ "cdrId": "5d035c832d357b369b6f7aff", "verdict": "NOT_MEASURED", "measured": false, "severity": 0, "reason": "CALL_NOT_ANSWERED", "worst": null, "legs": [], "findings": [] }
| reason | Meaning |
|---|---|
| CALL_NOT_ANSWERED | The call was never answered by the callee. |
| NO_RTP_LEGS | No RTP leg was recorded - Local/ channels and SYSTEM calls have no RTP session. |
| PRE_ROLLOUT_CDR | The CDR predates the rtpStats rollout and carries the old flat fields, which cannot be trusted to a direction. |
| LEG_TOO_SHORT | Every leg carried less than 10 seconds of media. |
| NO_MEDIA_TIME | The legs answer time was not known, so no rate can be derived. |
| NO_RTCP_FROM_FAR_END | Direction level only: the far end sends no RTCP receiver reports. |
| Error code | Message | Description |
|---|---|---|
| 401 | unauthorized | Missing or invalid token |
| 403 | access_denied | Not TX staff, or the call belongs to a customer the user may not read |
| 404 | id | Call not found |
| 500 | internal_error | <Unspecified> |