> For the complete documentation index, see [llms.txt](https://docs.limephone.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.limephone.io/api-reference/calls.md).

# Calls

Call records for your organization — who called whom, when, for how long, with what result — plus the recording, transcription and AI summary attached to each call.

## List calls

`GET /v1/calls` — scope `calls:read`

Lists calls, newest first, with standard [pagination](/api-reference/rate-limits-errors-and-pagination.md).

```bash
curl "https://dashboard.limephone.io/api/v1/calls?limit=10" \
  -H "Authorization: Bearer sk_live_..."
```

Each call carries `id`, `direction`, `fromNumber`, `toNumber`, `status`, `duration` and `createdAt`; additional fields (SIDs, recording flags, costs) appear when populated. The `id` is what the sub-resource endpoints below take.

```javascript
// Node.js — page through recent calls
const res = await fetch(
  'https://dashboard.limephone.io/api/v1/calls?limit=50',
  { headers: { Authorization: `Bearer ${process.env.LIMEPHONE_API_KEY}` } },
);
const { data, pagination } = await res.json();
for (const call of data) {
  console.log(call.direction, call.from, '->', call.to, call.status);
}
```

```python
# Python
import os, requests

res = requests.get(
    "https://dashboard.limephone.io/api/v1/calls",
    headers={"Authorization": f"Bearer {os.environ['LIMEPHONE_API_KEY']}"},
    params={"limit": 50},
).json()
for call in res["data"]:
    print(call["direction"], call["from"], "->", call["to"], call["status"])
```

## Get a call

`GET /v1/calls/{id}` — scope `calls:read`

Fetches one call by id. Returns `404` if the call does not exist in your organization.

## Get the recording

`GET /v1/calls/{id}/recording` — scope `calls:read`

Returns the recording URL plus duration; `404` when the call has no recording.

```json
{
  "recordingUrl": "https://...",
  "duration": 184,
  "callSid": "CA9c1f..."
}
```

## Get the transcription

`GET /v1/calls/{id}/transcription` — scope `calls:read`

Returns the call transcription as text; `404` when none is available.

## Get the AI summary

`GET /v1/calls/{id}/summary` — scope `calls:read`

Returns the AI-generated summary of the call — what it was about and how it ended; `404` when none is available.

## Get the voicemail

`GET /v1/calls/{id}/voicemail` — scope `calls:read`

Returns the voicemail left on a call, looked up by the call's **SID** (pass the `callSid`, not the numeric id); `404` when the call has no voicemail.

## Record a call outcome

`PATCH /v1/calls/{id}` — scope `calls:write`

**Outcome write-back.** Record what an AI-handled call was actually worth once your CRM knows — the closed deal, the booked value — so LimePhone reporting reflects revenue, not just call counts. Applies to AI voice calls.

**Body** — at least one of:

| Field      | Type   | Notes                                                                            |
| ---------- | ------ | -------------------------------------------------------------------------------- |
| `outcome`  | string | Your label, e.g. `"appointment_confirmed"`, `"sale"`, `"no_sale"`. Max 120 chars |
| `value`    | number | Monetary value attributed to the call                                            |
| `currency` | string | ISO-4217 code; defaults to `GBP` when a value is sent                            |
| `metadata` | object | Free-form CRM fields — **merged** with existing metadata, never replaced         |

**Query:** `preference=first|last` (default `last`). With `last`, the newest write wins. With `first`, an outcome already on the call is kept — the response returns `200` with `applied: false`, so a webhook firing twice can't clobber the original verdict.

```bash
curl -X PATCH https://dashboard.limephone.io/api/v1/calls/1204 \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "outcome": "appointment_confirmed",
    "value": 250,
    "currency": "GBP",
    "metadata": { "dealId": "D-4482" }
  }'
```

```json
{
  "applied": true,
  "call": {
    "id": 1204,
    "outcome": "appointment_confirmed",
    "value": "250",
    "currency": "GBP",
    "metadata": { "dealId": "D-4482" },
    "outcomeSetAt": "2026-09-04T10:02:11.000Z"
  }
}
```
