CallDetailRecord.duration includes ring time; no way to get answered/talk duration
The gap
A CallDetailRecord's duration is measured from call setup, not from answer, so it includes ring time. There is no way for an API consumer to obtain the answered (billable/talk) duration of a call.
mods/apiserver/src/calls/createFetchSingleCall.ts:41-44computesduration: int(v: r.endedAt) - int(v: r.startedAt).startedAtcomes from the call-start event'sstartTime(mods/apiserver/src/events/transformEvent.ts:40-45), which corresponds to the initial INVITE — before ringing.- No answer timestamp is recorded anywhere in the CDR pipeline, and
CallDetailRecordinmods/common/src/protos/calls.proto:62-84has no field for one.
Evidence of the size of the discrepancy
From an internal incident investigation (2026-08-30). For one call, the start event was timestamped 18:08:52.072, while the SIP 200 OK (answer) arrived at 18:08:56.145 per a packet capture — roughly 4 seconds of ring folded into duration. Ring times in that same campaign ranged from under a second up to ~26 seconds, so the error is variable and can dominate a short call.
Impact
Consumers doing per-call billing, talk-time reporting, or answer-rate analysis cannot use duration and must measure it themselves inside their voice application — which only works for calls that reach their application at all, and gives a number that does not reconcile with Fonoster's own CDR or with the call recording.
Suggested direction (a suggestion, not a prescription)
Record an answer timestamp when the channel is answered and expose it — either as a new answered_at field on CallDetailRecord alongside the existing started_at/ended_at, or as a separate answered_duration. Additive proto fields, backward compatible. Leave the existing duration semantics unchanged so nothing breaks; just make the answered figure obtainable.
Source: fonoster/fonoster