# Call logs

The Calls API provides access to call history, recordings, transcripts, and real-time call events.

{% hint style="info" %}
Base URL: `https://api.krosai.com/v1/calls`
{% endhint %}

## List Calls

Retrieve call history with filtering and pagination.

GET /calls

### Query Parameters

| Parameter         | Type    | Description                                            |
| ----------------- | ------- | ------------------------------------------------------ |
| `status`          | string  | Filter by status: `completed`, `failed`, `in_progress` |
| `direction`       | string  | Filter by direction: `inbound`, `outbound`             |
| `phone_number_id` | string  | Filter by phone number                                 |
| `endpoint_id`     | string  | Filter by endpoint                                     |
| `from_date`       | string  | Start date (ISO 8601)                                  |
| `to_date`         | string  | End date (ISO 8601)                                    |
| `limit`           | integer | Results per page (default: 50, max: 100)               |
| `offset`          | integer | Pagination offset                                      |

### Request

{% code title="curl" %}

```bash
curl -X GET "https://api.krosai.com/v1/calls?limit=10&status=completed" \
  -H "x-api-key: kros_live_your_key"
```

{% endcode %}

### Response

```json
{
  "calls": [
    {
      "id": "call_abc123",
      "from_number": "+14155551234",
      "to_number": "+2348012345678",
      "direction": "inbound",
      "status": "completed",
      "duration": 180,
      "cost_cents": 12,
      "endpoint_id": "ep_xyz789",
      "phone_number_id": "pn_123",
      "recording_url": "https://storage.krosai.com/recordings/call_abc123.mp3",
      "transcript": "Hello, how can I help you today?...",
      "created_at": "2025-01-10T10:00:00Z",
      "answered_at": "2025-01-10T10:00:05Z",
      "completed_at": "2025-01-10T10:03:05Z"
    }
  ],
  "total": 156,
  "limit": 10,
  "offset": 0
}
```

## Get Call

Retrieve detailed information about a specific call.

GET /calls/{id}

### Request

{% code title="curl" %}

```bash
curl -X GET "https://api.krosai.com/v1/calls/call_abc123" \
  -H "x-api-key: kros_live_your_key"
```

{% endcode %}

### Response

```json
{
  "id": "call_abc123",
  "from_number": "+14155551234",
  "to_number": "+2348012345678",
  "direction": "inbound",
  "status": "completed",
  "duration": 180,
  "cost_cents": 12,
  "endpoint": {
    "id": "ep_xyz789",
    "name": "Support Agent",
    "provider": "elevenlabs"
  },
  "phone_number": {
    "id": "pn_123",
    "number": "+2348012345678"
  },
  "recording_url": "https://storage.krosai.com/recordings/call_abc123.mp3",
  "transcript": "Hello, how can I help you today? I'm looking for information about...",
  "quality_metrics": {
    "latency_ms": 120,
    "audio_codec": "opus",
    "packet_loss": 0.01
  },
  "hangup_cause": "normal_clearing",
  "created_at": "2025-01-10T10:00:00Z",
  "answered_at": "2025-01-10T10:00:05Z",
  "completed_at": "2025-01-10T10:03:05Z"
}
```

## Get Call Statistics

Get aggregated statistics for calls.

GET /calls/stats

### Query Parameters

| Parameter         | Type   | Description            |
| ----------------- | ------ | ---------------------- |
| `phone_number_id` | string | Filter by phone number |
| `endpoint_id`     | string | Filter by endpoint     |
| `from_date`       | string | Start date (ISO 8601)  |
| `to_date`         | string | End date (ISO 8601)    |

### Request

{% code title="curl" %}

```bash
curl -X GET "https://api.krosai.com/v1/calls/stats?from_date=2025-01-01" \
  -H "x-api-key: kros_live_your_key"
```

{% endcode %}

### Response

```json
{
  "total_calls": 1250,
  "completed_calls": 1180,
  "failed_calls": 70,
  "total_duration_seconds": 45000,
  "average_duration_seconds": 38,
  "total_cost_cents": 3600,
  "inbound_calls": 800,
  "outbound_calls": 450,
  "success_rate": 0.944
}
```

## Get Call Events

Retrieve the event timeline for a specific call.

GET /calls/{id}/events

### Request

{% code title="curl" %}

```bash
curl -X GET "https://api.krosai.com/v1/calls/call_abc123/events" \
  -H "x-api-key: kros_live_your_key"
```

{% endcode %}

### Response

```json
{
  "events": [
    {
      "id": "evt_001",
      "event_type": "call_initiated",
      "created_at": "2025-01-10T10:00:00Z",
      "event_data": {}
    },
    {
      "id": "evt_002",
      "event_type": "sip_invite_sent",
      "created_at": "2025-01-10T10:00:01Z",
      "event_data": {
        "sip_uri": "sip:agent@sip.rtc.elevenlabs.io"
      }
    },
    {
      "id": "evt_003",
      "event_type": "call_answered",
      "created_at": "2025-01-10T10:00:05Z",
      "event_data": {}
    },
    {
      "id": "evt_004",
      "event_type": "sip_media_established",
      "created_at": "2025-01-10T10:00:06Z",
      "event_data": {
        "codec": "opus",
        "latency_ms": 120
      }
    },
    {
      "id": "evt_005",
      "event_type": "call_completed",
      "created_at": "2025-01-10T10:03:05Z",
      "event_data": {
        "duration": 180,
        "hangup_cause": "normal_clearing"
      }
    }
  ]
}
```

