<Intro>

<EndpointHeader />

<Description>

Returns a paginated list of the workspace's calls, ordered by start time descending.

The `status` filter selects which side of the call lifecycle you get. Omit it, or pass only final statuses, and you get completed calls. Pass only the in-flight statuses (`ringing`, `in_progress`) and you get the calls happening right now. A call in flight carries no economics yet: `duration_ms`, `billable_ms`, `ended_at`, and `cost` are null until it ends, and the completed record then appears under the same `id`.

In-flight and completed calls are paged separately, so a request that mixes in-flight and final statuses returns a 422 `validation_error`.

</Description>

</Intro>

<Parameters in="query">

<Parameter name="direction" type="string">

<Description>

Return only calls in this direction.

</Description>

<Description>

Possible values: `inbound`, `outbound`

</Description>

</Parameter>

<Parameter name="status" type="array">

<Description>

Return only calls with one of these statuses, comma-separated. The in-flight statuses (`ringing`, `in_progress`) cannot be combined with final ones in the same request.

</Description>

</Parameter>

<Parameter name="session_id" type="string">

<Description>

Return only calls belonging to this session, which is how the legs of one multi-party or transferred call are correlated.

</Description>

</Parameter>

<Parameter name="sip_trunk_id" type="string">

<Description>

Return only calls carried by this SIP trunk.

</Description>

</Parameter>

<Parameter name="from" type="string">

<Description>

Return only calls 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 calls, because a call record keeps the number exactly as the calling equipment presented it. A number given without a country code matches only calls recorded in that same form, since it names a different number in every country. Use `number` instead to match part of a number, or either side of the call.

</Description>

</Parameter>

<Parameter name="to" type="string">

<Description>

Return only calls 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 calls, because a call record keeps the number exactly as the calling equipment presented it. A number given without a country code matches only calls recorded in that same form, since it names a different number in every country. Use `number` instead to match part of a number, or either side of the call.

</Description>

</Parameter>

<Parameter name="number" type="string">

<Description>

Return only calls where the calling or called number contains this value. Matches a partial number, so a country or area-code prefix returns every call to or from it. Combines with `from`/`to`, which match one side exactly.

</Description>

</Parameter>

<Parameter name="started_after" type="string">

<Description>

Return only calls that started at or after this instant, inclusive. RFC 3339 timestamp.

</Description>

</Parameter>

<Parameter name="started_before" type="string">

<Description>

Return only calls that started at or before this instant, inclusive. RFC 3339 timestamp.

</Description>

</Parameter>

<Parameter name="limit" type="integer">

<Description>

Maximum number of items to return per page.

</Description>

</Parameter>

<Parameter name="starting_after" type="string">

<Description>

Cursor from the `next_cursor` field of a previous list response. Returns items immediately after the cursor position in the current sort order.

</Description>

</Parameter>

<Parameter name="ending_before" type="string">

<Description>

Cursor from the `prev_cursor` field of a previous list response. Returns items immediately before the cursor position in the current sort order.

</Description>

</Parameter>

</Parameters>

<Payload kind="response">

<Field name="data" type="array of object" required>

<FieldChildren kind="response">

<Field name="id" type="string" prefix="data." required>

<Description>

Unique identifier for this call record.

</Description>

</Field>

<Field name="session_id" type="nullable string" prefix="data.">

<Description>

Session identifier shared across all legs of a multi-party or transferred call. Use this to correlate related call records. Null when session correlation is not available for the call.

</Description>

</Field>

<Field name="workspace_id" type="string" prefix="data." required />

<Field name="direction" type="object" prefix="data." required />

<Field name="from" type="string" prefix="data." required>

<Description>

Calling party number in E.164 format.

</Description>

</Field>

<Field name="to" type="string" prefix="data." required>

<Description>

Called party number in E.164 format.

</Description>

</Field>

<Field name="sip_trunk_id" type="nullable string" prefix="data.">

<Description>

Identifier of the SIP trunk that originated this call. Null when no trunk is associated.

</Description>

</Field>

<Field name="status" type="object" prefix="data." required />

<Field name="sip_response_code" type="nullable integer" prefix="data.">

