Skip to main content

GET /calls/{callid}/transcripts

Get a call's transcripts

Every transcript for a call — one per recorded leg, not one per call.

Scoperecordings:read
Role permissionCall reports → allow recordings
CostFree

Why recordings:read and not reports:read: a transcript is the conversation written down, so it carries the same privacy weight as the audio. The platform gates both on the same role permission, so they share one scope — a consent screen offering "transcripts but not recordings" would be describing a separation that does not exist.

A transferred call produces several recordings and therefore several transcripts, all sharing this call id. Pair them to legs with recording, which embeds the leg's uniqueId.

200 with [] is normal — the call was not recorded, was too short, or transcription has not finished. It does not mean the call is missing.

Path parameters

NameTypeRequiredExampleDescription
callidstringyes1754489201.884213The call id from call history, reports or a call webhook — a unix timestamp, a dot, and a sequence number. A malformed id is a 400 that names the expected shape, not a 404.

Responses

200

The call's transcripts. Empty when there are none.

FieldTypeDescription
[].idinteger
[].callIdstringShared by every transcript of the call.
[].recordingstringThe audio file this was transcribed from, and the reliable way to tell which leg it is: the name embeds the leg's uniqueId with the dot removed — 1785979165.372492 becomes record_1785979165372492_93458.wav. Without it the only option is pairing transcripts to legs by position and hoping the orders agree.
[].segmentsobject[]The diarized utterances in time order. Empty when the audio produced no transcript.
[].segments[].startnumberSeconds from the start of the audio. Fractional.
[].segments[].endnumberSeconds from the start of the audio. Fractional.
[].segments[].speakerintegerA diarization index, not an identity. 0 and 1 distinguish voices, and the mapping is not stable between calls. Use the transcript's agentSpeaker to tell which one is the agent.
[].segments[].textstring
[].shortSummarystringAbsent when summarization did not run, which is normal rather than an error.
[].bulletPointsstring[]
[].callPurposestringPer-account vocabulary, not a fixed enum.
[].callSentimentstringPer-account vocabulary, not a fixed enum.
[].customerSatisfactionScoreintegerAbsent is not zero. A missing score means the call was never analyzed; zero would mean it scored nothing. Averaging nulls as zeros is the most common way these numbers get misreported.
[].customerSatisfactionScoreNotestring
[].agentPerformanceScoreintegerAbsent when not scored — see customerSatisfactionScore.
[].agentPerformanceScoreNotestring
[].actionRequiredboolean
[].actionRequiredNotestring
[].urgentActionRequiredboolean
[].urgentActionRequiredNotestring
[].agentNamestring
[].agentSpeakerintegerWhich diarized speaker is the agent. Absent when the analysis could not tell them apart — do not fall back to assuming speaker 0.
[].customKpisobject[]
[].customKpis[].namestringThe KPI as your account defined it — these are per-account.
[].customKpis[].valueintegerAbsent means the KPI was not scored on this call, which is not the same as scoring zero.
[].customKpis[].notestringThe model's reasoning, when it gave one.
{
"data": [
{
"id": 44219,
"callId": "1754489201.884213",
"recording": "record_1754489201884213_93458.wav",
"shortSummary": "Caller asked to reschedule Tuesday's roof inspection to 9am.",
"bulletPoints": [
"Reschedule requested",
"Agent confirmed the new slot"
],
"callPurpose": "scheduling",
"callSentiment": "positive",
"customerSatisfactionScore": 9,
"agentPerformanceScore": 8,
"actionRequired": true,
"actionRequiredNote": "Update the crew calendar.",
"urgentActionRequired": false,
"agentName": "Dana Spencer",
"agentSpeaker": 1,
"segments": [
{
"start": 0.42,
"end": 3.1,
"speaker": 0,
"text": "Hi, can we move Tuesday to nine?"
},
{
"start": 3.4,
"end": 6.85,
"speaker": 1,
"text": "Sure, nine works. I will update the crew."
}
]
}
]
}

Errors

StatusMeaning
400invalid_request — a missing or malformed field, an unknown enum value, or an unknown field in the body. Nothing was charged.
401unauthenticated — no credential, or one that is invalid, revoked or expired. The WWW-Authenticate header names the scope the endpoint wanted.
403Two different failures share this status, and the type tells them apart:
404not_found — no such object, or it is not this account's. The two are deliberately indistinguishable.
500internal_error — something failed on our side. For a send, nothing was charged, guaranteed, which is what makes a retry safe.

See Errors for the full catalog and what to do about each.

Example

curl -X GET 'https://api.account.telebroad.com/api/public/v1/calls/1754489201.884213/transcripts' \
-H "Authorization: Bearer $TB_KEY"

Try it in the playground →