{"openapi":"3.1.0","info":{"title":"AGIL Calls API","version":"0.1.0","description":"AGIL Calls — встраиваемая платформа видеозвонков: комнаты и WebRTC-сигналинг,\nчат и файлы, запись и субтитры, темы, права и аудит, AI-ассистенты, вебхуки.\n\n**С чего начать:** человекочитаемое руководство — `/docs/api-guide.md`,\nподробный справочник — `/docs/api.md`, контракт — `/docs/contract.md`.\nИнтерактивный офлайн-эксплорер — `/docs` (без CDN).\n\n**Авторизация:** `x-api-key` — админский ключ тенанта, только с сервера\n(никогда не отдавайте его в браузер); `authorization: Bearer <join token>` —\nкороткоживущий токен участника для звонка, чата, файлов, STT и ассистента.\n`GET /openapi.json` — только публичная спека, `/openapi.admin.json` — полная\n(доступ управляется `AGIL_DOCS_*` / `AGIL_ADMIN_*`).\n\n**Ошибки:** всегда `{error:{code,message}}`; коды — `unauthorized`, `forbidden`,\n`validation_failed`, `password_required`, `password_invalid`, `geo_blocked`,\n`room_locked`, `room_full`, `rate_limited`, `not_found`, `feature_disabled`,\n`provider_failed`, `stt_not_configured`, `internal_error`.\n\nWebSocket-сигналинг — `/ws?token=<join token>` (см. docs/api.md §10).","x-websocket":{"path":"/ws","auth":"token query param or anonymous room/tenant/name when AGIL_ALLOW_ANONYMOUS=1","messages":["hello","sdp","ice","chat","state","reaction","caption","integrity","location","ping","history","bye","analysis-request","assistant-query"]}},"servers":[{"url":"https://calls.guardify.ru","description":"AGIL Calls server"}],"tags":[{"name":"Public","description":"Доступно без авторизации: здоровье, ICE, публичный конфиг, фоны"},{"name":"Config","description":"Конфигурация тенанта (темы, фичи, безопасность, провайдеры)"},{"name":"Rooms","description":"Создание комнат и токенов (комнаты — in-memory)"},{"name":"Join","description":"Вход в звонок, чат и AI-ассистент от имени участника"},{"name":"Files","description":"Файлы: подписанные ссылки, лимиты, feature-gating"},{"name":"Recordings","description":"Записи звонков (серверное хранилище)"},{"name":"STT","description":"Серверный speech-to-text (501, если не настроен)"},{"name":"Admin","description":"Админ API тенанта: x-api-key, только с сервера"},{"name":"Docs","description":"OpenAPI и офлайн-эксплорер"}],"security":[],"paths":{"/v1/health":{"get":{"tags":["Public"],"summary":"Проверка живости и флаги безопасности","responses":{"200":{"description":"Server health","content":{"application/json":{"schema":{"$ref":"#/components/schemas/HealthResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/ice":{"get":{"tags":["Public"],"summary":"ICE-серверы для RTCPeerConnection (STUN + TURN-пул)","responses":{"200":{"description":"ICE config","content":{"application/json":{"schema":{"type":"object","properties":{"iceServers":{"type":"array","items":{"$ref":"#/components/schemas/IceServer"}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/tenants/{tenantId}/config":{"get":{"tags":["Public"],"summary":"Публичный конфиг тенанта (тема, фичи)","parameters":[{"name":"tenantId","in":"path","required":true,"description":"Tenant id","schema":{"type":"string"}}],"responses":{"200":{"description":"Config + etag","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigEnvelope"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Config"],"summary":"Заменить конфиг тенанта","security":[{"apiKey":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"description":"Tenant id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantConfig"}}}},"responses":{"200":{"description":"Updated config","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigEnvelope"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"patch":{"tags":["Config"],"summary":"Частичное обновление конфига (тема, фичи, безопасность, провайдеры)","security":[{"apiKey":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"description":"Tenant id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantConfigPatch"}}}},"responses":{"200":{"description":"Updated config","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConfigEnvelope"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/tenants/{tenantId}/backgrounds":{"get":{"tags":["Public"],"summary":"Библиотека виртуальных фонов (builtin или внешний провайдер)","parameters":[{"name":"tenantId","in":"path","required":true,"description":"Tenant id","schema":{"type":"string"}}],"responses":{"200":{"description":"Available backgrounds","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BackgroundsResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms":{"post":{"tags":["Rooms"],"summary":"Создать комнату (анонимно при AGIL_ALLOW_ANONYMOUS=1)","security":[{},{"apiKey":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoomRequest"},"example":{"tenantId":"demo","name":"Планёрка","mode":"group"}}}},"responses":{"200":{"description":"Created room","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoomResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}},"description":"Вызывается сервером компании. Создаёт комнату и (для открытых комнат) сразу возвращает join-токен, joinUrl и embedUrl. Пароль комнаты хранится только хэшем."}},"/v1/tokens":{"post":{"tags":["Rooms"],"summary":"Выдать join-токен с фиксированными правами (admin)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenRequest"},"example":{"tenantId":"demo","roomId":"room-1","participant":{"name":"Анна","role":"guest"},"permissions":["chat","fileShare","screenShare"]}}}},"responses":{"200":{"description":"Issued token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TokenResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}},"description":"Вызывается сервером компании. Выдаёт короткоживущий токен участника с `permissions` (или правами роли, включая кастомную `roleId`). Токен передаётся браузеру; админский ключ — никогда."}},"/v1/rooms/{roomId}":{"get":{"tags":["Rooms"],"summary":"Информация о комнате и участники","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Room snapshot","content":{"application/json":{"schema":{"type":"object","properties":{"room":{"$ref":"#/components/schemas/RoomInfo"},"participants":{"type":"array","items":{"$ref":"#/components/schemas/Participant"}},"createdAt":{"type":"number"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Rooms"],"summary":"Закрыть комнату","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Closed","content":{"application/json":{"schema":{"type":"object","properties":{"closed":{"type":"boolean"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/messages":{"get":{"tags":["Rooms"],"summary":"История чата комнаты","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Max messages (1..200)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Messages","content":{"application/json":{"schema":{"type":"object","properties":{"messages":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/calendar.ics":{"get":{"tags":["Join"],"summary":"Download a room as an .ics calendar event (UTC VEVENT)","parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"start","in":"query","required":false,"description":"Event start (ISO 8601, default now)","schema":{"type":"string"}},{"name":"durationMin","in":"query","required":false,"description":"Duration 15..1440 (default 60)","schema":{"type":"integer"}},{"name":"download","in":"query","required":false,"description":"1 = attachment","schema":{"type":"string"}}],"responses":{"200":{"description":"text/calendar","content":{"text/calendar":{"schema":{"type":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/lobby":{"get":{"tags":["Join"],"summary":"Waiting-room queue (host/moderator or tenant admin key)","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Pending join requests","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LobbyRequestsResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/lobby/{requestId}":{"get":{"tags":["Join"],"summary":"Poll a waiting-room request (admitted token returned once)","parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"requestId","in":"path","required":true,"description":"Lobby request id","schema":{"type":"string"}}],"responses":{"200":{"description":"Request status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LobbyStatusResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Join"],"summary":"Kick/remove a waiting guest from the queue","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"requestId","in":"path","required":true,"description":"Lobby request id","schema":{"type":"string"}}],"responses":{"200":{"description":"Removed from the queue","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LobbyDecisionResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/lobby/{requestId}/admit":{"post":{"tags":["Join"],"summary":"Admit a waiting guest (host/moderator or tenant admin key)","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"requestId","in":"path","required":true,"description":"Lobby request id","schema":{"type":"string"}}],"responses":{"200":{"description":"Admitted guest with a join token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinRoomResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/lobby/{requestId}/reject":{"post":{"tags":["Join"],"summary":"Reject a waiting guest (body {reason?})","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"requestId","in":"path","required":true,"description":"Lobby request id","schema":{"type":"string"}}],"responses":{"200":{"description":"Rejected","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LobbyDecisionResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/breakouts":{"get":{"tags":["Join"],"summary":"Current breakout plan (host/moderator or tenant admin key)","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Active/last plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakoutListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/breakouts/start":{"post":{"tags":["Join"],"summary":"Start breakout rooms: create child rooms, assign participants, issue child-room tokens","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateBreakoutRequest"},"example":{"mode":"random","count":2,"durationMin":15,"allowReturn":true}}}},"responses":{"200":{"description":"Created plan (WS: breakout.started + per-participant breakout.assigned)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakoutPlan"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/breakouts/close":{"post":{"tags":["Join"],"summary":"Close breakout rooms (child rooms removed, plan closed)","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Closed plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/BreakoutPlan"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/breakouts/return":{"post":{"tags":["Join"],"summary":"Return to the main room (participant token; 403 when allowReturn=false)","security":[{"bearer":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Return target","content":{"application/json":{"schema":{"type":"object","properties":{"returnToRoomId":{"type":"string"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/polls":{"get":{"tags":["Join"],"summary":"Room polls/Q&A with results and personal selected/voted flags","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Polls","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PollListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"post":{"tags":["Join"],"summary":"Create a poll or Q&A (host/moderator only)","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePollRequest"},"example":{"question":"Куда идём на обед?","options":[{"text":"Пицца"},{"text":"Суши"}],"multiple":false,"kind":"poll"}}}},"responses":{"200":{"description":"Created poll (broadcast via poll.updated)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomPoll"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/polls/{pollId}/vote":{"post":{"tags":["Join"],"summary":"Vote in a poll (one vote per participant; multiple optionIds when multiple=true)","security":[{"bearer":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"pollId","in":"path","required":true,"description":"Poll id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VotePollRequest"},"example":{"optionIds":["option-id"]}}}},"responses":{"200":{"description":"Vote result (accepted or already_voted)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PollVoteResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/polls/{pollId}/close":{"post":{"tags":["Join"],"summary":"Close a poll (host/moderator only)","security":[{},{"bearer":[]},{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"pollId","in":"path","required":true,"description":"Poll id","schema":{"type":"string"}}],"responses":{"200":{"description":"Closed poll","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomPoll"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/join":{"post":{"tags":["Join"],"summary":"Войти в комнату: пароль, lock, лимит, гео, rate-limit; возвращает join-токен","parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinRoomRequest"},"example":{"name":"Анна","password":"secret","locale":"ru"}}}},"responses":{"200":{"description":"Join accepted","content":{"application/json":{"schema":{"$ref":"#/components/schemas/JoinRoomResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}},"description":"Вызывается браузером/сервером компании. Проверяет пароль, lock, гео-политику, лимит участников и rate-limit; возвращает токен и эффективные права для UI."}},"/v1/rooms/{roomId}/chat":{"post":{"tags":["Join"],"summary":"Отправить сообщение в чат звонка (внешний чат; идемпотентно по id)","description":"Вызывается сервером компании (внешний чат/бот) с join-токеном. Сообщение бродкастится в звонок, пишется в историю, уходит вебхуком chat.message; повтор с тем же `id` не дублирует.\n\nRequires the effective `chat` permission. Text messages need `session.chat.allowHostInjection`; system notices need `session.chat.allowSystemMessages` and a host/moderator role.","security":[{"bearer":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatPostRequest"},"example":{"text":"Привет из корпоративного чата","id":"msg-1"}}}},"responses":{"200":{"description":"Stored and broadcast message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatPostResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/rooms/{roomId}/assistant":{"post":{"tags":["Join"],"summary":"AI-ассистент в звонке с правами участника","description":"Вызывается браузером с join-токеном. Ассистент отвечает от имени пользователя: сервер фильтрует предложенные действия по эффективным правам; `mode:local` — 501, движок в виджете.\n\nRequires `session.inCallAgent.enabled`. `mode:\"local\"` answers 501 assistant_local_only (the widget runs the offline assistant). `hybrid` falls back to 501 on endpoint failure; `external` is fail-closed (502 provider_failed). Actions are filtered through the effective permissions and `maxActionsPerReply`.","security":[{"bearer":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/InCallAssistantRequest"}}}},"responses":{"200":{"description":"Assistant reply with permission-filtered actions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistantReply"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/files":{"post":{"tags":["Files"],"summary":"Загрузить файл в чат (raw body, лимит из конфига)","security":[{"bearer":[]}],"parameters":[{"name":"x-file-name","in":"query","required":false,"description":"Original file name","schema":{"type":"header"}}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Stored file with signed URL","content":{"application/json":{"schema":{"$ref":"#/components/schemas/FileRecord"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}},"description":"Вызывается браузером с join-токеном. Требует features.fileShare и права fileShare; возвращает запись с подписанной ссылкой."}},"/v1/files/{id}":{"get":{"tags":["Files"],"summary":"Скачать файл по подписанной ссылке","parameters":[{"name":"id","in":"path","required":true,"description":"File id","schema":{"type":"string"}},{"name":"sig","in":"query","required":false,"description":"HMAC signature","schema":{"type":"string"}},{"name":"exp","in":"query","required":false,"description":"Expiry (epoch ms)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Raw bytes","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/recordings":{"post":{"tags":["Recordings"],"summary":"Загрузить запись (raw webm/mp4 + x-recording-meta)","security":[{"bearer":[]}],"parameters":[{"name":"x-recording-meta","in":"query","required":false,"description":"JSON {roomId,durationSec,mimeType}","schema":{"type":"header"}}],"requestBody":{"required":true,"content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Stored recording","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RecordingRecord"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/recordings/{id}":{"get":{"tags":["Recordings"],"summary":"Скачать запись по подписанной ссылке","parameters":[{"name":"id","in":"path","required":true,"description":"Recording id","schema":{"type":"string"}},{"name":"sig","in":"query","required":false,"description":"HMAC signature","schema":{"type":"string"}},{"name":"exp","in":"query","required":false,"description":"Expiry (epoch ms)","schema":{"type":"integer"}}],"responses":{"200":{"description":"Raw bytes","content":{"application/octet-stream":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/stt/transcribe":{"post":{"tags":["STT"],"summary":"Серверный speech-to-text (501, если не настроен)","security":[{"bearer":[]}],"parameters":[{"name":"x-language","in":"query","required":false,"description":"ru|en (header)","schema":{"type":"header"}}],"requestBody":{"required":true,"content":{"audio/webm":{"schema":{"type":"string","format":"binary"}},"audio/wav":{"schema":{"type":"string","format":"binary"}}}},"responses":{"200":{"description":"Transcript","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SttResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/overview":{"get":{"tags":["Admin"],"summary":"Обзор KPI тенанта","security":[{"apiKey":[]}],"responses":{"200":{"description":"Overview","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminOverview"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms":{"get":{"tags":["Admin"],"summary":"Список комнат","security":[{"apiKey":[]}],"responses":{"200":{"description":"Rooms","content":{"application/json":{"schema":{"type":"object","properties":{"rooms":{"type":"array","items":{"$ref":"#/components/schemas/AdminRoomSummary"}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"post":{"tags":["Admin"],"summary":"Создать комнату; пароль хранится только scrypt-хэшем","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoomRequest"},"example":{"tenantId":"demo","name":"Планёрка","password":"secret","maxParticipants":12,"mode":"group"}}}},"responses":{"200":{"description":"Created room","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateRoomResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}":{"get":{"tags":["Admin"],"summary":"Детали комнаты: участники, чат, ссылки","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Room detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomDetail"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Admin"],"summary":"Закрыть комнату (admin)","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Closed","content":{"application/json":{"schema":{"type":"object","properties":{"closed":{"type":"boolean"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/invites":{"post":{"tags":["Admin"],"summary":"Создать инвайт-ссылку и токен","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"type":"object","properties":{"ttlSec":{"type":"integer"},"role":{"type":"string","enum":["host","moderator","guest"]}}}}}},"responses":{"200":{"description":"Invite","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InviteLink"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/lock":{"post":{"tags":["Admin"],"summary":"Заблокировать/разблокировать комнату","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["locked"],"properties":{"locked":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Lock state","content":{"application/json":{"schema":{"type":"object","properties":{"locked":{"type":"boolean"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/kick":{"post":{"tags":["Admin"],"summary":"Отключить участника (kick)","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["participantId"],"properties":{"participantId":{"type":"string"}}}}}},"responses":{"200":{"description":"Kicked","content":{"application/json":{"schema":{"type":"object","properties":{"kicked":{"type":"boolean"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/chat":{"post":{"tags":["Admin"],"summary":"Сообщение в чат от бота/CRM компании (без токена)","description":"System notices require `session.chat.allowSystemMessages`; text messages require `session.chat.allowHostInjection`. Default author is {name:\"Система\", role:\"moderator\"}.","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatPostRequest"},"example":{"text":"Привет из корпоративного чата","id":"msg-1"}}}},"responses":{"200":{"description":"Stored and broadcast message","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatPostResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/transcript":{"get":{"tags":["Admin"],"summary":"Сегменты транскрипта","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Transcript","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/password":{"post":{"tags":["Admin"],"summary":"Set or generate a room password (scrypt; generated password shown once)","description":"`{password}` sets it; empty/omitted body generates a strong password and returns it **once** (`generated:true`). Only the scrypt hash is stored; GET/list never return the password. Use for «Сменить/Установить пароль» in the dashboard.","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomPasswordRequest"},"example":{}}}},"responses":{"200":{"description":"Password updated (generated password only on generation)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomPasswordResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Admin"],"summary":"Remove the room password (make the room public)","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Password removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoomPasswordResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/analysis":{"get":{"tags":["Admin"],"summary":"Комплаенс-отчёт, находки и заметки","description":"JSON для экспорта; `?format=md` отдаёт Markdown, `&download=1` — как файл (content-disposition).","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"format","in":"query","required":false,"description":"json|md","schema":{"type":"string"}},{"name":"download","in":"query","required":false,"description":"1 = attachment","schema":{"type":"string"}}],"responses":{"200":{"description":"Analysis","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/notes":{"get":{"tags":["Admin"],"summary":"Meeting notes (summary, decisions, action items) for export","description":"JSON `{roomId, notes, updatedAt}`; `?format=md` — Markdown для скачивания/печати.","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}},{"name":"format","in":"query","required":false,"description":"json|md","schema":{"type":"string"}},{"name":"download","in":"query","required":false,"description":"1 = attachment","schema":{"type":"string"}}],"responses":{"200":{"description":"Notes JSON or markdown","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}},"text/markdown":{"schema":{"type":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/analysis/run":{"post":{"tags":["Admin"],"summary":"Принудительный прогон анализа (правила + AI)","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Analysis","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnalysisResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/rooms/{roomId}/locations":{"get":{"tags":["Admin"],"summary":"Локации участников (GPS-координаты — только admin)","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"path","required":true,"description":"Room id","schema":{"type":"string"}}],"responses":{"200":{"description":"Locations","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/audit":{"get":{"tags":["Admin"],"summary":"Аудит-лог с пагинацией (IP только в виде хэша)","security":[{"apiKey":[]}],"parameters":[{"name":"limit","in":"query","required":false,"description":"Max entries (1..1000)","schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"description":"Pagination offset","schema":{"type":"integer"}},{"name":"type","in":"query","required":false,"description":"Event type","schema":{"type":"string"}},{"name":"severity","in":"query","required":false,"description":"info|warn|critical","schema":{"type":"string"}},{"name":"roomId","in":"query","required":false,"description":"Room filter","schema":{"type":"string"}}],"responses":{"200":{"description":"Entries + total/offset/limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AuditListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}},"description":"Вызывается дашбордом/SIEM. Отдаёт аудит только своего тенанта, IP — в виде хэша; фильтры type/severity/roomId, пагинация limit/offset."}},"/v1/admin/security":{"get":{"tags":["Admin"],"summary":"Обзор безопасности (неудачные join, гео-блоки, подозрительные участники)","security":[{"apiKey":[]}],"responses":{"200":{"description":"Security overview","content":{"application/json":{"schema":{"$ref":"#/components/schemas/SecurityOverview"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/recordings":{"get":{"tags":["Admin"],"summary":"Список записей","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"query","required":false,"description":"Room filter","schema":{"type":"string"}}],"responses":{"200":{"description":"Recordings","content":{"application/json":{"schema":{"type":"object","properties":{"recordings":{"type":"array","items":{"$ref":"#/components/schemas/RecordingRecord"}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/recordings/{id}":{"delete":{"tags":["Admin"],"summary":"Удалить запись","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Recording id","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/files":{"get":{"tags":["Admin"],"summary":"Список файлов","security":[{"apiKey":[]}],"parameters":[{"name":"roomId","in":"query","required":false,"description":"Room filter","schema":{"type":"string"}}],"responses":{"200":{"description":"Files","content":{"application/json":{"schema":{"type":"object","properties":{"files":{"type":"array","items":{"$ref":"#/components/schemas/FileRecord"}}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/ai-agent":{"get":{"tags":["Admin"],"summary":"Настройки AI-агента (секрет — только имя env)","security":[{"apiKey":[]}],"responses":{"200":{"description":"AI agent settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentSettingsResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Обновить настройки AI-агента (merge в session.aiAgent)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["config"],"properties":{"config":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Updated settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AiAgentSettingsResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/knowledge-agent":{"get":{"tags":["Admin"],"summary":"Настройки knowledge-агента","security":[{"apiKey":[]}],"responses":{"200":{"description":"Knowledge agent settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeAgentSettingsResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Обновить настройки knowledge-агента","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["config"],"properties":{"config":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Updated settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeAgentSettingsResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/knowledge/ask":{"post":{"tags":["Admin"],"summary":"Проксировать вопрос корпоративному knowledge-агенту","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeAskRequest"}}}},"responses":{"200":{"description":"Answer with citations","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeAskResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/in-call-agent":{"get":{"tags":["Admin"],"summary":"Настройки in-call ассистента","security":[{"apiKey":[]}],"responses":{"200":{"description":"In-call agent settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InCallAssistantSettings"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Обновить настройки in-call ассистента","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["config"],"properties":{"config":{"type":"object","additionalProperties":true}}}}}},"responses":{"200":{"description":"Updated settings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/InCallAssistantSettings"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/access-policy":{"get":{"tags":["Admin"],"summary":"Политика доступа: права ролей и эффективные фичи","security":[{"apiKey":[]}],"responses":{"200":{"description":"Policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessPolicyResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Обновить политику доступа (аудит access.updated)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["policy"],"properties":{"policy":{"$ref":"#/components/schemas/AccessPolicy"}}}}}},"responses":{"200":{"description":"Policy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccessPolicyResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/webhooks":{"get":{"tags":["Admin"],"summary":"Вебхук-эндпоинты и последние доставки","security":[{"apiKey":[]}],"responses":{"200":{"description":"Webhooks","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhooksResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Заменить вебхук-эндпоинты (SSRF-политика)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["webhooks"],"properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpointConfig"}}}}}}},"responses":{"200":{"description":"Webhooks","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhooksResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/webhooks/test":{"post":{"tags":["Admin"],"summary":"Тестовая доставка security.event вебхука","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["endpointId"],"properties":{"endpointId":{"type":"string"}}}}}},"responses":{"200":{"description":"Delivery outcome","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookTestResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/providers":{"get":{"tags":["Admin"],"summary":"Статус слотов заменяемых провайдеров","security":[{"apiKey":[]}],"responses":{"200":{"description":"Provider slots","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvidersResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Обновить слоты провайдеров (URL проходят SSRF-политику)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["providers"],"properties":{"providers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/ProviderSlot"}}}}}}},"responses":{"200":{"description":"Updated provider slots","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvidersResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/providers/test":{"post":{"tags":["Admin"],"summary":"Проверить слот провайдера (builtin или подписанный тест)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderTestRequest"}}}},"responses":{"200":{"description":"Test outcome with latency","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProviderTestResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/roles":{"get":{"tags":["Admin"],"summary":"Роли: встроенные host/moderator/guest + кастомные","security":[{"apiKey":[]}],"responses":{"200":{"description":"Roles with effective feature lists","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RolesResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"post":{"tags":["Admin"],"summary":"Создать кастомную роль","description":"Вызывается дашбордом/админом компании. Создаёт кастомную роль с набором фич; до 30 ролей, встроенные id зарезервированы.\n\nBuilt-in ids (host/moderator/guest) are reserved; up to 30 custom roles. Effective features are computed on every join/token.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleWriteRequest"},"example":{"id":"streamer","name":"Стример","description":"Ведущий трансляции","baseRole":"moderator","features":["chat","screenShare","liveStreaming"],"canModerate":true,"color":"#7c3aed"}}}},"responses":{"200":{"description":"Created role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDefinition"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/roles/{id}":{"put":{"tags":["Admin"],"summary":"Обновить кастомную роль (встроенные — read-only)","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Role id","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleWriteRequest"},"example":{"id":"streamer","name":"Стример v2","baseRole":"moderator","features":["chat","screenShare"]}}}},"responses":{"200":{"description":"Updated role","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RoleDefinition"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Admin"],"summary":"Удалить кастомную роль (участники откатываются на baseRole)","security":[{"apiKey":[]}],"parameters":[{"name":"id","in":"path","required":true,"description":"Role id","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted + affected active participants","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"affectedParticipants":{"type":"integer"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/assistant/prompts":{"get":{"tags":["Admin"],"summary":"Prompt catalogue for the dashboard mascot assistant roles","security":[{"apiKey":[]}],"responses":{"200":{"description":"Prompt roles","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistantPromptsResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/assistant":{"post":{"tags":["Admin"],"summary":"Dashboard mascot assistant (DeepSeek, local fallback)","description":"Admin-only copilot for the dashboard. DeepSeek answers when `AGIL_DEEPSEEK_API_KEY` is configured; on any error a deterministic local answer is returned with `fallback:true`. History is trimmed to 12 messages / 8000 chars; the key is never returned or logged.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardAssistantRequest"},"example":{"messages":[{"role":"user","content":"Что будет, если выключить запись?"}],"role":"config-guardian","context":{"screen":"settings","tenantId":"demo"}}}}},"responses":{"200":{"description":"Assistant answer (model or local fallback)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DashboardAssistantResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/guard/assess":{"post":{"tags":["Admin"],"summary":"Assess the risk of a critical change before applying it","description":"Guardrail for destructive admin actions: compares the proposed `next` value with the live tenant config (rooms/roles/access/scale/providers/webhooks) and returns risk, findings and a plain-language confirmation message for the mascot.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardAssessRequest"},"example":{"kind":"config","next":{"features":{"recording":false}},"intent":"выключить запись"}}}},"responses":{"200":{"description":"Risk assessment with findings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/GuardAssessResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/docs":{"get":{"tags":["Admin"],"summary":"Documentation CMS: bundled + edited/uploaded docs, versions, default","security":[{"apiKey":[]}],"responses":{"200":{"description":"Documents + defaultName","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocsListResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/docs/upload":{"post":{"tags":["Admin"],"summary":"Upload a document (raw body + x-file-name, or JSON {name,content})","description":"`.md`/`.txt`, ≤200KB; the file name is sanitised (basename, lowercase, no paths). Создаёт custom-копию и версию в истории.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"text/markdown":{"schema":{"type":"string","format":"binary"}},"application/json":{"schema":{"type":"object","required":["name","content"],"properties":{"name":{"type":"string"},"content":{"type":"string"},"title":{"type":"string"}}}}}},"responses":{"200":{"description":"Uploaded document meta","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocContentResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/docs/default":{"put":{"tags":["Admin"],"summary":"Choose the primary document for the panel/docs menu","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocDefaultRequest"},"example":{"name":"api-guide.md"}}}},"responses":{"200":{"description":"New default","content":{"application/json":{"schema":{"type":"object","properties":{"updated":{"type":"boolean"},"defaultName":{"type":"string"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/docs/{name}":{"get":{"tags":["Admin"],"summary":"Read a document (custom copy wins over bundled)","security":[{"apiKey":[]}],"parameters":[{"name":"name","in":"path","required":true,"description":"Document name (e.g. api-guide.md)","schema":{"type":"string"}}],"responses":{"200":{"description":"Document content","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocContentResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Save an edited document (custom copy + version history, ≤200KB)","security":[{"apiKey":[]}],"parameters":[{"name":"name","in":"path","required":true,"description":"Document name","schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocWriteRequest"},"example":{"content":"# AGIL Calls API\n\nОбновлённое описание.","title":"AGIL Calls API"}}}},"responses":{"200":{"description":"Updated document meta","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocContentResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Admin"],"summary":"Reset custom copy to bundled (or delete an uploaded-only doc)","security":[{"apiKey":[]}],"parameters":[{"name":"name","in":"path","required":true,"description":"Document name","schema":{"type":"string"}}],"responses":{"200":{"description":"Reset result","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/docs/{name}/versions":{"get":{"tags":["Admin"],"summary":"Document version history (newest first)","security":[{"apiKey":[]}],"parameters":[{"name":"name","in":"path","required":true,"description":"Document name","schema":{"type":"string"}}],"responses":{"200":{"description":"Versions","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocHistoryResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/docs/{name}/versions/{versionId}":{"get":{"tags":["Admin"],"summary":"Read one historical version (content + meta)","security":[{"apiKey":[]}],"parameters":[{"name":"name","in":"path","required":true,"description":"Document name","schema":{"type":"string"}},{"name":"versionId","in":"path","required":true,"description":"Version id","schema":{"type":"string"}}],"responses":{"200":{"description":"Version + content","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/docs/{name}/versions/{versionId}/restore":{"post":{"tags":["Admin"],"summary":"Restore a historical version as current (current is archived first)","security":[{"apiKey":[]}],"parameters":[{"name":"name","in":"path","required":true,"description":"Document name","schema":{"type":"string"}},{"name":"versionId","in":"path","required":true,"description":"Version id","schema":{"type":"string"}}],"responses":{"200":{"description":"Restored document meta","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DocContentResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/domain":{"get":{"tags":["Admin"],"summary":"Custom white-label domain + DNS instructions","security":[{"apiKey":[]}],"responses":{"200":{"description":"Domain config","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainConfigResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Set the custom domain (format validation; DNS/TLS handled by Caddy)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainConfigRequest"},"example":{"domain":"meet.acme.com"}}}},"responses":{"200":{"description":"Saved (verified=false until DNS verification ships)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainConfigResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Admin"],"summary":"Reset the custom domain","security":[{"apiKey":[]}],"responses":{"200":{"description":"Domain removed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DomainConfigResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/tenants":{"get":{"tags":["Admin"],"summary":"Platform: list SaaS organisations (counts, branding, key presence)","security":[{"apiKey":[]}],"responses":{"200":{"description":"Tenants + platform flag","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantsResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"post":{"tags":["Admin"],"summary":"Platform: onboard a new organisation (config preset, branding, API key once)","description":"Requires `AGIL_PLATFORM_KEY`. tenantId is unique; preset default|corporate|minimal; templateTenantId copies an existing config. Returns the plaintext API key **once**; only its hash is stored in the data dir.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreateRequest"},"example":{"tenantId":"acme","name":"ACME Calls","organizationName":"ACME LLC","branding":{"productName":"ACME Meet","logoUrl":"https://acme.example/logo.png"},"theme":{"scheme":"dark"},"preset":"corporate"}}}},"responses":{"200":{"description":"Created tenant + plaintext API key (once)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreatedResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/tenants/{tenantId}":{"get":{"tags":["Admin"],"summary":"Tenant summary (platform or the tenant itself)","security":[{"apiKey":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"description":"Tenant id","schema":{"type":"string"}}],"responses":{"200":{"description":"Tenant summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantSummary"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"patch":{"tags":["Admin"],"summary":"Update branding/name/theme (platform or the tenant itself)","security":[{"apiKey":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"description":"Tenant id","schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantCreateRequest"},"example":{"tenantId":"acme","name":"ACME Meet","branding":{"productName":"ACME Meet v2"}}}}},"responses":{"200":{"description":"Updated summary","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantSummary"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"delete":{"tags":["Admin"],"summary":"Platform: delete a tenant (config archived, keys revoked, rooms closed; demo protected)","security":[{"apiKey":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"description":"Tenant id","schema":{"type":"string"}}],"responses":{"200":{"description":"Deleted","content":{"application/json":{"schema":{"type":"object","properties":{"deleted":{"type":"boolean"},"tenantId":{"type":"string"}}}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/tenants/{tenantId}/keys":{"post":{"tags":["Admin"],"summary":"Platform: rotate the tenant API key (old dynamic key is revoked)","security":[{"apiKey":[]}],"parameters":[{"name":"tenantId","in":"path","required":true,"description":"Tenant id","schema":{"type":"string"}}],"responses":{"200":{"description":"New plaintext key (once)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TenantKeyResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/scale":{"get":{"tags":["Admin"],"summary":"Статус масштабирования: media mode, кластер, TURN-пул, SFU/вебинары, ограничения MVP","security":[{"apiKey":[]}],"responses":{"200":{"description":"Scale status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScaleStatusResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}},"put":{"tags":["Admin"],"summary":"Обновить конфигурацию масштабирования (media mode, TURN, узлы, SFU, вебинары)","description":"Вызывается админом/DevOps. Обновляет конфигурацию масштабирования (TURN-пул влияет на welcome.iceServers, maxParticipants — на комнаты); кластер/SFU/стриминг только декларируются.\n\nURLs are validated (SSRF policy; TLS required in production mode), secrets are env-variable names only. This updates configuration/status only: cluster/SFU/streaming orchestration is not implemented in the single-node MVP.","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScaleConfig"},"example":{"mediaMode":"sfu","maxParticipants":500,"signaling":{"nodeId":"node-1","stickySessions":true},"turn":[{"id":"turn-msk","urls":["turn:turn-msk.example:3478?transport=udp"],"username":"agil","credentialEnv":"AGIL_TURN_MSK_SECRET","region":"ru-msk","weight":100}]}}}},"responses":{"200":{"description":"Updated scale status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ScaleStatusResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/cluster/status":{"get":{"tags":["Admin"],"summary":"Статус кластера сигналинга (MVP: single-node)","security":[{"apiKey":[]}],"responses":{"200":{"description":"Cluster status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ClusterStatusResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/v1/admin/scale/turn/test":{"post":{"tags":["Admin"],"summary":"Проверить конфигурацию TURN (без реального allocate)","security":[{"apiKey":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["id"],"properties":{"id":{"type":"string"}}}}}},"responses":{"200":{"description":"Configuration check result","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TurnTestResponse"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/openapi.json":{"get":{"tags":["Docs"],"summary":"Эта OpenAPI 3.1 спека (только публичные пути)","responses":{"200":{"description":"OpenAPI spec","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/openapi.admin.json":{"get":{"tags":["Docs"],"summary":"Полная OpenAPI 3.1 спека (admin; только внутренний доступ)","responses":{"200":{"description":"OpenAPI spec","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}},"/docs":{"get":{"tags":["Docs"],"summary":"Офлайн API-эксплорер (self-contained HTML)","responses":{"200":{"description":"HTML","content":{"text/html":{"schema":{"type":"string"}}}},"400":{"description":"Validation error","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"401":{"description":"Missing/invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"403":{"description":"Forbidden (wrong tenant, policy, feature)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"409":{"description":"Conflict (room full/exists)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"413":{"description":"Payload too large","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"423":{"description":"Room is locked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"429":{"description":"Rate limited / lockout","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}},"501":{"description":"Not configured (e.g. server STT)","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiErrorBody"}}}}}}}},"components":{"securitySchemes":{"apiKey":{"type":"apiKey","in":"header","name":"x-api-key","description":"Tenant admin key (AGIL_APY_KEYS)"},"bearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Join token from /v1/rooms/:id/join or an invite"}},"schemas":{"ApiErrorBody":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"string","description":"Stable machine-readable code"},"message":{"type":"string"},"details":{}}}}},"HealthResponse":{"type":"object","properties":{"ok":{"type":"boolean"},"name":{"type":"string"},"version":{"type":"string"},"uptimeSec":{"type":"number"},"rooms":{"type":"number"},"tenants":{"type":"number"},"security":{"type":"object","properties":{"geoEnabled":{"type":"boolean"},"integrityEnabled":{"type":"boolean"},"sttConfigured":{"type":"boolean"},"aiAgentConfigured":{"type":"boolean"},"recordingsDir":{"type":"string"}}}}},"TenantConfig":{"type":"object","description":"Complete tenant configuration (see @agil/protocol tenantConfigSchema)","additionalProperties":true},"TenantConfigPatch":{"type":"object","description":"Deep-partial tenant configuration","additionalProperties":true},"ConfigEnvelope":{"type":"object","required":["config","etag"],"properties":{"config":{"$ref":"#/components/schemas/TenantConfig"},"etag":{"type":"string","description":"sha256 of the config"}}},"IceServer":{"type":"object","required":["urls"],"properties":{"urls":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"username":{"type":"string"},"credential":{"type":"string"}}},"RoomContext":{"type":"object","properties":{"messenger":{"type":"string","description":"telegram|slack|teams|matrix|corp-messenger"},"conversationId":{"type":"string"},"directPeerId":{"type":"string"},"title":{"type":"string"}}},"RoomInfo":{"type":"object","required":["id","tenantId","name","createdAt","locked"],"properties":{"id":{"type":"string"},"tenantId":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"number"},"locked":{"type":"boolean"},"mode":{"type":"string","enum":["direct","group"]},"context":{"$ref":"#/components/schemas/RoomContext"}}},"ParticipantState":{"type":"object","properties":{"mic":{"type":"string","enum":["on","off"]},"cam":{"type":"string","enum":["on","off"]},"screen":{"type":"boolean"},"handRaised":{"type":"boolean"},"network":{"type":"string","enum":["good","fair","poor"]}}},"ParticipantLocation":{"type":"object","required":["source"],"properties":{"country":{"type":"string"},"city":{"type":"string"},"source":{"type":"string","enum":["ip","gps","none"]},"vpnSuspected":{"type":"boolean"},"accuracyM":{"type":"number"}}},"Participant":{"type":"object","required":["id","name","role","joinedAt","state","verified","integrity"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["host","moderator","guest"]},"joinedAt":{"type":"number"},"state":{"$ref":"#/components/schemas/ParticipantState"},"country":{"type":"string"},"verified":{"type":"boolean"},"integrity":{"type":"string","enum":["unknown","verified","suspicious"]},"permissions":{"type":"array","items":{"type":"string"}},"roleName":{"type":"string","description":"Display name of a custom role"},"location":{"$ref":"#/components/schemas/ParticipantLocation"}}},"ChatMessage":{"type":"object","required":["id","roomId","from","text","ts","kind"],"properties":{"id":{"type":"string"},"roomId":{"type":"string"},"from":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["host","moderator","guest"]}}},"text":{"type":"string"},"ts":{"type":"number"},"kind":{"type":"string","enum":["text","system","file"]},"attachment":{"type":"object","properties":{"name":{"type":"string"},"size":{"type":"number"},"mime":{"type":"string"},"url":{"type":"string"}}}}},"CreateRoomRequest":{"type":"object","properties":{"tenantId":{"type":"string"},"roomId":{"type":"string"},"name":{"type":"string"},"password":{"type":"string"},"maxParticipants":{"type":"integer","minimum":2,"maximum":200},"ttlSec":{"type":"integer"},"configOverrides":{"$ref":"#/components/schemas/TenantConfigPatch"},"mode":{"type":"string","enum":["direct","group"],"description":"direct = 1:1 messenger call (max 2 participants); group = default"},"context":{"$ref":"#/components/schemas/RoomContext"}}},"CreateRoomResponse":{"type":"object","required":["room","joinUrl","embedUrl","passwordProtected"],"properties":{"room":{"$ref":"#/components/schemas/RoomInfo"},"joinUrl":{"type":"string"},"embedUrl":{"type":"string"},"token":{"type":"string"},"expiresAt":{"type":"number"},"passwordProtected":{"type":"boolean"}}},"JoinRoomRequest":{"type":"object","properties":{"name":{"type":"string"},"password":{"type":"string"},"participantId":{"type":"string"},"locale":{"type":"string","enum":["ru","en"]},"token":{"type":"string"}}},"JoinRoomResponse":{"type":"object","required":["token","expiresAt","room","participant","config","passwordAccepted"],"properties":{"token":{"type":"string"},"expiresAt":{"type":"number"},"room":{"$ref":"#/components/schemas/RoomInfo"},"participant":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string"}}},"config":{"$ref":"#/components/schemas/TenantConfig"},"passwordAccepted":{"type":"boolean"},"permissions":{"type":"array","items":{"type":"string"}},"media":{"$ref":"#/components/schemas/SfuMediaSession"}}},"TokenRequest":{"type":"object","required":["tenantId","roomId","participant"],"properties":{"tenantId":{"type":"string"},"roomId":{"type":"string"},"participant":{"type":"object","properties":{"name":{"type":"string"},"role":{"type":"string","enum":["host","moderator","guest"]},"participantId":{"type":"string"},"roleId":{"type":"string","description":"Custom role id (security.accessPolicy.customRoles)"}}},"ttlSec":{"type":"integer"},"permissions":{"type":"array","items":{"type":"string"}}}},"TokenResponse":{"type":"object","required":["token","expiresAt","tenantId","roomId","permissions"],"properties":{"token":{"type":"string"},"expiresAt":{"type":"number"},"tenantId":{"type":"string"},"roomId":{"type":"string"},"permissions":{"type":"array","items":{"type":"string"}},"roleId":{"type":"string"},"roleName":{"type":"string"}}},"RoleDefinition":{"type":"object","required":["id","name","description","baseRole","features","canModerate","color","builtin"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"description":{"type":"string"},"baseRole":{"type":"string","enum":["host","moderator","guest"]},"features":{"type":"array","items":{"type":"string"}},"canModerate":{"type":"boolean"},"color":{"type":"string"},"builtin":{"type":"boolean"},"assigned":{"type":"integer","description":"Active participants currently using this role"}}},"RolesResponse":{"type":"object","required":["roles"],"properties":{"roles":{"type":"array","items":{"$ref":"#/components/schemas/RoleDefinition"}}}},"RoleWriteRequest":{"type":"object","required":["id","name","baseRole","features"],"properties":{"id":{"type":"string","description":"lowercase latin, digits, _ and -"},"name":{"type":"string"},"description":{"type":"string"},"baseRole":{"type":"string","enum":["host","moderator","guest"]},"features":{"type":"array","items":{"type":"string"}},"canModerate":{"type":"boolean"},"color":{"type":"string"}}},"AssistantPromptInfo":{"type":"object","required":["role","title","description","starters"],"properties":{"role":{"type":"string","enum":["assistant","config-guardian","security-reviewer","onboarding","api-helper","scaling-advisor","roles-admin"]},"title":{"type":"string"},"description":{"type":"string"},"starters":{"type":"array","items":{"type":"string"}},"systemPrompt":{"type":"string"}}},"AssistantPromptsResponse":{"type":"object","required":["prompts"],"properties":{"prompts":{"type":"array","items":{"$ref":"#/components/schemas/AssistantPromptInfo"}}}},"RoomPasswordRequest":{"type":"object","properties":{"password":{"type":"string","description":"Опустите/пусто — сгенерировать и вернуть один раз"}}},"DocEntry":{"type":"object","required":["name","title","sizeBytes","updatedAt","bundled","custom","isDefault","versions"],"properties":{"name":{"type":"string"},"title":{"type":"string"},"sizeBytes":{"type":"integer"},"updatedAt":{"type":"number"},"bundled":{"type":"boolean"},"custom":{"type":"boolean"},"isDefault":{"type":"boolean"},"versions":{"type":"integer"}}},"DocsListResponse":{"type":"object","required":["docs","defaultName","editable"],"properties":{"docs":{"type":"array","items":{"$ref":"#/components/schemas/DocEntry"}},"defaultName":{"type":"string"},"editable":{"type":"boolean"}}},"DocContentResponse":{"type":"object","required":["name","title","content","updatedAt","bundled","custom","isDefault"],"properties":{"name":{"type":"string"},"title":{"type":"string"},"content":{"type":"string"},"updatedAt":{"type":"number"},"bundled":{"type":"boolean"},"custom":{"type":"boolean"},"isDefault":{"type":"boolean"}}},"DocWriteRequest":{"type":"object","required":["content"],"properties":{"content":{"type":"string"},"title":{"type":"string"}}},"DocVersion":{"type":"object","required":["id","name","createdAt","sizeBytes","author","isCurrent"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"createdAt":{"type":"number"},"sizeBytes":{"type":"integer"},"author":{"type":"string"},"note":{"type":"string"},"isCurrent":{"type":"boolean"}}},"DocHistoryResponse":{"type":"object","required":["name","versions"],"properties":{"name":{"type":"string"},"versions":{"type":"array","items":{"$ref":"#/components/schemas/DocVersion"}}}},"DocDefaultRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string"}}},"TenantSummary":{"type":"object","required":["tenantId","name","organizationName","productName","logoUrl","scheme","rooms","participants","recordings","apiKeyConfigured"],"properties":{"tenantId":{"type":"string"},"name":{"type":"string"},"organizationName":{"type":"string"},"productName":{"type":"string"},"logoUrl":{"type":"string"},"scheme":{"type":"string","enum":["light","dark","auto","auto-light","auto-dark"]},"rooms":{"type":"integer"},"participants":{"type":"integer"},"recordings":{"type":"integer"},"apiKeyConfigured":{"type":"boolean"},"createdAt":{"type":"number"}}},"TenantsResponse":{"type":"object","required":["tenants","platform"],"properties":{"tenants":{"type":"array","items":{"$ref":"#/components/schemas/TenantSummary"}},"platform":{"type":"boolean"}}},"TenantCreateRequest":{"type":"object","required":["tenantId","name"],"properties":{"tenantId":{"type":"string","description":"latin letters, digits, dot, underscore, dash (1..64)"},"name":{"type":"string"},"organizationName":{"type":"string"},"branding":{"type":"object","additionalProperties":true},"theme":{"type":"object","additionalProperties":true},"templateTenantId":{"type":"string"},"preset":{"type":"string","enum":["default","corporate","minimal"]}}},"TenantCreatedResponse":{"type":"object","required":["tenant","apiKey","embedUrl"],"properties":{"tenant":{"$ref":"#/components/schemas/TenantSummary"},"apiKey":{"type":"string","description":"Plaintext key — returned once"},"embedUrl":{"type":"string"}}},"TenantKeyResponse":{"type":"object","required":["tenantId","apiKey"],"properties":{"tenantId":{"type":"string"},"apiKey":{"type":"string","description":"Plaintext key — returned once"}}},"BreakoutRoomInfo":{"type":"object","required":["id","roomId","name","index","participantIds","status"],"properties":{"id":{"type":"string"},"roomId":{"type":"string"},"name":{"type":"string"},"index":{"type":"integer"},"participantIds":{"type":"array","items":{"type":"string"}},"status":{"type":"string","enum":["open","closed"]}}},"BreakoutPlan":{"type":"object","required":["id","mainRoomId","status","mode","rooms","assignments","allowReturn","createdAt"],"properties":{"id":{"type":"string"},"mainRoomId":{"type":"string"},"status":{"type":"string","enum":["active","closed"]},"mode":{"type":"string","enum":["random","manual"]},"rooms":{"type":"array","items":{"$ref":"#/components/schemas/BreakoutRoomInfo"}},"assignments":{"type":"object","additionalProperties":{"type":"string"}},"allowReturn":{"type":"boolean"},"createdAt":{"type":"number"},"endsAt":{"type":"number"},"closedAt":{"type":"number"}}},"BreakoutListResponse":{"type":"object","required":["roomId"],"properties":{"roomId":{"type":"string"},"plan":{"$ref":"#/components/schemas/BreakoutPlan"}}},"BreakoutAssignedMessage":{"type":"object","required":["planId","breakoutRoomId","roomId","name","token","joinUrl"],"properties":{"planId":{"type":"string"},"breakoutRoomId":{"type":"string"},"roomId":{"type":"string"},"name":{"type":"string"},"token":{"type":"string"},"joinUrl":{"type":"string"}}},"PollOptionResult":{"type":"object","required":["id","text","votes","share"],"properties":{"id":{"type":"string"},"text":{"type":"string"},"votes":{"type":"integer"},"share":{"type":"number"},"selected":{"type":"boolean"}}},"RoomPoll":{"type":"object","required":["id","roomId","tenantId","question","options","multiple","anonymous","kind","status","createdAt","totalVotes"],"properties":{"id":{"type":"string"},"roomId":{"type":"string"},"tenantId":{"type":"string"},"question":{"type":"string"},"options":{"type":"array","items":{"$ref":"#/components/schemas/PollOptionResult"}},"multiple":{"type":"boolean"},"anonymous":{"type":"boolean"},"kind":{"type":"string","enum":["poll","qna"]},"status":{"type":"string","enum":["open","closed"]},"createdBy":{"type":"object","additionalProperties":true},"createdAt":{"type":"number"},"closedAt":{"type":"number"},"totalVotes":{"type":"integer"},"voted":{"type":"boolean"}}},"PollListResponse":{"type":"object","required":["roomId","polls"],"properties":{"roomId":{"type":"string"},"polls":{"type":"array","items":{"$ref":"#/components/schemas/RoomPoll"}}}},"PollVoteResponse":{"type":"object","required":["poll","accepted"],"properties":{"poll":{"$ref":"#/components/schemas/RoomPoll"},"accepted":{"type":"boolean"},"reason":{"type":"string"}}},"CreateBreakoutRequest":{"type":"object","properties":{"mode":{"type":"string","enum":["random","manual"]},"rooms":{"type":"array","items":{"type":"object","additionalProperties":true},"minItems":2,"maxItems":20},"count":{"type":"integer"},"durationMin":{"type":"integer"},"allowReturn":{"type":"boolean"}}},"CreatePollRequest":{"type":"object","required":["question","options"],"properties":{"question":{"type":"string"},"options":{"type":"array","items":{"type":"object","required":["text"],"properties":{"text":{"type":"string"}}},"minItems":2,"maxItems":10},"multiple":{"type":"boolean"},"anonymous":{"type":"boolean"},"kind":{"type":"string","enum":["poll","qna"]}}},"VotePollRequest":{"type":"object","required":["optionIds"],"properties":{"optionIds":{"type":"array","items":{"type":"string"}}}},"SfuMediaSession":{"type":"object","required":["mode","url","token","room","canPublish","expiresAt"],"properties":{"mode":{"type":"string","enum":["sfu"]},"url":{"type":"string"},"token":{"type":"string","description":"HS256 LiveKit-compatible JWT"},"room":{"type":"string"},"canPublish":{"type":"boolean"},"expiresAt":{"type":"number"}}},"LobbyRequestInfo":{"type":"object","required":["id","name","createdAt","expiresAt","status"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"country":{"type":"string"},"createdAt":{"type":"number"},"expiresAt":{"type":"number"},"status":{"type":"string","enum":["pending"]}}},"LobbyJoinResponse":{"type":"object","required":["pending","requestId","roomId","status","expiresAt","pollAfterMs"],"properties":{"pending":{"type":"boolean"},"requestId":{"type":"string"},"roomId":{"type":"string"},"status":{"type":"string","enum":["pending"]},"expiresAt":{"type":"number"},"pollAfterMs":{"type":"integer"}}},"LobbyRequestsResponse":{"type":"object","required":["roomId","requests"],"properties":{"roomId":{"type":"string"},"requests":{"type":"array","items":{"$ref":"#/components/schemas/LobbyRequestInfo"}}}},"LobbyStatusResponse":{"type":"object","required":["requestId","status"],"properties":{"requestId":{"type":"string"},"status":{"type":"string","enum":["pending","admitted","rejected","expired"]},"token":{"type":"string","description":"Join token, returned once after admit"},"expiresAt":{"type":"number"},"joinUrl":{"type":"string"},"embedUrl":{"type":"string"},"reason":{"type":"string"}}},"LobbyDecisionResponse":{"type":"object","required":["requestId","status"],"properties":{"requestId":{"type":"string"},"status":{"type":"string","enum":["admitted","rejected"]}}},"DomainConfigRequest":{"type":"object","required":["domain"],"properties":{"domain":{"type":"string","description":"Bare host name, empty to reset"}}},"DomainConfigResponse":{"type":"object","required":["domain","verified","dnsInstructions","docsHint"],"properties":{"domain":{"type":"string"},"verified":{"type":"boolean"},"dnsInstructions":{"type":"object","required":["type","name","value","ttl"],"properties":{"type":{"type":"string","enum":["CNAME"]},"name":{"type":"string"},"value":{"type":"string"},"ttl":{"type":"integer"}}},"docsHint":{"type":"string"}}},"RoomPasswordResponse":{"type":"object","required":["updated","passwordProtected"],"properties":{"updated":{"type":"boolean"},"passwordProtected":{"type":"boolean"},"generated":{"type":"boolean"},"password":{"type":"string","description":"Generated password — shown once"},"removed":{"type":"boolean"}}},"DashboardAssistantRequest":{"type":"object","required":["messages"],"properties":{"messages":{"type":"array","items":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"type":"string"}}}},"role":{"type":"string","enum":["assistant","config-guardian","security-reviewer","onboarding","api-helper","scaling-advisor","roles-admin"]},"context":{"type":"object","properties":{"screen":{"type":"string"},"tenantId":{"type":"string"},"roomId":{"type":"string"},"currentConfig":{"type":"object","additionalProperties":true},"memory":{"type":"string","description":"Excerpts from previous admin chats (≤2000 chars used)"},"chatId":{"type":"string","description":"Chat session id for audit"}}}}},"DashboardAssistantResponse":{"type":"object","required":["reply","role","model","fallback","suggestions"],"properties":{"reply":{"type":"string"},"role":{"type":"string"},"model":{"type":"string"},"fallback":{"type":"boolean"},"risk":{"type":"object","additionalProperties":true},"suggestions":{"type":"array","items":{"type":"string"}}}},"GuardFinding":{"type":"object","required":["id","severity","title","description","impact","affected","requiresConfirmation"],"properties":{"id":{"type":"string"},"severity":{"type":"string","enum":["info","warn","critical"]},"title":{"type":"string"},"description":{"type":"string"},"impact":{"type":"string"},"affected":{"type":"array","items":{"type":"string"}},"requiresConfirmation":{"type":"boolean"}}},"GuardAssessRequest":{"type":"object","required":["kind","next"],"properties":{"kind":{"type":"string","enum":["config","roles","access","scale","providers","webhook","room","integrations"]},"current":{"type":"object","additionalProperties":true},"next":{"type":"object","additionalProperties":true},"intent":{"type":"string"}}},"GuardAssessResponse":{"type":"object","required":["risk","requiresConfirmation","summary","message","findings","recommendations"],"properties":{"risk":{"type":"string","enum":["low","medium","high","critical"]},"requiresConfirmation":{"type":"boolean"},"summary":{"type":"string"},"message":{"type":"string"},"findings":{"type":"array","items":{"$ref":"#/components/schemas/GuardFinding"}},"recommendations":{"type":"array","items":{"type":"string"}}}},"FileRecord":{"type":"object","required":["id","tenantId","roomId","name","size","mime","url","createdAt","expiresAt","uploadedBy"],"properties":{"id":{"type":"string"},"tenantId":{"type":"string"},"roomId":{"type":"string"},"name":{"type":"string"},"size":{"type":"number"},"mime":{"type":"string"},"url":{"type":"string"},"createdAt":{"type":"number"},"expiresAt":{"type":"number"},"uploadedBy":{"type":"string"}}},"RecordingRecord":{"type":"object","required":["id","tenantId","roomId","mime","size","durationSec","url","createdAt","createdBy"],"properties":{"id":{"type":"string"},"tenantId":{"type":"string"},"roomId":{"type":"string"},"mime":{"type":"string"},"size":{"type":"number"},"durationSec":{"type":"number"},"url":{"type":"string"},"createdAt":{"type":"number"},"createdBy":{"type":"string"},"transcript":{"type":"string"}}},"SttResponse":{"type":"object","required":["text","provider"],"properties":{"text":{"type":"string"},"provider":{"type":"string","enum":["browser","server","stub"]},"language":{"type":"string"},"durationSec":{"type":"number"},"segments":{"type":"array","items":{"type":"object","properties":{"start":{"type":"number"},"end":{"type":"number"},"text":{"type":"string"}}}}}},"InviteLink":{"type":"object","required":["roomId","joinUrl","embedUrl","token","expiresAt","passwordProtected"],"properties":{"roomId":{"type":"string"},"joinUrl":{"type":"string"},"embedUrl":{"type":"string"},"token":{"type":"string"},"expiresAt":{"type":"number"},"passwordProtected":{"type":"boolean"}}},"AdminOverview":{"type":"object","properties":{"tenantId":{"type":"string"},"serverTime":{"type":"number"},"uptimeSec":{"type":"number"},"activeRooms":{"type":"number"},"activeParticipants":{"type":"number"},"totalRoomsCreated":{"type":"number"},"recordings":{"type":"number"},"sharedFiles":{"type":"number"},"securityEvents24h":{"type":"number"},"countries":{"type":"object","additionalProperties":{"type":"number"}}}},"AdminRoomSummary":{"type":"object","required":["room","participants","maxParticipants","passwordProtected","createdAt","lastActivityAt","recordings","joinUrl","embedUrl"],"properties":{"room":{"$ref":"#/components/schemas/RoomInfo"},"participants":{"type":"number"},"maxParticipants":{"type":"number"},"passwordProtected":{"type":"boolean"},"createdAt":{"type":"number"},"lastActivityAt":{"type":"number"},"recordings":{"type":"number"},"joinUrl":{"type":"string"},"embedUrl":{"type":"string"}}},"RoomDetail":{"type":"object","required":["room","participants","messages","passwordProtected","createdAt","lastActivityAt","joinUrl","embedUrl"],"properties":{"room":{"$ref":"#/components/schemas/RoomInfo"},"participants":{"type":"array","items":{"$ref":"#/components/schemas/Participant"}},"messages":{"type":"array","items":{"$ref":"#/components/schemas/ChatMessage"}},"passwordProtected":{"type":"boolean"},"createdAt":{"type":"number"},"lastActivityAt":{"type":"number"},"joinUrl":{"type":"string"},"embedUrl":{"type":"string"}}},"TranscriptResponse":{"type":"object","required":["roomId","segments","updatedAt"],"properties":{"roomId":{"type":"string"},"segments":{"type":"array","items":{"type":"object","additionalProperties":true}},"updatedAt":{"type":"number"}}},"ChatPostRequest":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"1..4000 characters"},"kind":{"type":"string","enum":["text","system"]},"from":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"role":{"type":"string","enum":["host","moderator","guest"]}}},"id":{"type":"string","description":"Idempotency key"}}},"ChatPostResponse":{"type":"object","required":["message"],"properties":{"message":{"$ref":"#/components/schemas/ChatMessage"}}},"ComplianceFinding":{"type":"object","additionalProperties":true,"description":"ComplianceFinding from @agil/protocol"},"MeetingNotes":{"type":"object","additionalProperties":true,"description":"MeetingNotes (summary, verbatim excerpts, action items)"},"AnalysisResponse":{"type":"object","required":["roomId","report","findings","notes"],"properties":{"roomId":{"type":"string"},"report":{"type":["object","null"],"additionalProperties":true},"findings":{"type":"array","items":{"$ref":"#/components/schemas/ComplianceFinding"}},"notes":{"oneOf":[{"$ref":"#/components/schemas/MeetingNotes"},{"type":"null"}]}}},"AuditEntry":{"type":"object","required":["id","ts","type","severity","message"],"properties":{"id":{"type":"string"},"ts":{"type":"number"},"type":{"type":"string"},"severity":{"type":"string","enum":["info","warn","critical"]},"tenantId":{"type":"string"},"roomId":{"type":"string"},"participantId":{"type":"string"},"ipHash":{"type":"string"},"country":{"type":"string"},"message":{"type":"string"},"details":{"type":"object","additionalProperties":true}}},"AuditListResponse":{"type":"object","required":["entries","total","offset","limit"],"properties":{"entries":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"}},"total":{"type":"number"},"offset":{"type":"number"},"limit":{"type":"number"}}},"SecurityOverview":{"type":"object","properties":{"tenantId":{"type":"string"},"events":{"type":"array","items":{"$ref":"#/components/schemas/AuditEntry"}},"failedJoins24h":{"type":"number"},"blockedJoins24h":{"type":"number"},"suspiciousParticipants":{"type":"number"},"countries":{"type":"object","additionalProperties":{"type":"number"}}}},"AccessPolicy":{"type":"object","additionalProperties":true,"description":"AccessPolicy: mode, roleDefaults, deniedFeatures, userOverrides"},"AccessPolicyResponse":{"type":"object","required":["policy","featureKeys","effective"],"properties":{"policy":{"$ref":"#/components/schemas/AccessPolicy"},"featureKeys":{"type":"array","items":{"type":"string"}},"effective":{"type":"object","properties":{"host":{"type":"array","items":{"type":"string"}},"moderator":{"type":"array","items":{"type":"string"}},"guest":{"type":"array","items":{"type":"string"}}}}}},"AiAgentSettingsResponse":{"type":"object","required":["config","endpointConfigured","apiKeyConfigured"],"properties":{"config":{"type":"object","additionalProperties":true},"endpointConfigured":{"type":"boolean"},"apiKeyConfigured":{"type":"boolean"}}},"KnowledgeAgentSettingsResponse":{"type":"object","required":["config","endpointConfigured","apiKeyConfigured"],"properties":{"config":{"type":"object","additionalProperties":true},"endpointConfigured":{"type":"boolean"},"apiKeyConfigured":{"type":"boolean"}}},"KnowledgeAskRequest":{"type":"object","required":["question"],"properties":{"question":{"type":"string"},"userId":{"type":"string"},"role":{"type":"string","enum":["host","moderator","guest"]},"roomId":{"type":"string"},"locale":{"type":"string","enum":["ru","en"]}}},"KnowledgeCitation":{"type":"object","required":["title","url"],"properties":{"title":{"type":"string"},"url":{"type":"string"},"snippet":{"type":"string"}}},"KnowledgeAskResponse":{"type":"object","required":["answer","citations"],"properties":{"answer":{"type":"string"},"citations":{"type":"array","items":{"$ref":"#/components/schemas/KnowledgeCitation"}},"confidence":{"type":"number"},"provider":{"type":"string"},"model":{"type":"string"},"refused":{"type":"boolean"}}},"WebhookEndpointConfig":{"type":"object","required":["id","url","events","secretEnv","enabled","retries","timeoutMs"],"properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}},"secretEnv":{"type":"string"},"enabled":{"type":"boolean"},"retries":{"type":"integer"},"timeoutMs":{"type":"integer"},"description":{"type":"string"}}},"WebhookDeliveryRecord":{"type":"object","properties":{"id":{"type":"string"},"endpointId":{"type":"string"},"type":{"type":"string"},"status":{"type":"string","enum":["delivered","failed","retrying"]},"attempts":{"type":"number"},"ts":{"type":"number"},"lastError":{"type":"string"},"statusCode":{"type":"number"}}},"WebhooksResponse":{"type":"object","required":["webhooks","recentDeliveries"],"properties":{"webhooks":{"type":"array","items":{"$ref":"#/components/schemas/WebhookEndpointConfig"}},"recentDeliveries":{"type":"array","items":{"$ref":"#/components/schemas/WebhookDeliveryRecord"}}}},"WebhookTestResponse":{"type":"object","required":["endpointId","status"],"properties":{"endpointId":{"type":"string"},"status":{"type":"string","enum":["delivered","failed"]},"statusCode":{"type":"number"},"error":{"type":"string"}}},"ProviderSlot":{"type":"object","required":["mode","providerName","endpoint","apiKeyEnv","timeoutMs","fallback"],"properties":{"mode":{"type":"string","enum":["builtin","external","disabled"]},"providerName":{"type":"string","description":"Display name, e.g. corp-messenger"},"endpoint":{"type":"string","description":"Signed JSON envelope endpoint for external providers"},"apiKeyEnv":{"type":"string","description":"Env variable name holding the HMAC secret"},"timeoutMs":{"type":"integer","minimum":200,"maximum":30000},"fallback":{"type":"string","enum":["builtin","fail"]},"options":{"type":"object","additionalProperties":true}}},"ProvidersConfig":{"type":"object","properties":{"chat":{"$ref":"#/components/schemas/ProviderSlot"},"files":{"$ref":"#/components/schemas/ProviderSlot"},"stt":{"$ref":"#/components/schemas/ProviderSlot"},"notifications":{"$ref":"#/components/schemas/ProviderSlot"},"recording":{"$ref":"#/components/schemas/ProviderSlot"},"backgrounds":{"$ref":"#/components/schemas/ProviderSlot"}}},"ProviderStatus":{"type":"object","properties":{"slot":{"type":"string","enum":["chat","files","stt","notifications","recording","backgrounds"]},"mode":{"type":"string","enum":["builtin","external","disabled"]},"providerName":{"type":"string"},"configured":{"type":"boolean"},"available":{"type":"boolean"},"fallback":{"type":"string","enum":["builtin","fail"]},"note":{"type":"string"}}},"ProvidersResponse":{"type":"object","required":["providers"],"properties":{"providers":{"type":"array","items":{"$ref":"#/components/schemas/ProviderStatus"}}}},"ProviderTestRequest":{"type":"object","required":["slot"],"properties":{"slot":{"type":"string","enum":["chat","files","stt","notifications","recording","backgrounds"]},"payload":{"type":"object","additionalProperties":true}}},"ProviderTestResponse":{"type":"object","required":["slot","ok","providerName","latencyMs"],"properties":{"slot":{"type":"string"},"ok":{"type":"boolean"},"providerName":{"type":"string"},"latencyMs":{"type":"number"},"detail":{"type":"string"}}},"BackgroundItem":{"type":"object","required":["id","name","url"],"properties":{"id":{"type":"string"},"name":{"type":"string"},"url":{"type":"string"}}},"BackgroundsResponse":{"type":"object","required":["backgrounds","provider"],"properties":{"backgrounds":{"type":"array","items":{"$ref":"#/components/schemas/BackgroundItem"}},"provider":{"type":"string"}}},"AssistantAction":{"type":"object","required":["tool"],"properties":{"tool":{"type":"string","enum":["start_recording","stop_recording","toggle_mic","toggle_camera","toggle_screen_share","raise_hand","send_chat","open_chat","open_files","open_participants","open_notes","open_settings","set_blur","minimize","restore","request_fullscreen","open_new_tab","copy_invite_link"]},"args":{"type":"object","additionalProperties":true}}},"AssistantSpotlight":{"type":"object","required":["target","text"],"properties":{"target":{"type":"string"},"text":{"type":"string"},"step":{"type":"integer"}}},"AssistantReply":{"type":"object","required":["id","text","actions","spotlight","source","ts"],"properties":{"id":{"type":"string"},"text":{"type":"string"},"actions":{"type":"array","items":{"$ref":"#/components/schemas/AssistantAction"}},"spotlight":{"type":"array","items":{"$ref":"#/components/schemas/AssistantSpotlight"}},"source":{"type":"string","enum":["local","external"]},"ts":{"type":"number"}}},"InCallAssistantState":{"type":"object","properties":{"participants":{"type":"integer"},"recording":{"type":"boolean"},"mic":{"type":"string","enum":["on","off"]},"camera":{"type":"string","enum":["on","off"]},"screenSharing":{"type":"boolean"},"chatOpen":{"type":"boolean"},"layoutMode":{"type":"string"},"qualityTier":{"type":"string"}}},"InCallAssistantRequest":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"1..2000 characters"},"locale":{"type":"string","enum":["ru","en"]},"state":{"$ref":"#/components/schemas/InCallAssistantState"}}},"InCallAssistantSettings":{"type":"object","required":["config","endpointConfigured","apiKeyConfigured"],"properties":{"config":{"type":"object","additionalProperties":true},"endpointConfigured":{"type":"boolean"},"apiKeyConfigured":{"type":"boolean"}}},"ScaleConfig":{"type":"object","additionalProperties":true,"description":"TenantConfig.scale: mediaMode, signaling, sfu, turn pool, webinar, streaming, cdn"},"ScaleClusterNode":{"type":"object","required":["id","url","region","weight"],"properties":{"id":{"type":"string"},"url":{"type":"string"},"region":{"type":"string"},"weight":{"type":"number"},"healthy":{"type":["boolean","null"]},"note":{"type":"string"}}},"ScaleTurnStatus":{"type":"object","required":["id","urls","region","weight","usernameConfigured","credentialConfigured"],"properties":{"id":{"type":"string"},"urls":{"type":"array","items":{"type":"string"}},"region":{"type":"string"},"weight":{"type":"number"},"usernameConfigured":{"type":"boolean"},"credentialConfigured":{"type":"boolean"}}},"ScaleStatusResponse":{"type":"object","required":["config","mediaMode","cluster","turn","sfuConfigured","webinarEnabled","streamingProvider","limitations"],"properties":{"config":{"$ref":"#/components/schemas/ScaleConfig"},"mediaMode":{"type":"string","enum":["mesh","sfu","broadcast"]},"cluster":{"type":"object","properties":{"nodeId":{"type":"string"},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/ScaleClusterNode"}},"strategy":{"type":"string"},"redisConfigured":{"type":"boolean"},"stickySessions":{"type":"boolean"}}},"turn":{"type":"array","items":{"$ref":"#/components/schemas/ScaleTurnStatus"}},"sfuConfigured":{"type":"boolean"},"webinarEnabled":{"type":"boolean"},"streamingProvider":{"type":"string"},"limitations":{"type":"array","items":{"type":"string"}}}},"ClusterStatusResponse":{"type":"object","required":["nodeId","nodes","strategy","redisConfigured","stickySessions","multiNodeActive"],"properties":{"nodeId":{"type":"string"},"nodes":{"type":"array","items":{"$ref":"#/components/schemas/ScaleClusterNode"}},"strategy":{"type":"string"},"redisConfigured":{"type":"boolean"},"stickySessions":{"type":"boolean"},"multiNodeActive":{"type":"boolean"}}},"TurnTestResponse":{"type":"object","required":["id","ok","latencyMs","detail"],"properties":{"id":{"type":"string"},"ok":{"type":"boolean"},"latencyMs":{"type":"number"},"detail":{"type":"string"}}}}}}