
## Статистика по ключу

`GET /v1/ai/credentials/:id/usage`

Возвращает агрегированную статистику использования конкретного BYOK-ключа: общее количество запросов, расход токенов и разбивку по моделям. Период настраивается через query-параметр.

## Параметры

| Параметр | Тип | Обяз. | По умолч. | Описание |
|----------|-----|:-----:|-----------|----------|
| `id` (path) | string | да | — | ID ключа из [`GET /v1/ai/credentials`](./list.md) |
| `days` (query) | number | нет | `30` | Период в днях. Допустимый диапазон: `1..90`. Значения вне диапазона автоматически приводятся к границам |

## Примеры

### curl — личный ключ

```bash
curl "https://vibecode.bitrix24.tech/v1/ai/credentials/cred_abc123def456/usage?days=7" \
  -H "X-Api-Key: YOUR_API_KEY"
```

### curl — OAuth-приложение

```bash
curl "https://vibecode.bitrix24.tech/v1/ai/credentials/cred_abc123def456/usage?days=7" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN"
```

### JavaScript — личный ключ

```javascript
const id = 'cred_abc123def456'
const res = await fetch(`https://vibecode.bitrix24.tech/v1/ai/credentials/${id}/usage?days=7`, {
  headers: { 'X-Api-Key': 'YOUR_API_KEY' },
})

const { data } = await res.json()
console.log(`За ${data.period.days} дней: ${data.requests} запросов, ${data.totalTokens} токенов`)
data.byModel.forEach((m) => console.log(`  ${m.modelId}: ${m.calls} запросов`))
```

### JavaScript — OAuth-приложение

```javascript
const id = 'cred_abc123def456'
const res = await fetch(`https://vibecode.bitrix24.tech/v1/ai/credentials/${id}/usage?days=30`, {
  headers: {
    'X-Api-Key': 'YOUR_APP_KEY',
    'Authorization': 'Bearer USER_SESSION_TOKEN',
  },
})

const { data } = await res.json()
console.log('Токены ответа:', data.completionTokens)
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | Всегда `true` при успехе |
| `data.period.days` | number | Фактический период в днях (после ограничения 1..90) |
| `data.period.since` | string | Начало периода в `ISO 8601` |
| `data.requests` | number | Общее количество запросов через этот ключ за период |
| `data.promptTokens` | number | Сумма токенов входа |
| `data.completionTokens` | number | Сумма токенов ответа |
| `data.totalTokens` | number | Сумма всех токенов |
| `data.byModel` | array | Разбивка успешных запросов по моделям, отсортирована по убыванию количества вызовов |
| `data.byModel[].modelId` | string | ID модели |
| `data.byModel[].calls` | number | Количество запросов к этой модели |
| `data.byModel[].promptTokens` | number | Токены входа по модели |
| `data.byModel[].completionTokens` | number | Токены ответа по модели |

## Пример ответа

```json
{
  "success": true,
  "data": {
    "period": {
      "days": 7,
      "since": "2026-04-20T11:30:00.000Z"
    },
    "requests": 142,
    "promptTokens": 45200,
    "completionTokens": 18300,
    "totalTokens": 63500,
    "byModel": [
      {
        "modelId": "openai/gpt-4o-mini",
        "calls": 98,
        "promptTokens": 28000,
        "completionTokens": 11000
      },
      {
        "modelId": "openai/gpt-4o",
        "calls": 44,
        "promptTokens": 17200,
        "completionTokens": 7300
      }
    ]
  }
}
```

## Пример ответа при ошибке

`404 not_found` — ключ не найден или принадлежит другому пользователю:

```json
{
  "success": false,
  "error": {
    "code": "not_found",
    "message": "Credential not found"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 404 | `not_found` | Ключ с таким `id` не найден или не принадлежит вам |
| 403 | `scope_missing` | API-ключу не хватает скоупа `vibe:ai` |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

**Только успешные вызовы в `byModel`.** Разбивка по моделям учитывает только записи со статусом `SUCCESS`. Общие счётчики (`requests`, `promptTokens` и др.) включают все статусы — успешные, ошибочные, частично успешные.

**Группировка по `(userId, providerId)`.** Статистика на уровне ключа выводится из логов, отфильтрованных по комбинации «ваш `userId`» + «`providerId` ключа» + `credentialScope: USER`. Если вы переподключали ключ того же провайдера — старые записи попадут в новую статистику, потому что они соотносятся не по `id` ключа, а по провайдеру.

**Разница с [`GET /v1/ai/usage`](/docs/ai/consumption/usage).** Этот эндпоинт показывает статистику только по одному BYOK-ключу. Общий [`/v1/ai/usage`](/docs/ai/consumption/usage) показывает все вызовы текущего API-ключа, включая платформенные модели и PORTAL-credentials, не только USER-BYOK.

## Смотрите также

- [Статистика использования](/docs/ai/consumption/usage)
- [Список ключей](./list.md)
- [Свои ключи (BYOK)](/docs/ai/credentials)
