---
title: "Read Speak AI voice agent call history"
description: "List and inspect calls handled by your voice agents, including the event log for a single call. Completed calls link to a Media record via mediaId."
---

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

# Read Speak AI voice agent call history


import EndpointIndex from "@/components/api/EndpointIndex.astro";

The Speak AI API exposes 3 conversations endpoints under the base URL `https://api.speakai.co/v1`. Every request needs the `x-speakai-key` and `x-access-token` headers described in [Authentication](/api/authentication/).

## What can you do with the conversations endpoints?

Speak AI groups these 3 endpoints under the conversations resource. Each entry below links to the full reference for that endpoint further down this page.

| Method | Path | What it does |
| --- | --- | --- |
| `GET` | [`/voice/conversations`](#get-voice-conversations) | List Conversations |
| `GET` | [`/voice/conversations/{conversationId}`](#get-voice-conversations-conversation-id) | Get Conversation |
| `GET` | [`/voice/conversations/{conversationId}/events`](#get-voice-conversations-conversation-id-events) | Get Conversation Events |

<h2 id="get-voice-conversations">List Conversations</h2>

#### List Conversations

Lists calls handled by your voice agents, newest first. Once a call finishes processing, mediaId links it to a regular Speak media record -- pull the recording, transcript, and insights through the Media API using that id.

### Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `agentId` | query | string | No | One agent id, or repeat the param for several (?agentId=a&agentId=b). |
| `callType` | query | string | No |  |
| `search` | query | string | No | Matches against the agent's name. Max 200 characters. |
| `startDate` | query | string | No | ISO 8601 date. |
| `endDate` | query | string | No | ISO 8601 date. |
| `page` | query | integer | No | Defaults to 1. |
| `limit` | query | integer | No | Defaults to 50, max 200. |

<div slot="code">

<CodePanel label="Example request">

```bash
curl -X GET 'https://api.speakai.co/v1/voice/conversations' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
```

</CodePanel>

<ResponsePanel id="get-voice-conversations" statuses={[{"code":"200","description":"OK"}]}>

<div slot="status-200">

**`200` OK**

Response body, `application/json`.

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | One of: `success` . |
| `data` | object |  |
| `data.conversations` | object[] |  |
| `data.total` | integer |  |
| `data.page` | integer |  |
| `data.limit` | integer |  |

<details>
<summary>`data.conversations` -- 28 more fields</summary>

| Field | Type | Description |
| --- | --- | --- |
| `_id` | string | MongoDB document id, included because every document has one; use conversationId to identify it. |
| `conversationId` | string | Server-generated UUID. Immutable. |
| `agentId` | string |  |
| `agentName` | string | Only present on the single-conversation Get response, resolved server-side for display. |
| `companyId` | string |  |
| `userId` | string |  |
| `widgetSessionId` | string |  |
| `participants` | string[] |  |
| `sessionId` | string |  |
| `status` | string | One of: `active`, `completed`, `ended`, `transferred` . |
| `duration` | number | Call length in seconds. |
| `costs` | object | Vendor cost breakdown (LLM, TTS, STT, telephony). Reporting only, not the customer charge. |
| `startedAt` | string (date-time) |  |
| `endedAt` | string (date-time) |  |
| `endedReason` | string |  |
| `recordingUrls` | object |  |
| `recordingUrls.mixed` | string |  |
| `recordingUrls.user` | string |  |
| `recordingUrls.agent` | string |  |
| `recordingStatus` | string | One of: `pending`, `recording`, `processing`, `completed`, `failed` . |
| `callType` | string | One of: `web`, `phone` . |
| `sourceLanguage` | string |  |
| `phone` | object |  |
| `phone.callSid` | string |  |
| `phone.from` | string |  |
| `phone.to` | string |  |
| `handoff` | object |  |
| `handoff.occurred` | boolean |  |
| `handoff.targetNumber` | string |  |
| `handoff.transferredAt` | string (date-time) |  |
| `handoff.summary` | string |  |
| `callerId` | string |  |
| `mediaId` | string | Set once the call's post-call pipeline finishes. This is a regular Speak media record -- use it with the Media API (GET /media/\{mediaId\}, insights, transcript, export) to pull the recording, transcript, summary, and any Fields this call's Questions wrote onto it. |
| `folderId` | string | The folder the call's media was filed into. See the Folders API. |
| `pipelineState` | string | Internal post-call processing state. pending/running calls may not have mediaId set yet. One of: `pending`, `running`, `completed` . |
| `feedback` | object |  |
| `feedback.rating` | integer |  |
| `feedback.comment` | string |  |
| `feedback.submittedAt` | string (date-time) |  |
| `createdAt` | string (date-time) |  |
| `updatedAt` | string (date-time) |  |

</details>

Example response, `application/json`.

```json
{
  "status": "success",
  "data": {
"conversations": [
  {
    "conversationId": "c9d8e7f6-a5b4-3210-9876-543210fedcba",
    "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "companyId": "6650a1b2c3d4e5f60000000a",
    "participants": [
      "caller"
    ],
    "sessionId": "sess-88a1",
    "status": "completed",
    "duration": 142.5,
    "startedAt": "2026-08-01T12:00:00.000Z",
    "endedAt": "2026-08-01T12:02:22.500Z",
    "endedReason": "user_hangup",
    "recordingStatus": "completed",
    "callType": "web",
    "mediaId": "6650a1b2c3d4e5f678909999",
    "folderId": "6650a1b2c3d4e5f678908888",
    "pipelineState": "completed",
    "createdAt": "2026-08-01T12:00:00.000Z",
    "updatedAt": "2026-08-01T12:02:25.000Z"
  }
],
"total": 1,
"page": 1,
"limit": 50
  }
}
```

</div>

</ResponsePanel>

</div>

<h2 id="get-voice-conversations-conversation-id">Get Conversation</h2>

#### Get Conversation

Fetches a single call by id, scoped to your company. Use mediaId from the response with the Media API to retrieve the recording, transcript, and analysis for this call.

### Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `conversationId` | path | string | Yes |  |

<div slot="code">

<CodePanel label="Example request">

```bash
curl -X GET 'https://api.speakai.co/v1/voice/conversations/CONVERSATION_ID' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
```

</CodePanel>

<ResponsePanel id="get-voice-conversations-conversation-id" statuses={[{"code":"200","description":"OK"},{"code":"404","description":"Conversation not found"}]}>

<div slot="status-200">

**`200` OK**

Response body, `application/json`.

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | One of: `success` . |
| `data` | object |  |
| `data.conversation` | object |  |

<details>
<summary>`data.conversation` -- 28 more fields</summary>

| Field | Type | Description |
| --- | --- | --- |
| `_id` | string | MongoDB document id, included because every document has one; use conversationId to identify it. |
| `conversationId` | string | Server-generated UUID. Immutable. |
| `agentId` | string |  |
| `agentName` | string | Only present on the single-conversation Get response, resolved server-side for display. |
| `companyId` | string |  |
| `userId` | string |  |
| `widgetSessionId` | string |  |
| `participants` | string[] |  |
| `sessionId` | string |  |
| `status` | string | One of: `active`, `completed`, `ended`, `transferred` . |
| `duration` | number | Call length in seconds. |
| `costs` | object | Vendor cost breakdown (LLM, TTS, STT, telephony). Reporting only, not the customer charge. |
| `startedAt` | string (date-time) |  |
| `endedAt` | string (date-time) |  |
| `endedReason` | string |  |
| `recordingUrls` | object |  |
| `recordingUrls.mixed` | string |  |
| `recordingUrls.user` | string |  |
| `recordingUrls.agent` | string |  |
| `recordingStatus` | string | One of: `pending`, `recording`, `processing`, `completed`, `failed` . |
| `callType` | string | One of: `web`, `phone` . |
| `sourceLanguage` | string |  |
| `phone` | object |  |
| `phone.callSid` | string |  |
| `phone.from` | string |  |
| `phone.to` | string |  |
| `handoff` | object |  |
| `handoff.occurred` | boolean |  |
| `handoff.targetNumber` | string |  |
| `handoff.transferredAt` | string (date-time) |  |
| `handoff.summary` | string |  |
| `callerId` | string |  |
| `mediaId` | string | Set once the call's post-call pipeline finishes. This is a regular Speak media record -- use it with the Media API (GET /media/\{mediaId\}, insights, transcript, export) to pull the recording, transcript, summary, and any Fields this call's Questions wrote onto it. |
| `folderId` | string | The folder the call's media was filed into. See the Folders API. |
| `pipelineState` | string | Internal post-call processing state. pending/running calls may not have mediaId set yet. One of: `pending`, `running`, `completed` . |
| `feedback` | object |  |
| `feedback.rating` | integer |  |
| `feedback.comment` | string |  |
| `feedback.submittedAt` | string (date-time) |  |
| `createdAt` | string (date-time) |  |
| `updatedAt` | string (date-time) |  |

</details>

Example response, `application/json`.

```json
{
  "status": "success",
  "data": {
"conversation": {
  "conversationId": "c9d8e7f6-a5b4-3210-9876-543210fedcba",
  "agentId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "companyId": "6650a1b2c3d4e5f60000000a",
  "participants": [
    "caller"
  ],
  "sessionId": "sess-88a1",
  "status": "completed",
  "duration": 142.5,
  "startedAt": "2026-08-01T12:00:00.000Z",
  "endedAt": "2026-08-01T12:02:22.500Z",
  "endedReason": "user_hangup",
  "recordingStatus": "completed",
  "callType": "web",
  "mediaId": "6650a1b2c3d4e5f678909999",
  "folderId": "6650a1b2c3d4e5f678908888",
  "pipelineState": "completed",
  "createdAt": "2026-08-01T12:00:00.000Z",
  "updatedAt": "2026-08-01T12:02:25.000Z"
}
  }
}
```

</div>

<div slot="status-404">

**`404` Conversation not found**

Response body, `application/json`.

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | One of: `failed` . |
| `requestId` | string |  |
| `code` | integer |  |
| `message` | string |  |
| `hints` | string[] |  |

Example response, `application/json`.

```json
{
  "status": "failed",
  "code": 404,
  "message": "Conversation not found",
  "hints": []
}
```

</div>

</ResponsePanel>

</div>

<h2 id="get-voice-conversations-conversation-id-events">Get Conversation Events</h2>

#### Get Conversation Events

Lists the raw turn-by-turn event log for one call (in chronological order): each transcript turn, tool call, and lifecycle transition the worker recorded during the call.

### Parameters

| Parameter | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `conversationId` | path | string | Yes |  |

<div slot="code">

<CodePanel label="Example request">

```bash
curl -X GET 'https://api.speakai.co/v1/voice/conversations/CONVERSATION_ID/events' \
  -H 'x-speakai-key: sk_test_speak_0000000000000000' \
  -H 'x-access-token: eyJhbGciOiJIUzI1NiJ9.test-access-token.0000000000'
```

</CodePanel>

<ResponsePanel id="get-voice-conversations-conversation-id-events" statuses={[{"code":"200","description":"OK"},{"code":"404","description":"Conversation not found"}]}>

<div slot="status-200">

**`200` OK**

Response body, `application/json`.

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | One of: `success` . |
| `data` | object |  |
| `data.events` | object[] |  |

<details>
<summary>`data.events` -- 9 more fields</summary>

| Field | Type | Description |
| --- | --- | --- |
| `_id` | string | MongoDB document id, included because every document has one; use eventId to identify it. |
| `eventId` | string |  |
| `conversationId` | string |  |
| `eventType` | string | One of the voice call lifecycle event types (turn taken, tool called, handoff, etc). |
| `timestamp` | string (date-time) |  |
| `cost` | number |  |
| `platformCost` | number |  |
| `data` | object | Event-type-specific payload. Shape varies by eventType. |
| `metadata` | object |  |
| `metadata.requestId` | string |  |
| `metadata.turnNumber` | integer |  |

</details>

Example response, `application/json`.

```json
{
  "status": "success",
  "data": {
"events": [
  {
    "eventId": "evt-1",
    "conversationId": "c9d8e7f6-a5b4-3210-9876-543210fedcba",
    "eventType": "turn_completed",
    "timestamp": "2026-08-01T12:00:05.000Z"
  }
]
  }
}
```

</div>

<div slot="status-404">

**`404` Conversation not found**

Response body, `application/json`.

| Field | Type | Description |
| --- | --- | --- |
| `status` | string | One of: `failed` . |
| `requestId` | string |  |
| `code` | integer |  |
| `message` | string |  |
| `hints` | string[] |  |

Example response, `application/json`.

```json
{
  "status": "failed",
  "code": 404,
  "message": "Conversation not found",
  "hints": []
}
```

</div>

</ResponsePanel>

</div>

## Related pages

- [API reference](/api/) for the base URL, authentication, and the error format.
- [Authenticate with the Speak AI API using access tokens](/api/authentication/)
- [Upload audio and video to Speak AI and read insights](/api/media/)
- [Create and update live transcription sessions](/api/live-transcription/)
- [Analyze text notes with the Speak AI text endpoints](/api/text/)

Get an API key on the [Speak AI developer page](https://app.speakai.co/developers?utm_source=docs&utm_medium=referral&utm_campaign=api-reference&utm_content=api-voice-agents/conversations).

Source: https://docs.speakai.co/api/voice-agents/conversations/index.mdx