## Hangup Call

Terminate an active call.

POST /calls/{id}/hangup

### Request

{% code title="curl" %}

```bash
curl -X POST "https://api.krosai.com/v1/calls/call_abc123/hangup" \
  -H "x-api-key: kros_live_your_key"
```

{% endcode %}

### Response

```json
{
  "success": true,
  "message": "Call hangup initiated"
}
```

## Call Status Values

| Status        | Description              |
| ------------- | ------------------------ |
| `initiated`   | Call is being set up     |
| `ringing`     | Destination is ringing   |
| `in_progress` | Call is active           |
| `completed`   | Call ended normally      |
| `failed`      | Call failed to connect   |
| `busy`        | Destination was busy     |
| `no_answer`   | No answer at destination |

## Hangup Causes

| Cause             | Description               |
| ----------------- | ------------------------- |
| `normal_clearing` | Normal call termination   |
| `user_hangup`     | Caller hung up            |
| `agent_hangup`    | Agent/endpoint hung up    |
| `no_answer`       | Destination didn't answer |
| `busy`            | Destination busy          |
| `rejected`        | Call rejected             |
| `network_error`   | Network failure           |
| `timeout`         | Call timed out            |

## Recordings

Call recordings are automatically generated for completed calls and stored securely.

### Recording URL

Recordings are available via the `recording_url` field:

<https://storage.krosai.com/recordings/call\\_abc123.mp3>

### Recording Formats

* Format: MP3
* Sample Rate: 48kHz
* Channels: Mono (mixed)
* Retention: 90 days (configurable)

## Transcripts

Full transcripts are generated using speech-to-text and available in the `transcript` field.

### Transcript Format

Plain text with speaker labels (when available):

```
[Agent]: Hello, how can I help you today?
[Caller]: Hi, I'm calling about my order status.
[Agent]: I'd be happy to help. Can you provide your order number?
...
```

## Code Examples

{% tabs %}
{% tab title="TypeScript" %}
{% code title="examples/calls.ts" %}

```typescript
// List recent call
async function listCalls(options?: {
  status?: string;
  direction?: string;
  limit?: number;
}) {
  const params = new URLSearchParams();
  if (options?.status) params.set('status', options.status);
  if (options?.direction) params.set('direction', options.direction);
  if (options?.limit) params.set('limit', options.limit.toString());
  
  const response = await fetch(
    `https://api.krosai.com/v1/calls?${params}`,
    {
      headers: { 'x-api-key': process.env.KROSAI_API_KEY! },
    }
  );
  
  return response.json();
}

// Get call details with recording
async function getCallWithRecording(callId: string) {
  const response = await fetch(
    `https://api.krosai.com/v1/calls/${callId}`,
    {
      headers: { 'x-api-key': process.env.KROSAI_API_KEY! },
    }
  );
  
  const call = await response.json();
  
  if (call.recording_url) {
    console.log(`Recording available: ${call.recording_url}`);
  }
  
  return call;
}

// Hangup an active call
async function hangupCall(callId: string) {
  const response = await fetch(
    `https://api.krosai.com/v1/calls/${callId}/hangup`,
    {
      method: 'POST',
      headers: { 'x-api-key': process.env.KROSAI_API_KEY! },
    }
  );
  
  return response.json();
}
```

{% endcode %}
{% endtab %}

{% tab title="Python" %}
{% code title="examples/calls.py" %}

```python
import requests
import os

API_KEY = os.environ.get('KROSAI_API_KEY')
BASE_URL = 'https://api.krosai.com/v1'

def list_calls(status=None, direction=None, limit=50):
    params = {'limit': limit}
    if status:
        params['status'] = status
    if direction:
        params['direction'] = direction
    
    response = requests.get(
        f'{BASE_URL}/calls',
        headers={'x-api-key': API_KEY},
        params=params
    )
    return response.json()

def get_call(call_id):
    response = requests.get(
        f'{BASE_URL}/calls/{call_id}',
        headers={'x-api-key': API_KEY}
    )
    return response.json()

def get_call_events(call_id):
    response = requests.get(
        f'{BASE_URL}/calls/{call_id}/events',
        headers={'x-api-key': API_KEY}
    )
    return response.json()

def download_recording(call_id, output_path):
    call = get_call(call_id)
    if call.get('recording_url'):
        response = requests.get(call['recording_url'])
        with open(output_path, 'wb') as f:
            f.write(response.content)
        print(f'Recording saved to {output_path}')
```

{% endcode %}
{% endtab %}
{% endtabs %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.krosai.com/voice/call-logs.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
