
## Метрики туннеля

`GET /v1/infra/servers/:id/metrics`

Возвращает данные активности сервера из Black Hole Gateway в реальном времени: время подключения агента, последние HTTP и SSH запросы, количество активных соединений. Используйте для мониторинга «живо ли приложение», отладки таймаутов, проверки авто-сна. Работает только для BLACKHOLE-серверов. Если Gateway временно недоступен — ответ всё равно придёт со статусом 200, но поле `available: false`.

## Параметры

| Параметр | В | Тип | Обяз. | Описание |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | да | ID BLACKHOLE-сервера |

## Примеры

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

```bash
curl -H "X-Api-Key: YOUR_API_KEY" \
  https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/metrics
```

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

```bash
curl -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/metrics
```

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

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/metrics`,
  { headers: { 'X-Api-Key': 'YOUR_API_KEY' } }
)
const { data } = await res.json()

if (data.available) {
  console.log(`Подключён: ${data.connectedAt}`)
  console.log(`Последний HTTP: ${data.lastRequestAt ?? 'никогда'}`)
  console.log(`HTTP-соединений: ${data.httpConnections}`)
} else {
  console.log('Gateway недоступен, туннель может работать')
}
```

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

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/metrics`,
  {
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
    },
  }
)
```

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

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | Всегда `true` — даже когда Gateway недоступен, эндпоинт возвращает 200 с `available: false` |
| `data.available` | boolean | `true` — данные получены от Gateway. `false` — Gateway не отвечает (но туннель мог работать) |
| `data.subdomain` | string | Субдомен приложения (всегда присутствует) |
| `data.appUrl` | string | HTTPS-адрес приложения (только при `available: true`) |
| `data.connectedAt` | string (ISO 8601) \| null | Момент, когда агент подключился к Gateway. `null` — агент ни разу не был подключён |
| `data.lastRequestAt` | string (ISO 8601) \| null | Момент последнего HTTP-запроса к приложению. `null` — ни одного запроса не было |
| `data.lastSshActivityAt` | string (ISO 8601) \| null | Момент последней SSH-активности. Для современных BLACKHOLE-серверов всегда `null` (SSH-relay отключён) |
| `data.httpConnections` | number | Количество активных HTTP-соединений через туннель |
| `data.sshConnections` | number | Количество активных SSH-соединений. Всегда `0` для современных серверов |

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

Gateway доступен:

```json
{
  "success": true,
  "data": {
    "available": true,
    "subdomain": "app-5ec02c7e",
    "appUrl": "https://app-5ec02c7e.vibecode.bitrix24.tech",
    "lastRequestAt": null,
    "lastSshActivityAt": null,
    "connectedAt": "2026-04-22T11:16:32Z",
    "httpConnections": 0,
    "sshConnections": 0
  }
}
```

Gateway недоступен (штатное поведение при временной недоступности):

```json
{
  "success": true,
  "data": {
    "available": false,
    "subdomain": "app-5ec02c7e"
  }
}
```

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

404 — не BLACKHOLE-сервер:

```json
{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "BLACKHOLE server not found"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Неверный или просроченный API-ключ |
| 403 | `SERVER_ROLE_FORBIDDEN` | Вы состоите в команде разработки этого сервера с ролью «Разработчик», а операция открыта роли «Администратор». В `error.hint` придут ваша роль, требуемый порог и перечень открытых вам вызовов. Разбор ролей — [Список серверов](/docs/infra/servers/list) |
| 404 | `NOT_FOUND` | Сервер не в режиме BLACKHOLE, удалён или привязан к другому API-ключу, и вы не состоите в его команде разработки. Для OPEN-сервера эндпоинт возвращает 404 (метрики туннеля не применимы) |
| 429 | `RATE_LIMITED` | Превышен общий лимит запросов платформы |

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

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

- **HTTP 200 + `available: false` — это не ошибка, а штатное поведение при временной недоступности Gateway.** Gateway временно не отвечает (перезапуск, сетевые проблемы внутри платформы), но приложение при этом **может** работать — туннель восстановится сам. В UI показывайте «метрики недоступны», а не «сервер мёртв».
- **`connectedAt` сбрасывается при перезапуске Gateway.** Если Gateway перезапустили, `connectedAt` покажет момент нового подключения агента. Это не значит, что агент переподключался — Gateway просто «забыл» историю.
- **`lastRequestAt: null` при запущенном сервере — норма.** Означает, что никто не обращался к HTTPS-субдомену приложения. Именно это поле сбрасывает таймер простоя, поэтому такой сервер скоро усыпит авто-сон: у новой машины он включён с таймаутом 60 минут. Отключается значением `null` — [Настроить авто-сон](/docs/infra/lifecycle/sleep).
- **`available: true` ≠ «приложение работает».** Это означает лишь, что Gateway отдал данные. Агент подключён, туннель готов — но приложение может не слушать порт 3000 и отдавать 503. Для проверки работоспособности делайте HTTP-запрос на `appUrl`.

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

- [Настроить авто-сон](/docs/infra/lifecycle/sleep)
- [Получить сервер](/docs/infra/servers/get)
- [Восстановить туннель](/docs/infra/lifecycle/repair)
- [Логи сервиса](./logs.md)
