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

# Voice API

> Integrate voice capabilities into your application using the thinnestAI Voice API for programmatic call control.

# Voice API

The Voice API gives you programmatic control over voice interactions — start calls, check status, retrieve recordings, and manage sessions. Use it to build custom voice experiences in your applications.

## Authentication

All voice API endpoints require a Bearer token:

```bash theme={null}
curl -H "Authorization: Bearer YOUR_API_KEY" \
  https://api.thinnest.ai/voice/...
```

## Endpoints

### Start an Outbound Call

**POST** `/voice/outbound/dial`

```bash theme={null}
curl -X POST "https://api.thinnest.ai/voice/outbound/dial" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agent_xyz",
    "to_number": "+14155551234",
    "from_number": "+18005551234",
    "context": {
      "customer_name": "Jane Doe",
      "order_id": "ORD-123"
    },
    "max_duration": 300,
    "recording": true,
    "webhook_url": "https://your-app.com/call-events"
  }'
```

**Parameters:**

| Field          | Type    | Required | Description                               |
| -------------- | ------- | -------- | ----------------------------------------- |
| `agent_id`     | string  | Yes      | Voice agent to use                        |
| `to_number`    | string  | Yes      | Destination number (E.164)                |
| `from_number`  | string  | Yes      | Caller ID (must be verified)              |
| `context`      | object  | No       | Data passed to agent's prompt             |
| `max_duration` | integer | No       | Max call length in seconds (default: 600) |
| `recording`    | boolean | No       | Record the call                           |
| `scheduled_at` | string  | No       | ISO 8601 timestamp for scheduled call     |
| `webhook_url`  | string  | No       | URL for call status events                |

**Response:**

```json theme={null}
{
  "call_id": "call_abc123",
  "status": "initiating",
  "agent_id": "agent_xyz",
  "to_number": "+14155551234",
  "created_at": "2026-03-07T10:00:00Z"
}
```

### Start a Voice Session (WebRTC)

**POST** `/voice/start`

Creates a WebRTC session for browser-based voice:

```bash theme={null}
curl -X POST "https://api.thinnest.ai/voice/start" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "agent_xyz",
    "context": {
      "user_name": "Jane",
      "page": "pricing"
    }
  }'
```

**Response:**

```json theme={null}
{
  "session_id": "session_abc123",
  "token": "eyJhbGciOiJIUzI1NiIs...",
  "websocket_url": "wss://voice.thinnest.ai/ws/session_abc123",
  "livekit_url": "wss://livekit.thinnest.ai"
}
```

Use the returned `token` and `livekit_url` to connect via [WebRTC](/docs/deploy/webrtc).

### Get Session Status

**GET** `/voice/status/{session_id}`

```bash theme={null}
curl "https://api.thinnest.ai/voice/status/session_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response:**

```json theme={null}
{
  "session_id": "session_abc123",
  "status": "completed",
  "duration": 145,
  "agent_id": "agent_xyz",
  "to_number": "+14155551234",
  "from_number": "+18005551234",
  "started_at": "2026-03-07T10:00:05Z",
  "ended_at": "2026-03-07T10:02:30Z",
  "tokens_used": 1250
}
```

### List Voice Sessions

**GET** `/voice/sessions`

```bash theme={null}
curl "https://api.thinnest.ai/voice/sessions?limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Query Parameters:**

| Parameter    | Type    | Description                                        |
| ------------ | ------- | -------------------------------------------------- |
| `agent_id`   | string  | Filter by agent                                    |
| `status`     | string  | Filter by status (completed, failed, in\_progress) |
| `limit`      | integer | Results per page (default: 20, max: 100)           |
| `offset`     | integer | Pagination offset                                  |
| `start_date` | string  | Filter from date (ISO 8601)                        |
| `end_date`   | string  | Filter until date (ISO 8601)                       |

### Get Session Details

**GET** `/voice/sessions/{session_id}`

```bash theme={null}
curl "https://api.thinnest.ai/voice/sessions/session_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Get Session Transcript

**GET** `/v1/widget/transcript/{session_id}`

```bash theme={null}
curl "https://api.thinnest.ai/v1/widget/transcript/session_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

**Response:**

```json theme={null}
{
  "call_id": "session_abc123",
  "transcript": [
    { "role": "agent", "text": "Hello, thanks for calling Acme.", "timestamp": 0.5 },
    { "role": "user", "text": "Hi, I need help with my order.", "timestamp": 2.1 },
    { "role": "agent", "text": "Of course! What's your order number?", "timestamp": 3.8 }
  ]
}
```

### Get Recording

**GET** `/voice/recording/{recording_id}`

Returns the recording details:

```bash theme={null}
curl "https://api.thinnest.ai/voice/recording/rec_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### End a Voice Session

**POST** `/voice/end/{session_id}`

```bash theme={null}
curl -X POST "https://api.thinnest.ai/voice/end/session_abc123" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

## Webhook Events

If you provide a `webhook_url` when starting a call, you'll receive POST requests with call status updates:

```json theme={null}
{
  "event": "call.completed",
  "call_id": "call_abc123",
  "status": "completed",
  "duration": 145,
  "timestamp": "2026-03-07T10:02:30Z"
}
```

### Event Types

| Event              | Description                         |
| ------------------ | ----------------------------------- |
| `call.initiating`  | Call is being set up                |
| `call.ringing`     | Phone is ringing                    |
| `call.in_progress` | Call connected, conversation active |
| `call.completed`   | Call ended normally                 |
| `call.failed`      | Call failed to connect              |
| `call.no_answer`   | No answer after timeout             |

## Integration Example: Appointment Reminders

```python theme={null}
import httpx
from datetime import datetime, timedelta

API_KEY = "YOUR_API_KEY"
BASE_URL = "https://api.thinnest.ai"

async def send_reminder(customer_phone: str, appointment_time: str):
    async with httpx.AsyncClient() as client:
        response = await client.post(
            f"{BASE_URL}/voice/outbound/dial",
            headers={"Authorization": f"Bearer {API_KEY}"},
            json={
                "agent_id": "agent_reminder",
                "to_number": customer_phone,
                "from_number": "+18005551234",
                "context": {
                    "appointment_time": appointment_time,
                    "purpose": "appointment_reminder"
                },
                "max_duration": 120,
                "webhook_url": "https://your-app.com/call-events",
            },
        )
        return response.json()

# Send a reminder
result = await send_reminder("+14155551234", "March 10 at 2 PM")
print(f"Call ID: {result['call_id']}")
```

## Rate Limits

| Endpoint      | Rate   |
| ------------- | ------ |
| Start call    | 10/min |
| Voice session | 30/min |
| Get status    | 60/min |
| List sessions | 30/min |

## Best Practices

* **Set `max_duration`** to prevent unexpectedly long calls
* **Use `context`** to personalize the agent's greeting and behavior
* **Enable recording** for compliance and quality review
* **Handle webhook events** for real-time call tracking
* **Use scheduled calls** for time-sensitive outreach (reminders, follow-ups)