<Description>

Final SIP response code received from the carrier. Null when no SIP response was received, for example on timeout or DNS failure.

</Description>

</Field>

<Field name="rejection_reason" type="object" prefix="data.">

<Description>

Why Bird refused the call before dialing a carrier. Absent when Bird did not refuse it, meaning the call either connected or it failed at the carrier, where `sip_response_code` is the whole story.

</Description>

</Field>

<Field name="started_at" type="string" prefix="data." required>

<Description>

When the call was initiated.

</Description>

</Field>

<Field name="answered_at" type="nullable string" prefix="data.">

<Description>

When the call was answered (200 OK received). Null for unanswered calls.

</Description>

</Field>

<Field name="ended_at" type="nullable string" prefix="data.">

<Description>

When the call ended (BYE or final non-2xx response). Null for calls that ended abnormally without a recorded end event.

</Description>

</Field>

<Field name="duration_ms" type="nullable integer" prefix="data.">

<Description>

Total call duration in milliseconds, measured from the first INVITE to the BYE or final response. Null while the call is still in progress and has no final duration yet.

</Description>

</Field>

<Field name="pdd_ms" type="integer" prefix="data.">

<Description>

Post-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 call "not going through". Absent when the call never rang, either because it failed first or because the carrier answered it immediately.

</Description>

</Field>

<Field name="billable_ms" type="nullable integer" prefix="data.">

<Description>

Billable duration in milliseconds, measured from answer to call end. Zero for unanswered calls, and null while the call is still in progress.

</Description>

</Field>

<Field name="media_quality" type="object" prefix="data.">

<Description>

How the audio sounded, as opposed to whether the call connected. Absent when the call carried no audio, or when the far end reported nothing to measure from.

</Description>

<FieldChildren kind="response">

<Field name="mos" type="number" prefix="data.media_quality." required>

<Description>

Mean opinion score, the single number for how the call sounded, from 1 (unintelligible) to 5 (as good as being in the same room). Anything at or above 4.0 is what most people would call a clear line, and below 3.5 is where callers start asking each other to repeat themselves. The three other fields are the impairments that move it.

</Description>

</Field>

<Field name="jitter_ms" type="integer" prefix="data.media_quality." required>

<Description>

Variation in the arrival time of the audio packets, in milliseconds. Audio arriving unevenly is heard as choppiness even when no packets are lost at all.

</Description>

</Field>

<Field name="packet_loss_pct" type="number" prefix="data.media_quality." required>

<Description>

Percentage of audio packets that never arrived. Heard as brief gaps or clipped words, and the impairment that degrades a call fastest.

</Description>

</Field>

<Field name="round_trip_time_ms" type="integer" prefix="data.media_quality." required>

<Description>

Round-trip time between the two ends, in milliseconds. It does not distort the audio, but above roughly 300 ms the two parties start talking over each other.

</Description>

</Field>

</FieldChildren>

</Field>

<Field name="cost" type="object" prefix="data.">

<Description>

Amount billed for this call, net of tax, at full precision. Absent until the call has been rated; unanswered or unpriced calls have no cost.

</Description>

<FieldChildren kind="response">

<Field name="amount" type="string" prefix="data.cost." required>

<Description>

Decimal amount as a string, in major currency units.

</Description>

</Field>

<Field name="currency_code" type="string" prefix="data.cost." required>

<Description>

ISO 4217 currency code.

</Description>

</Field>

</FieldChildren>

</Field>

</FieldChildren>

</Field>

<Field name="next_cursor" type="nullable string" required>

<Description>

Cursor for the next page. Pass back as `starting_after` to advance forward. Null when no next page exists.

</Description>

</Field>

<Field name="prev_cursor" type="nullable string" required>

<Description>

Cursor for the previous page. Pass back as `ending_before` to step backward. Null when no previous page exists.

</Description>

</Field>

<Field name="refresh_cursor" type="nullable string" required>

<Description>

Refresh anchor. Pass back as `ending_before` later to fetch items that have appeared since this response. Non-null whenever `data` is non-empty; null only on an empty page. Distinct from `prev_cursor`.

</Description>

</Field>

</Payload>