> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tracklysms.com/llms.txt
> Use this file to discover all available pages before exploring further.

# List Calls

> List your voice calls newest-first, filterable by status and queue.

Returns your account's voice calls, most recent first. Filter by lifecycle status or queue, and page through results with the cursor returned on each response.

Requires the `voice_calls.read` scope and the **Voice Calls** product entitlement.

## Query Parameters

<ParamField query="status" type="string" optional>
  Filter by lifecycle state. Pass `active` for all non-terminal calls, or a specific state (e.g. `established`). See [Call states](/api-reference/voice/overview#call-states).
</ParamField>

<ParamField query="queue" type="string" optional>
  Return only calls associated with this queue id.
</ParamField>

<ParamField query="cursor" type="string" optional>
  A pagination cursor. Pass the `nextCursor` from the previous response to fetch the next page.
</ParamField>

<ParamField query="limit" type="integer" default={50}>
  Maximum number of calls to return. Maximum `100`.
</ParamField>

## Response Fields

<ResponseField name="calls" type="array">
  The matching calls, newest first.

  <Expandable title="Call properties" defaultOpen>
    <ResponseField name="calls[].id" type="string">The call's unique identifier.</ResponseField>
    <ResponseField name="calls[].direction" type="string">`inbound` or `outbound`.</ResponseField>
    <ResponseField name="calls[].state" type="string">Lifecycle state. See [Call states](/api-reference/voice/overview#call-states).</ResponseField>
    <ResponseField name="calls[].legKind" type="string">`primary`, `bridge`, or `monitor`.</ResponseField>
    <ResponseField name="calls[].from" type="string">The calling number.</ResponseField>
    <ResponseField name="calls[].to" type="string">The destination number.</ResponseField>
    <ResponseField name="calls[].connectTo" type="string | null">The resolved bridge target, if any.</ResponseField>
    <ResponseField name="calls[].queueId" type="string | null">The queue this call is parked in, if any.</ResponseField>
    <ResponseField name="calls[].conferenceId" type="string | null">The provider conference id once a bridge or monitor leg is attached.</ResponseField>
    <ResponseField name="calls[].parentCallId" type="string | null">For a bridge/monitor leg, the primary call it belongs to.</ResponseField>
    <ResponseField name="calls[].bridgedCallId" type="string | null">For a primary call, the currently bridged agent leg.</ResponseField>
    <ResponseField name="calls[].monitorRole" type="string | null">`MONITOR` or `ADVISOR` for a monitor leg.</ResponseField>
    <ResponseField name="calls[].record" type="boolean">Whether recording was requested.</ResponseField>
    <ResponseField name="calls[].recordingState" type="string | null">`requested`, `started`, `stopped`, `ready`, `failed`, or `deleted`.</ResponseField>
    <ResponseField name="calls[].recordingFileIds" type="array">Provider file ids for completed recordings.</ResponseField>
    <ResponseField name="calls[].customData" type="object">The metadata attached to the call.</ResponseField>
    <ResponseField name="calls[].error" type="string | null">A machine-readable reason when the call failed.</ResponseField>
    <ResponseField name="calls[].startedAt" type="string | null">ISO 8601 timestamp when the call started.</ResponseField>
    <ResponseField name="calls[].answeredAt" type="string | null">ISO 8601 timestamp when the call was answered.</ResponseField>
    <ResponseField name="calls[].endedAt" type="string | null">ISO 8601 timestamp when the call ended.</ResponseField>
    <ResponseField name="calls[].createdAt" type="string | null">ISO 8601 timestamp when the record was created.</ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="nextCursor" type="string">
  Returned whenever the page is full (the number of results equals `limit`), indicating there may be more. Pass it back as the `cursor` query parameter to fetch the next page; a page that comes back with fewer results than `limit` (or empty) is the end.
</ResponseField>

## Examples

<RequestExample>
  ```bash cURL theme={null}
  curl "https://api.tracklysms.com/api/v1/voice/calls?status=active&limit=50" \
    -H "X-Api-Key: trk_your_api_key_here"
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "calls": [
      {
        "id": "665f1e2a9c4b1a0012ab34cd",
        "direction": "outbound",
        "state": "established",
        "legKind": "primary",
        "from": "+18005551234",
        "to": "+14155551234",
        "connectTo": "+14155559876",
        "queueId": null,
        "conferenceId": "665f1e2a9c4b1a0012ab34ce",
        "parentCallId": null,
        "bridgedCallId": "665f1e2a9c4b1a0012ab34cf",
        "monitorRole": null,
        "record": true,
        "recordingState": "started",
        "recordingFileIds": [],
        "customData": { "caseId": "abc-123" },
        "error": null,
        "startedAt": "2026-08-21T18:00:00.000000Z",
        "answeredAt": "2026-08-21T18:00:12.000000Z",
        "endedAt": null,
        "createdAt": "2026-08-21T18:00:00.000000Z"
      }
    ]
  }
  ```
</ResponseExample>

## Error Codes

| Status | Code                 | Meaning                                                   |
| ------ | -------------------- | --------------------------------------------------------- |
| 422    | `invalid_status`     | The `status` value is not `active` or a known call state. |
| 422    | `invalid_queue`      | `queue` is not a valid queue id.                          |
| 422    | `invalid_cursor`     | `cursor` is not a valid pagination cursor.                |
| 403    | `voice_not_entitled` | Voice calling is not enabled for your account.            |
