List legs
/v1/voice/legsfor await (const leg of bird.voice.legs.list()) {
console.log(leg.id, leg.status);
}for leg in client.voice.legs.list():
print(leg.id, leg.status)for leg, err := range client.Voice.Legs.List(context.Background(), bird.VoiceLegsListParams{}) {
if err != nil {
log.Fatal(err)
}
fmt.Println(leg.Id, leg.Status)
}foreach ($bird->voice->legs->list() as $leg) {
echo $leg->getId(), ' ', $leg->getStatus(), "\n";
}bird voice legs listcurl -X GET "https://us1.platform.bird.com/v1/voice/legs" \
-H "Authorization: Bearer $TOKEN" \
--url-query "limit=25"{
"data": [
{
"id": "vcl_01krdgeqcxet5s7t44vh8rt9mg",
"call_id": "vcs_01krdgeqcxet5s7t44vh8rt9mg",
"workspace_id": "ws_01krdgeqcxet5s7t44vh8rt9mg",
"direction": "outbound",
"from": "+14155551234",
"to": "+16505559876",
"actor": {
"id": "usr_01krdgeqcxet5s7t44vh8rt9mg",
"type": "user"
},
"sip_trunk_id": "spt_01krdgeqcxet5s7t44vh8rt9mg",
"sip_call_id": "3f9a1c8e7b2d4a5f@sip.example.net",
"status": "answered",
"sip_response_code": 200,
"rejection_reason": "destination_not_enabled",
"route": {
"type": "trunk"
},
"tags": [
{
"name": "category",
"value": "welcome"
}
],
"duration_ms": 65000,
"pdd_ms": 850,
"billable_ms": 60000,
"media_quality": {
"mos": 4.32,
"jitter_ms": 12,
"packet_loss_pct": 1.5,
"round_trip_time_ms": 42
},
"cost": {
"amount": "0.013000",
"currency_code": "USD",
"outbound_amount": "0.013000",
"inbound_amount": null,
"call_handling_amount": null,
"recording_amount": null,
"transcription_amount": null
}
}
],
"next_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE0OjAzOjEwWlwiIiwiaSI6IjAxOTJmM2IxLTRjN2UtN2EyYi05ZDYxLThmM2E1YzJlN2I0MCJ9",
"prev_cursor": null,
"refresh_cursor": "eyJ2IjoxLCJzIjoiXCIyMDI2LTA1LTI1VDE2OjQyOjAxWlwiIiwiaSI6IjAxOTJmM2IxLTllMDQtN2NkMy1iODE3LTJhNmY0ZDFjOGUwOSJ9"
}
Returns a paginated list of the workspace's legs, ordered by start time descending.
The status filter selects where in the lifecycle you look, and any
combination is a single page: in-flight statuses (ringing,
in_progress), final ones, or both together. Omit it and you get
completed legs, which is what this list has always returned.
A leg in flight carries no economics yet: duration_ms, billable_ms,
ended_at, and cost are null until it ends. It keeps the same id
throughout, so the same leg answers under one identity from the first
ring to settlement.
Query Parameters
directionstringReturn only legs in this direction.
Possible values: inbound, outbound
statusarrayReturn only legs with one of these statuses, comma-separated. In-flight and final statuses may be combined freely.
call_idstringReturn only legs belonging to this call, which is how the legs of one multi-party or transferred call are correlated.
sip_trunk_idstringReturn only legs carried by this SIP trunk.
fromstringReturn only legs placed from this calling party number, matched as a whole number rather than as a fragment. Give it in international form: +14155551234, 14155551234, and 0014155551234 all select the same legs. A number given without a country code is read as an international one, so give the country code to be sure of what you are matching. Use number instead to match part of a number, or either side of the leg.
tostringReturn only legs placed to this called party number, matched as a whole number rather than as a fragment. Give it in international form: +16505559876, 16505559876, and 0016505559876 all select the same legs. A number given without a country code is read as an international one, so give the country code to be sure of what you are matching. Use number instead to match part of a number, or either side of the leg.
numberstringReturn only legs where the calling or called number contains this value. Matches a partial number, so a country or area-code prefix returns every leg to or from it. Combines with from/to, which match one side exactly.
tagarrayFilter by tag. Accepts name to match any record carrying that tag name, or name:value to match a specific tag pair (for example category:welcome). Repeat the parameter to add more tags. A record must match every tag listed to be returned.
started_afterstringReturn only legs that started at or after this instant, inclusive. RFC 3339 timestamp.
started_beforestringReturn only legs that started at or before this instant, inclusive. RFC 3339 timestamp.
limitintegerMaximum number of items to return per page.
starting_afterstringCursor from the next_cursor field of a previous list response. Returns items immediately after the cursor position in the current sort order.
ending_beforestringCursor from the prev_cursor or refresh_cursor field of a previous list response. Returns items immediately before the cursor position in the current sort order. prev_cursor returns the preceding page. refresh_cursor anchors at the first row of that response, which on a newest-first sort is how to fetch the items that have appeared since.
Response Payload
dataShow child attributes
data.idUnique identifier for this leg record.
data.call_idCall identifier shared across all legs of a multi-party or transferred call. Use this to correlate related leg records. null when call correlation is not available for the leg.
data.workspace_iddata.directiondata.fromCalling party number in E.164 format.
data.toCalled party number in E.164 format.
data.actorWho placed the leg: the API key whose credentials it used, the integration acting for the workspace, or the user who placed it from a browser or the CLI. Absent when the leg was admitted only by its source IP address, or when no actor was recorded.
Show child attributes
data.actor.idActor identifier.
data.actor.typeNew actor types may be added. Treat unrecognized values as future types, not errors.
user: a member's own session.api_key: a workspace API key.oauth_token: a token issued to a caller on a member's behalf.system: an action we perform without a customer actor.sso: an organization's SSO connection.service_account: a workspace's connected Integration acting with no member behind it.automation: an automation execution in your workspace.
Possible values (may grow over time): user, api_key, oauth_token, system, sso, service_account, automation
data.actor.display_nameThe label the actor is shown under: typically a member's name or email address, or the API key's name. Null when it could not be resolved.
data.sip_trunk_idIdentifier of the SIP trunk that originated this leg. null when no trunk is associated.
data.sip_call_idThe SIP Call-ID of this leg's signalling. We relay it unchanged, so it matches what the carrier and your own equipment logged for the same leg: the carrier's value on an incoming leg, and your system's value on a leg you place through a SIP trunk. Use it to match this leg against a carrier's records or your PBX logs. Legs recorded before this field existed carry it only if they were answered.
data.statusdata.sip_response_codeFinal SIP response code received from the carrier. null when no SIP response was received, for example on timeout or DNS failure.
data.rejection_reasonWhy we rejected the leg. Absent on connected legs and legs rejected
by the carrier or recipient. For carrier or recipient rejections, see
sip_response_code; a 6xx decline gives the leg a rejected status.
Read alongside route when present. A refusal caused by the number's
configuration has no rejection reason; the route records that
configuration.
data.routeWhich answer your number gave an incoming leg. Its type selects the shape, and each answer carries its own fields; the variants below are the full set you can receive. Recorded when the leg was handled, so changing the number's setup afterwards does not change what its past legs say. Absent on outbound legs, and on legs recorded before this field existed.
data.tagsYour own {name, value} labels for this leg, taken from the X-Bird-Call-Tag headers on the INVITE that placed it. Set them to organise legs by a dimension of your own (campaign, queue, agent, cost centre), then filter this list by them with tag. Read-only here: a leg is labelled when it is placed, and never afterwards. What is here may be less than what was sent, and the leg still goes through either way: a tag whose name or value breaks the rules below is dropped, anything past the first five is ignored, and a name sent more than once keeps its first value. Absent when the leg carried none, and on legs recorded before this field existed.
data.started_atWhen the leg was initiated.
data.answered_atWhen the leg was answered (200 OK received). null for unanswered legs.
data.ended_atWhen the leg ended (BYE or final non-2xx response). null for legs that ended abnormally without a recorded end event.
data.duration_msTotal leg duration in milliseconds, measured from the first INVITE to the BYE or final response. null while the leg is still in progress and has no final duration yet.
data.pdd_msPost-dial delay in milliseconds: how long the caller heard nothing between dialing and the phone starting to ring at the other end. High values are what callers experience as the leg not going through. Absent when the leg never rang, either because it failed first or because the carrier answered it immediately.
data.billable_msBillable duration in milliseconds, measured from answer to leg end. Zero for unanswered legs, and null while the leg is still in progress.
data.media_qualityHow the audio sounded, as opposed to whether the leg connected. Absent when the leg carried no audio, or when the far end reported nothing to measure from.
data.costWhat the leg cost, net of tax, at full precision, split into the components that make it up. Absent until the leg has been rated; unanswered or unpriced legs have no cost, and neither does a verification call Bird places and answers on your behalf, which is exempt from rating.
next_cursorCursor for the next page. Pass back as starting_after to advance forward. null when no next page exists.
prev_cursorCursor for the previous page. Pass back as ending_before to step backward. null when no previous page exists.
refresh_cursorRefresh anchor, the first row of this response. Pass back as ending_before to fetch what precedes it in the current sort order. On a newest-first sort those are the items that have appeared since; on any other sort they are the items that sort earlier, so refreshing such a list means re-fetching it instead. Non-null whenever data is non-empty; null only on an empty page. Distinct from prev_cursor.
Related resources
Continue with the documentation, guides and examples for this topic.