# List call journal

Take the lastId and lastStatusTime cursor pair from the last row. Forward statusTime unchanged; it is ATOM with a timezone offset.

`GET /v1/calls/log`

**Bitrix24:** `call.CallLog.list` | **Scope:** `call` | **Auth:** `X-Api-Key`

## Parameters

| Parameter | Type | Required | Description |
|---|---|---|---|
| status | string / string[] | no | initiated, answered, declined, missed; case-insensitive |
| excludeStatus | string | no | One status to subtract |
| type | string | no | incoming / outgoing; STATUS takes precedence; other scalar values follow Bitrix24 behavior |
| search | string | no | Search term |
| count | integer | no | Default 50, positive; clamped to 100 |
| lastId | integer | no | Last row id, or 0 for the first page |
| lastStatusTime | string | no | Unchanged last row statusTime, used with lastId |

For multiple statuses, pass `status[]=missed&status[]=answered` or repeat the parameter: `status=missed&status=answered`. With the MCP tool `manage_call_log`, use `action: "list"`, `query: { "status": ["missed", "answered"], "count": 50 }`. The array must contain at least one string; other `query` parameters remain strings or numbers.

## Response fields

`data.calls[]`: id, sourceType, sourceCallId, status, statusTime, type, isUnseen; optional callData: phoneNumber, duration, displayName, userId, chatId, title, avatar, color, userCount, dialogId, chatType. `data.missedCounter`: integer. Credentials in strings are redacted.

```json
{
  "success": true,
  "data": {
    "calls": [],
    "missedCounter": 0
  }
}
```

## Examples

```bash
curl --globoff -X GET "https://vibecode.bitrix24.com/v1/calls/log?status[]=missed&status[]=answered&count=50" -H "X-Api-Key: vibe_api_DUMMY_personal"
```

```bash
curl --globoff -X GET "https://vibecode.bitrix24.com/v1/calls/log?status[]=missed&status[]=answered&count=50" -H "X-Api-Key: vibe_app_DUMMY_oauth" -H "Authorization: Bearer DUMMY_SESSION"
```

```javascript
const response = await fetch("https://vibecode.bitrix24.com/v1/calls/log?status[]=missed&status[]=answered&count=50", {
  method: "GET", headers: { "X-Api-Key": "vibe_api_DUMMY_personal" }
});
const result = await response.json();
```

```javascript
const response = await fetch("https://vibecode.bitrix24.com/v1/calls/log?status[]=missed&status[]=answered&count=50", {
  method: "GET", headers: { "X-Api-Key": "vibe_app_DUMMY_oauth", "Authorization": "Bearer DUMMY_SESSION" }
});
const result = await response.json();
```

## Errors

| HTTP | Code | Meaning |
|---|---|---|
| 400 | INVALID_PARAMS / INVALID_FILTER_VALUE | Invalid input; no Bitrix24 call |
| 401 | TOKEN_MISSING / INVALID_API_KEY | Missing tokens or unusable key |
| 403 | SCOPE_DENIED / BITRIX_ACCESS_DENIED | Missing scope, portal permission refusal, or forbidden write |
| 422 | BITRIX_ERROR | Portal business refusal or unsuccessful operation |
| 429 | BITRIX_RATE_LIMIT | Portal rate limit |
| 502 / 503 | BITRIX_ERROR | Invalid response, unavailable portal or timeout |

400: invalid input.

```json
{"success":false,"error":{"code":"INVALID_PARAMS","message":"Invalid parameter"}}
```

## See also

- [Calls](/docs/calls)
- [Feed](/docs/feed)
- [Errors](/docs/errors)
