Sign inGet Started

Get a call's transcript

GET
/v1/voice/calls/{call_id}/transcript
const transcript = await bird.voice.calls.transcript("vcs_01krdgeqcxet5s7t44vh8rt9mg");
for (const cue of transcript.cues) {
  console.log(cue.text);
}
Response200
{
  "call_id": "vcs_01krdgeqcxet5s7t44vh8rt9mg",
  "parties": [
    {
      "endpoint": {
        "type": "pstn"
      },
      "address": "+14155551234"
    }
  ],
  "cues": [
    {
      "party": 0,
      "start_at": "2026-11-01T12:00:00Z",
      "end_at": "2026-11-01T12:00:01Z",
      "text": "Hello."
    }
  ],
  "complete": true,
  "evaluated_at": "2026-11-01T12:01:00Z"
}

Returns one transcript for the whole call: the cues of every party's stream in spoken order, each pointing into parties at the party its stream was captured from.

It is assembled on each read from the call's stored transcripts, one per stream: the latest whose every cue is timed, otherwise the latest that succeeded. When a live transcript exists, its cues take precedence; the selected transcript adds only timed cues that do not overlap them. Timed cues are placed by start_at. A transcript that timed nothing has null times, and its cues are placed at the start of their stream. A stream whose every transcription failed contributes nothing and sets complete to false. A stream where nothing was heard, one that was never transcribed, or one whose transcript has not arrived yet contributes no cues and leaves complete as it is.

Transcripts leave the API 30 days after the source audio starts. A call this workspace never placed, or whose transcripts have all expired, answers with no cues rather than 404.

Parameters

call_idstring

The call to read. Every leg carries its call's ID as call_id.

Response Payload

call_id
string
required
parties
array of object
required

Each distinct stored party heard in cues, once. A stream with no recorded party adds nothing here; its cues carry a null party.

Show child attributes
parties.endpoint
nullable object

What kind of participant sat on this side of a leg, and the coordinate that kind carries: a telephone endpoint off the platform, a SIP or WebRTC endpoint, Bird answering, or the platform placing a leg onward. It does not name a person.

null on an observation this API could not read. The entry stays, because the call counted it when it deduplicated, and dropping it here would report fewer participants than were observed.

Show child attributes
parties.endpoint.type
string
required

What kind of participant sat on this side of a leg. It selects which payload below is present, and most kinds carry none because the party's address is already their coordinate.

Possible values (may grow over time): pstn, sip, voicemail, bridge_pstn, bridge_sip, webhook

parties.endpoint.sip
object

The registered contact of a sip endpoint. Absent when the observation recorded none, and on every other kind of endpoint.

Show child attributes
parties.endpoint.sip.contact
string
required

The address the user agent registered, as a sip: or sips: URI. It is where the endpoint asked to be reached, which is not always the address that was dialled.

parties.endpoint.bridge_pstn
object

Where the platform placed the leg onward, on a bridge_pstn endpoint. Absent on every other kind of endpoint.

Show child attributes
parties.endpoint.bridge_sip
object

The trunk the platform delivered the leg onward to, on a bridge_sip endpoint. Absent on every other kind of endpoint.

Show child attributes
parties.address
nullable string

This side's own address, in E.164 or as a sip: URI. null when the observation carried none, which does not say whether one was withheld, missing, or nonexistent.

parties.overdial_suffix
string

Digits dialled after this party's number, including leading zeroes. Absent when no overdial was received.

parties.trunk_id
nullable string

The workspace trunk on this side of the leg. null when this side sat behind no trunk.

parties.user_id
nullable string

The workspace user this side acted for, such as a user's browser, the ring group member whose side a recording captured, or the user who started a sequence call. null for every other participant, including an API key.

cues
array of object
required

Every cue of the call in spoken order. A cue without times sits at the start of its stream.

Show child attributes
complete
boolean
required

false when a stream's every transcription failed, or the read was cut at its limit. true does not mean every stream has cues: a stream where nothing was heard, one never transcribed, or one whose transcript has not arrived yet contributes none and leaves this true.

evaluated_at
string
required

The instant retention was decided at. A transcript can expire after it.

Continue with the documentation, guides and examples for this topic.