# List calls, newest first (cursor-paginated)

Source: https://docs.usetone.ai/reference/calls/list

> Every call, inbound and outbound, including campaign calls.

`GET /v1/calls`
Every call, inbound and outbound, including campaign calls. Filter by agent, number, campaign, direction, disposition or date range. A campaign filter here returns every ATTEMPT including retries, which the recipient list cannot give you.

Requires the `read` scope.

## Parameters

| Name | In | | Meaning |
|---|---|---|---|
| `limit` | query | optional | How many calls to return. 1-100. |
| `cursor` | query | optional | Opaque page cursor — pass `meta.pagination.cursor` from the previous response. Its contents are an implementation detail; do not parse or construct one. |
| `agent_id` | query | optional | Only calls run by this agent, across every one of its versions. |
| `number_id` | query | optional | Only calls placed from, or received on, this number. |
| `campaign_id` | query | optional | Every call this campaign placed, retries included — which is what the recipient list cannot give you, since a recipient row names only its LAST attempt. |
| `direction` | query | optional | Which way the call went. Open set — handle an unrecognised value rather than throwing. Today: `inbound`, `outbound`. |
| `channel` | query | optional | How the call was carried. `browser` is the in-dashboard microphone test only; every dial the API places is `pstn`. Open set — handle an unrecognised value rather than throwing. Today: `browser`, `pstn`. |
| `status` | query | optional | Where the call is in its lifecycle. Open set — handle an unrecognised value rather than throwing. Today: `queued`, `in_progress`, `ended`. |
| `disposition` | query | optional | How the call finished. Only set once `status` is `ended`. Open set — handle an unrecognised value rather than throwing. Today: `answered`, `no_answer`, `busy`, `failed`, `voicemail`, `unknown`. |
| `environment` | query | optional | Ignored when you authenticate with an API key: the key's own prefix pins the environment, so a `tone_test_` key structurally cannot read live calls. |
| `from` | query | optional | Inclusive lower bound on `createdAt`. A bare date (`2026-08-01`) is accepted and read as midnight UTC. |
| `to` | query | optional | Exclusive upper bound on `createdAt`. Must be later than `from`. |
| `include_unstarted` | query | optional | Include rows for calls that never started — an abandoned browser test dialog mints one, so they are hidden by default. |

## Response



### Example response

```json
{
  "data": [
    {
      "agent": {
        "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
        "name": "Order confirmation"
      },
      "agentVersion": 3,
      "billedPaise": 600,
      "campaignId": null,
      "channel": "pstn",
      "compliance": "passed",
      "createdAt": "2026-08-25T09:14:22Z",
      "direction": "outbound",
      "disposition": "answered",
      "durationSeconds": 45,
      "endReason": "agent_ended",
      "endedAt": "2026-08-25T09:15:11Z",
      "environment": "live",
      "evaluations": {},
      "hasRecording": true,
      "hasTranscript": true,
      "id": "9f1c2d84-4e3a-4f6c-b902-7d1e8a33c451",
      "initiator": {
        "id": "key_8f14a2c9",
        "type": "api_key"
      },
      "number": {
        "e164": "+918045678901",
        "id": "4b7c1a02-9de5-4f31-bb07-2c1a5e9f0d43"
      },
      "outputs": {
        "confirmed": true,
        "delivery_day": "Thursday"
      },
      "peer": "+919876543210",
      "quality": {
        "answerP50Ms": 480,
        "perceivedP50Ms": 0,
        "turns": 6
      },
      "ratePaisePerMinute": 600,
      "startedAt": "2026-08-25T09:14:26Z",
      "status": "ended",
      "summary": "Customer confirmed the order and asked for Thursday delivery.",
      "variables": {
        "customer_name": "Priya",
        "order_id": "AC-4417"
      },
      "verdict": "success"
    }
  ]
}
```
