{"openapi":"3.1.0","info":{"title":"Hubris API","version":"1.0.0","description":"OpenAI-совместимый API российского LLM-агрегатора. Все цены в рублях.\n\nВерсии и вывод из эксплуатации (deprecation policy): несовместимые изменения — только в новой версии префикса (`/v2`); об отключении эндпоинта или поля предупреждаем не меньше чем за 90 дней заголовками `Deprecation` (RFC 9745) и `Sunset` (RFC 8594), записью в журнале изменений и письмом. Подробно: https://hubris.pw/docs/api/versioning"},"servers":[{"url":"https://api.hubris.pw","description":"Production"}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"sk-gw-...","description":"API-ключ в формате `sk-gw-` + 32 hex. Создаётся в дашборде на /keys. Обычный ключ даёт все права, ключ только для чтения не может тратить баланс."},"oauth2":{"type":"oauth2","description":"OAuth-токен приложения с ограниченными правами. Регистрация клиента — `POST /oauth/clients` (RFC 7591), PKCE S256 обязателен. Метаданные: `/.well-known/oauth-authorization-server`, `/.well-known/oauth-protected-resource`.","flows":{"authorizationCode":{"authorizationUrl":"https://api.hubris.pw/oauth/authorize","tokenUrl":"https://api.hubris.pw/oauth/token","refreshUrl":"https://api.hubris.pw/oauth/token","scopes":{"chat:write":"Запросы к моделям от имени пользователя (списывают баланс): чат, Responses, Messages, эмбеддинги, реранкеры, модели решений, изображения, распознавание и озвучка речи, расшифровка видео; коннекторы Битрикс24.","models:read":"Видеть цепочки резервных моделей пользователя в `GET /v1/models`.","balance:read":"Видеть остаток баланса пользователя.","videos:write":"Создавать видео от имени пользователя (`POST /v1/videos`, резервирует и списывает баланс).","videos:read":"Узнавать статус и скачивать видео пользователя (`GET /v1/videos/{id}`, `GET /v1/videos/{id}/content`).","offline_access":"Выдать refresh-токен, чтобы подключение жило 90 дней без повторного входа."}}}}},"schemas":{"TranscriptionResponse":{"type":"object","properties":{"text":{"type":"string","description":"Распознанный текст. Пустая строка — тоже результат: в записи тишина."},"usage":{"type":"object","properties":{"seconds":{"type":"number","description":"Длительность обработанного аудио в секундах, если модель её сообщает."},"input_tokens":{"type":"integer"},"output_tokens":{"type":"integer"},"total_tokens":{"type":"integer"},"cost":{"type":"integer","description":"Списано с баланса, в копейках."}}}},"required":["text"]},"TranscriptionMultipartRequest":{"type":"object","properties":{"file":{"type":"string","format":"binary","description":"Аудиофайл: WAV, MP3, FLAC, M4A, OGG, WebM, AAC. До 25 МБ."},"model":{"type":"string","minLength":1,"example":"openai/whisper-1"},"language":{"type":"string","description":"Язык записи в ISO-639-1 (`ru`, `en`). Без поля язык определяется сам."},"prompt":{"type":"string","description":"Подсказка: имена, термины, аббревиатуры, которые встречаются в записи."},"temperature":{"type":"number"},"response_format":{"type":"string","enum":["json","verbose_json"],"description":"`text`, `srt` и `vtt` не поддерживаются (400). Поддержка `verbose_json` зависит от модели."},"timestamp_granularities[]":{"type":"array","items":{"type":"string","enum":["segment","word"]},"description":"Таймкоды в `verbose_json`; поддерживаются не всеми моделями."}},"required":["file","model"]},"TranscriptionJsonRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"example":"openai/whisper-1"},"input_audio":{"type":"object","properties":{"data":{"type":"string","minLength":1,"description":"Аудио в base64 (без data:-префикса)."},"format":{"type":"string","minLength":1,"description":"Формат: wav, mp3, flac, m4a, ogg, webm, aac.","example":"mp3"}},"required":["data","format"],"description":"Аудио для распознавания. Прямые URL не поддерживаются."}},"required":["model","input_audio"]},"SpeechRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"example":"microsoft/mai-voice-2-flash"},"input":{"type":"string","minLength":1,"maxLength":50000,"description":"Текст для озвучки. Цена — по единице модели в каталоге: за символы текста или за токены (у Gemini 25 токенов на секунду звука).","example":"Привет! Это проверка озвучки."},"voice":{"type":"string","minLength":1,"description":"Голос модели. Список — в карточке модели каталога (поле «Голоса»); обязателен, если список есть.","example":"en-US-Harper:MAI-Voice-2"},"response_format":{"type":"string","enum":["mp3","pcm"],"description":"Формат аудио: mp3 или pcm (16-bit LE). Без поля формат выбирает модель, как правило pcm."}},"required":["model","input"]},"VideoJobCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid","description":"Номер задачи.","example":"b0f2c1a4-3e9d-4b7a-9c2e-8f1a6d5c4b3a"},"status":{"type":"string","enum":["pending"]},"polling_url":{"type":"string","format":"uri","description":"Адрес опроса статуса — `GET /v1/videos/{id}`."},"created":{"type":"integer","description":"Время создания задачи, Unix-секунды."}},"required":["id","status","polling_url","created"]},"VideoFrameImage":{"type":"object","properties":{"type":{"type":"string","enum":["image_url"]},"image_url":{"type":"object","properties":{"url":{"type":"string","minLength":1}},"required":["url"],"additionalProperties":false},"frame_type":{"type":"string","enum":["first_frame","last_frame"]}},"required":["type","image_url","frame_type"],"additionalProperties":false},"VideoInputReference":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["image_url"]},"image_url":{"type":"object","properties":{"url":{"type":"string","minLength":1}},"required":["url"],"additionalProperties":false}},"required":["type","image_url"],"additionalProperties":false},{"type":"object","properties":{"type":{"type":"string","enum":["video_url"]},"video_url":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2048}},"required":["url"],"additionalProperties":false}},"required":["type","video_url"],"additionalProperties":false}]},"CreateVideoRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"maxLength":200,"example":"kwaivgi/kling-v3.0-pro"},"prompt":{"type":"string","minLength":1,"maxLength":50000},"duration":{"type":"integer","minimum":1,"maximum":60},"resolution":{"type":"string","maxLength":10},"aspect_ratio":{"type":"string","maxLength":10},"size":{"type":"string","maxLength":16},"generate_audio":{"type":"boolean"},"seed":{"type":"integer"},"frame_images":{"type":"array","items":{"$ref":"#/components/schemas/VideoFrameImage"},"maxItems":2},"input_references":{"type":"array","items":{"$ref":"#/components/schemas/VideoInputReference"},"minItems":1,"maxItems":4},"upscale_factor":{"type":"number","minimum":0,"exclusiveMinimum":true},"creativity":{"type":"number","minimum":0,"maximum":1},"provider":{"type":"object","properties":{"options":{"type":"object","additionalProperties":{"type":"object","properties":{"parameters":{"type":"object","additionalProperties":{"nullable":true}}},"required":["parameters"],"additionalProperties":false}}},"required":["options"],"additionalProperties":false}},"required":["model","prompt"],"additionalProperties":false},"VideoJob":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"status":{"type":"string","enum":["pending","in_progress","completed","failed"]},"created":{"type":"integer","description":"Время создания задачи, Unix-секунды."},"unsigned_urls":{"type":"array","items":{"type":"string","format":"uri"},"description":"Только при `completed`: адрес скачивания `GET /v1/videos/{id}/content?index=0`. Несмотря на имя, нужен тот же ключ."},"usage":{"type":"object","properties":{"cost":{"type":"integer","description":"При `completed`: итоговое списание, копейки."},"estimated_cost":{"type":"integer","description":"Пока задача в работе: сумма, удержанная под задачу, копейки (верхняя оценка; если сверка прошла раньше готовности — уже списанная). После готовности приходит `cost`, разница возвращается на баланс."}}},"error":{"type":"string","description":"Только при `failed`: нейтральный текст. Удержание возвращается целиком."}},"required":["id","status","created"]},"VideoTranscription":{"type":"object","properties":{"id":{"type":"string","example":"vtr-3f9c1a7b2d4e5f60a1b2c3d4"},"object":{"type":"string","enum":["video.transcription"]},"created":{"type":"integer","description":"Unix-секунды."},"model":{"type":"string","description":"Модель, которая смотрела ролик."},"video":{"type":"object","properties":{"id":{"type":"string","description":"ID ролика на YouTube."},"title":{"type":"string"},"duration_sec":{"type":"integer"}},"required":["id","title","duration_sec"]},"mode":{"type":"string","enum":["exact","fast"]},"diarize":{"type":"boolean","description":"В режиме `fast` всегда `false`."},"text":{"type":"string","description":"Расшифровка или пересказ."},"truncated":{"type":"boolean","description":"`true` — текст оборвался по лимиту длины ответа даже после продолжений, или продолжение не удалось и отдано собранное."},"usage":{"type":"object","properties":{"prompt_tokens":{"type":"integer"},"completion_tokens":{"type":"integer"},"total_tokens":{"type":"integer"},"cost":{"type":"integer","description":"Списано с баланса за все запросы к модели, копейки."},"requests":{"type":"integer","description":"Сколько запросов к модели понадобилось."}},"required":["prompt_tokens","completion_tokens","total_tokens","cost","requests"]}},"required":["id","object","created","model","video","mode","diarize","text","truncated","usage"]},"VideoTranscriptionRequest":{"type":"object","properties":{"url":{"type":"string","minLength":1,"maxLength":2000,"description":"Ссылка на ролик YouTube: `youtube.com/watch?v=…`, `youtu.be/…`, `youtube.com/shorts/…`, `youtube.com/live/…`.","example":"https://youtu.be/ITL6WqcV6sE"},"mode":{"type":"string","enum":["exact","fast"],"default":"exact","description":"`exact` — дословная расшифровка, каждая реплика с новой строки и таймкодом `[HH:MM:SS]`. `fast` — пересказ и ключевые мысли с таймкодами: быстрее и дешевле на длинном ролике, таймкоды приблизительные."},"diarize":{"type":"boolean","default":false,"description":"Только для `exact`: помечать реплики говорящими («Говорящий 1:» или имя, если оно звучит в ролике)."}},"required":["url"]},"Bitrix24ConnectorCreated":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"completions_url":{"type":"string","format":"uri","description":"Адрес для `completions_url` при регистрации движка в Битрикс24 (`ai.engine.register`). Содержит секрет и показывается один раз."},"model":{"type":"string"},"key_prefix":{"type":"string","description":"Маскированный префикс выпущенного ключа.","example":"sk-gw-a1b2...c3d4"}},"required":["id","completions_url","model","key_prefix"]},"Bitrix24ConnectorCreateRequest":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":60,"description":"Имя подключения: видно в кабинете и в имени выпущенного ключа «Битрикс24 · <имя>».","example":"Отдел продаж"},"model":{"type":"string","minLength":1,"maxLength":200,"description":"Полный ID модели каталога. Битрикс24 модель не передаёт, она закрепляется за коннектором.","example":"anthropic/claude-sonnet-5"},"limit_kopecks":{"type":"integer","minimum":100,"maximum":10000000,"description":"Дневной лимит расхода выпущенного ключа, копейки.","example":50000}},"required":["name","model"]},"Bitrix24Connector":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"model":{"type":"string"},"key_prefix":{"type":"string","example":"sk-gw-a1b2...c3d4"},"created_at":{"type":"string","format":"date-time"},"last_used_at":{"type":"string","nullable":true,"format":"date-time"}},"required":["id","name","model","key_prefix","created_at","last_used_at"]},"Bitrix24ConnectorList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Bitrix24Connector"}}},"required":["data"]},"Bitrix24ConnectorDeleted":{"type":"object","properties":{"deleted":{"type":"boolean","enum":[true]}},"required":["deleted"]},"Model":{"type":"object","properties":{"id":{"type":"string","example":"anthropic/claude-haiku-4.5"},"object":{"type":"string","enum":["model"]},"created":{"type":"integer","description":"Unix-timestamp последнего обновления записи в каталоге Hubris."},"owned_by":{"type":"string","example":"anthropic"},"display_name":{"type":"string","example":"Claude Haiku 4.5"},"description":{"type":"string","nullable":true,"description":"Описание модели на русском языке (если переведено)."},"context_window":{"type":"integer","example":200000},"context_length":{"type":"integer","description":"То же, что `context_window`, — под именем, которое читают многие OpenAI-совместимые клиенты (RAGFlow и другие).","example":200000},"modalities":{"type":"array","items":{"type":"string"},"description":"Legacy OpenAI поле — равно `output_modalities`. Используйте `output_modalities` / `input_modalities` для точного фильтра.","example":["text","image"]},"input_modalities":{"type":"array","items":{"type":"string"},"description":"Что модель принимает на вход: `text`, `image`, `audio`, `file`.","example":["text","image"]},"output_modalities":{"type":"array","items":{"type":"string"},"description":"Что модель возвращает: `text` (chat / responses), `embeddings` (только /v1/embeddings), `image`, `audio`.","example":["text"]},"supported_parameters":{"type":"array","items":{"type":"string"},"description":"Параметры запроса, которые поддерживает модель: `tools`, `tool_choice`, `reasoning`, `include_reasoning`, `response_format`, `structured_outputs`, `temperature`, `top_p`, `seed`, `stop`, `web_search_options` и другие. Клиент по этому списку решает, показывать ли настройки инструментов и размышления для конкретной модели, а не включает их вслепую. Пустой массив — список для модели неизвестен.","example":["tools","tool_choice","reasoning","temperature","max_tokens","response_format","structured_outputs"]},"supported_voices":{"type":"array","items":{"type":"string"},"description":"Голоса модели озвучки (только у моделей с `output_modalities: [\"speech\"]`). Значение для поля `voice` в POST /v1/audio/speech.","example":["en-US-Harper:MAI-Voice-2"]},"pricing":{"type":"object","properties":{"unit":{"type":"string","enum":["token","unit","unknown"],"description":"Единица тарификации. `token` — цены в `input_rub_per_million` / `output_rub_per_million` за 1М токенов. `unit` — тарификация в других единицах (изображение, мегапиксель, минута, секунда видео), реальная цена в `per_unit`, а токенные поля равны нулю. `unknown` — провайдер не публикует тариф, списывается фактическая стоимость запроса. Считайте бюджет по этому полю: у нетокенных моделей нельзя умножать `input_rub_per_million` на число токенов.","example":"token"},"input_rub_per_million":{"type":"number","description":"Цена за 1М входных токенов. Осмысленна только при `unit: \"token\"`; иначе 0 — смотрите `per_unit`.","example":30.45},"output_rub_per_million":{"type":"number","description":"Цена за 1М выходных токенов. Осмысленна только при `unit: \"token\"`; иначе 0 — смотрите `per_unit`.","example":152.25},"currency":{"type":"string","enum":["RUB"]},"per_unit":{"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","example":"Output Image"},"price_rub":{"type":"number","example":3.6},"unit":{"type":"string","example":"per megapixel"}},"required":["sku","price_rub","unit"]},"description":"Цены за единицу (изображение, мегапиксель, reference). Присутствует только для моделей с unit-pricing — Flux, Recraft, Sourceful, Gemini Image."},"is_free":{"type":"boolean","description":"Бесплатна ли модель. Определяет сервер: нулевые цены во ВСЕХ единицах тарификации и немедийный выход. Ориентируйтесь на этот флаг, а не на `input_rub_per_million === 0`: у моделей с оплатой за изображение или секунду видео цена за токены нулевая, но запрос платный.","example":false}},"required":["unit","input_rub_per_million","output_rub_per_million","currency","is_free"]}},"required":["id","object","created","owned_by","display_name","description","context_window","context_length","modalities","input_modalities","output_modalities","supported_parameters","pricing"]},"ModelsList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Model"}}},"required":["object","data"]},"ErrorCode":{"type":"string","enum":["invalid_request","invalid_api_key","insufficient_balance","daily_limit_exceeded","model_not_found","exchange_rate_unavailable","upstream_error","upstream_timeout","too_many_active_jobs","video_not_ready","index_out_of_range","byok_disabled","byok_egress_unavailable","byok_not_configured","byok_insufficient_credits","byok_not_supported_for_videos"]},"ErrorObject":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"$ref":"#/components/schemas/ErrorCode"},"param":{"type":"string","nullable":true}},"required":["message","type","code"]},"ModelsErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorObject"}},"required":["error"]},"VideoModel":{"type":"object","properties":{"id":{"type":"string","example":"kwaivgi/kling-v3.0-pro"},"object":{"type":"string","enum":["video_model"]},"created":{"type":"integer","description":"Unix-timestamp последнего обновления записи в каталоге Hubris."},"owned_by":{"type":"string","example":"kwaivgi"},"display_name":{"type":"string","example":"Kling v3.0 Pro"},"description":{"type":"string","nullable":true,"description":"Описание модели на русском языке (если переведено)."},"supported_resolutions":{"type":"array","items":{"type":"string"},"example":["720p","1080p"]},"supported_aspect_ratios":{"type":"array","items":{"type":"string"},"example":["16:9","9:16"]},"supported_sizes":{"type":"array","items":{"type":"string"},"example":["1280x720"]},"supported_durations":{"type":"array","items":{"type":"integer"},"example":[5,8]},"supported_frame_images":{"type":"array","items":{"type":"string"},"description":"Какие опорные кадры принимает модель для image-to-video.","example":["first_frame"]},"generate_audio":{"type":"boolean","description":"Поддерживает ли модель генерацию звука."},"seed":{"type":"boolean","description":"Поддерживает ли модель детерминированный seed."},"required_input":{"type":"string","nullable":true,"enum":["video","image"],"description":"Что модели обязательно передать в input_references: исходное видео или фото. null — вход не нужен."},"upscale_factor":{"type":"object","nullable":true,"properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"]},"creativity":{"type":"object","nullable":true,"properties":{"min":{"type":"number"},"max":{"type":"number"}},"required":["min","max"]},"allowed_passthrough_parameters":{"type":"array","items":{"type":"string"},"description":"Ключи, которые можно передать в provider.options.<поставщик>.parameters."},"pricing":{"type":"object","properties":{"per_unit":{"type":"array","items":{"type":"object","properties":{"sku":{"type":"string","example":"video"},"price_rub":{"type":"number","example":10.33},"unit":{"type":"string","example":"second"}},"required":["sku","price_rub","unit"]},"description":"Цены за единицу в рублях (секунда/видео). Апстрим-цены в USD не раскрываются."},"currency":{"type":"string","enum":["RUB"]}},"required":["per_unit","currency"]}},"required":["id","object","created","owned_by","display_name","description","supported_resolutions","supported_aspect_ratios","supported_sizes","supported_durations","supported_frame_images","generate_audio","seed","required_input","upscale_factor","creativity","allowed_passthrough_parameters","pricing"]},"VideoModelsList":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/VideoModel"}}},"required":["object","data"]},"VideoModelsErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorObject"}},"required":["error"]},"CacheControl":{"type":"object","properties":{"type":{"type":"string","enum":["ephemeral"]},"ttl":{"type":"string","enum":["5m","1h"]}},"required":["type"]},"TextContentPart":{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"cache_control":{"$ref":"#/components/schemas/CacheControl"}},"required":["type","text"]},"ToolCall":{"type":"object","properties":{"id":{"type":"string"},"type":{"type":"string","enum":["function"]},"function":{"type":"object","properties":{"name":{"type":"string"},"arguments":{"type":"string","description":"JSON-строка с аргументами функции."}},"required":["name","arguments"]}},"required":["id","type","function"]},"GeneratedImage":{"type":"object","properties":{"type":{"type":"string","enum":["image_url"]},"image_url":{"type":"object","properties":{"url":{"type":"string","description":"Base64 data URL вида `data:image/png;base64,...`","example":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."}},"required":["url"]}},"required":["type","image_url"]},"AudioOutput":{"type":"object","properties":{"id":{"type":"string"},"data":{"type":"string","description":"Аудио ответа в base64 (формат — из запроса `audio.format`)."},"transcript":{"type":"string","description":"Текстовая расшифровка сказанного."},"expires_at":{"type":"number"}}},"AssistantMessage":{"type":"object","properties":{"role":{"type":"string","enum":["assistant"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/TextContentPart"}},{"nullable":true}]},"tool_calls":{"type":"array","items":{"$ref":"#/components/schemas/ToolCall"}},"name":{"type":"string"},"refusal":{"type":"string","nullable":true},"images":{"type":"array","items":{"$ref":"#/components/schemas/GeneratedImage"}},"audio":{"$ref":"#/components/schemas/AudioOutput"}},"required":["role"]},"FinishReason":{"type":"string","nullable":true,"enum":["stop","length","tool_calls","content_filter","function_call"]},"Choice":{"type":"object","properties":{"index":{"type":"integer","minimum":0},"message":{"$ref":"#/components/schemas/AssistantMessage"},"finish_reason":{"$ref":"#/components/schemas/FinishReason"},"logprobs":{"nullable":true}},"required":["index","message","finish_reason"]},"Usage":{"type":"object","properties":{"prompt_tokens":{"type":"integer","minimum":0},"completion_tokens":{"type":"integer","minimum":0},"total_tokens":{"type":"integer","minimum":0},"completion_tokens_details":{"type":"object","properties":{"reasoning_tokens":{"type":"integer","minimum":0}}},"prompt_tokens_details":{"type":"object","properties":{"cached_tokens":{"type":"integer","minimum":0}}}},"required":["prompt_tokens","completion_tokens","total_tokens"]},"ChatCompletionResponse":{"type":"object","properties":{"id":{"type":"string","example":"chatcmpl-abc123"},"object":{"type":"string","enum":["chat.completion"]},"created":{"type":"integer","description":"Unix-timestamp в секундах."},"model":{"type":"string"},"choices":{"type":"array","items":{"$ref":"#/components/schemas/Choice"},"minItems":1},"usage":{"$ref":"#/components/schemas/Usage"},"system_fingerprint":{"type":"string"}},"required":["id","object","created","model","choices","usage"]},"ChatCompletionErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorObject"}},"required":["error"]},"ImageUrlContentPart":{"type":"object","properties":{"type":{"type":"string","enum":["image_url"]},"image_url":{"type":"object","properties":{"url":{"type":"string","description":"URL изображения или data:image/<mime>;base64,..."},"detail":{"type":"string","enum":["auto","low","high"]}},"required":["url"]},"cache_control":{"$ref":"#/components/schemas/CacheControl"}},"required":["type","image_url"]},"InputAudioContentPart":{"type":"object","properties":{"type":{"type":"string","enum":["input_audio"]},"input_audio":{"type":"object","properties":{"data":{"type":"string","minLength":1,"description":"Аудио в base64 БЕЗ префикса `data:` — только сами данные."},"format":{"type":"string","enum":["wav","mp3","aiff","aac","ogg","flac","m4a","pcm16","pcm24"],"description":"Формат присланного аудио.","example":"wav"}},"required":["data","format"]},"cache_control":{"$ref":"#/components/schemas/CacheControl"}},"required":["type","input_audio"]},"VideoUrlContentPart":{"type":"object","properties":{"type":{"type":"string","enum":["video_url"]},"video_url":{"type":"object","properties":{"url":{"type":"string","minLength":1,"description":"Ссылка на публичный ролик YouTube или `data:video/<mime>;base64,...`.","example":"https://www.youtube.com/watch?v=dQw4w9WgXcQ"},"processing":{"type":"string","enum":["agentic","static"],"description":"Режим обработки видео у Gemini: `agentic` — модель сама перемещается по ролику (дешевле на длинных видео), `static` — просмотр целиком с фиксированной частотой кадров."}},"required":["url"]}},"required":["type","video_url"]},"ContentPart":{"oneOf":[{"$ref":"#/components/schemas/TextContentPart"},{"$ref":"#/components/schemas/ImageUrlContentPart"},{"$ref":"#/components/schemas/InputAudioContentPart"},{"$ref":"#/components/schemas/VideoUrlContentPart"}],"discriminator":{"propertyName":"type","mapping":{"text":"#/components/schemas/TextContentPart","image_url":"#/components/schemas/ImageUrlContentPart","input_audio":"#/components/schemas/InputAudioContentPart","video_url":"#/components/schemas/VideoUrlContentPart"}}},"SystemMessage":{"type":"object","properties":{"role":{"type":"string","enum":["system"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/ContentPart"}}]},"name":{"type":"string"},"cache_control":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["ephemeral"]},"ttl":{"type":"string","enum":["5m","1h"]}},"required":["type"],"description":"Маркер кеша на весь элемент — для клиентов, которые ставят его сюда. Основное место — `cache_control` на content-блоке."}},"required":["role","content"]},"UserMessage":{"type":"object","properties":{"role":{"type":"string","enum":["user"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/ContentPart"}}]},"name":{"type":"string"},"cache_control":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["ephemeral"]},"ttl":{"type":"string","enum":["5m","1h"]}},"required":["type"],"description":"Маркер кеша на весь элемент — для клиентов, которые ставят его сюда. Основное место — `cache_control` на content-блоке."}},"required":["role","content"]},"ToolCallInput":{"allOf":[{"$ref":"#/components/schemas/ToolCall"},{"type":"object","properties":{"cache_control":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["ephemeral"]},"ttl":{"type":"string","enum":["5m","1h"]}},"required":["type"],"description":"Маркер кеша на весь элемент — для клиентов, которые ставят его сюда. Основное место — `cache_control` на content-блоке."}}}]},"AssistantMessageInput":{"allOf":[{"$ref":"#/components/schemas/AssistantMessage"},{"type":"object","properties":{"tool_calls":{"type":"array","items":{"$ref":"#/components/schemas/ToolCallInput"}},"cache_control":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["ephemeral"]},"ttl":{"type":"string","enum":["5m","1h"]}},"required":["type"],"description":"Маркер кеша на весь элемент — для клиентов, которые ставят его сюда. Основное место — `cache_control` на content-блоке."}}}]},"ToolMessage":{"type":"object","properties":{"role":{"type":"string","enum":["tool"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/TextContentPart"}}]},"tool_call_id":{"type":"string"},"cache_control":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["ephemeral"]},"ttl":{"type":"string","enum":["5m","1h"]}},"required":["type"],"description":"Маркер кеша на весь элемент — для клиентов, которые ставят его сюда. Основное место — `cache_control` на content-блоке."}},"required":["role","content","tool_call_id"]},"Message":{"oneOf":[{"$ref":"#/components/schemas/SystemMessage"},{"$ref":"#/components/schemas/UserMessage"},{"$ref":"#/components/schemas/AssistantMessageInput"},{"$ref":"#/components/schemas/ToolMessage"}],"discriminator":{"propertyName":"role","mapping":{"system":"#/components/schemas/SystemMessage","user":"#/components/schemas/UserMessage","assistant":"#/components/schemas/AssistantMessageInput","tool":"#/components/schemas/ToolMessage"}}},"FunctionToolDefinition":{"type":"object","properties":{"type":{"type":"string","enum":["function"]},"function":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"parameters":{"type":"object","additionalProperties":{"nullable":true},"default":{"type":"object","properties":{}},"description":"JSON Schema объект с описанием параметров функции. Без него — функция без аргументов."},"strict":{"type":"boolean","nullable":true}},"required":["name"]},"cache_control":{"type":"object","nullable":true,"properties":{"type":{"type":"string","enum":["ephemeral"]},"ttl":{"type":"string","enum":["5m","1h"]}},"required":["type"],"description":"Маркер кеша на весь элемент — для клиентов, которые ставят его сюда. Основное место — `cache_control` на content-блоке."}},"required":["type","function"]},"ServerToolDefinition":{"type":"object","properties":{"type":{"type":"string","minLength":1}},"required":["type"]},"ToolDefinition":{"anyOf":[{"$ref":"#/components/schemas/FunctionToolDefinition"},{"$ref":"#/components/schemas/ServerToolDefinition"}]},"ToolChoice":{"anyOf":[{"type":"string","enum":["none","auto","required"]},{"type":"object","properties":{"type":{"type":"string","enum":["function"]},"function":{"type":"object","properties":{"name":{"type":"string"}},"required":["name"]}},"required":["type","function"]}]},"ResponseFormat":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["text"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["json_object"]}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["json_schema"]},"json_schema":{"type":"object","properties":{"name":{"type":"string"},"description":{"type":"string"},"schema":{"type":"object","additionalProperties":{"nullable":true}},"strict":{"type":"boolean"}},"required":["name","schema"]}},"required":["type","json_schema"]}]},"StreamOptions":{"type":"object","properties":{"include_usage":{"type":"boolean","description":"Hubris автоматически выставляет true для всех stream-запросов. Указывать необязательно."}}},"ChatCompletionRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"example":"anthropic/claude-haiku-4.5"},"models":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":10,"description":"Список fallback-моделей. Если основная (`model`) недоступна — попробует следующие по порядку. Биллинг по фактически использованной (см. `model` в ответе).","example":["anthropic/claude-sonnet-4.6","openai/gpt-4o-mini"]},"messages":{"type":"array","items":{"$ref":"#/components/schemas/Message"},"minItems":1},"tools":{"type":"array","items":{"$ref":"#/components/schemas/ToolDefinition"}},"tool_choice":{"$ref":"#/components/schemas/ToolChoice"},"parallel_tool_calls":{"type":"boolean"},"response_format":{"$ref":"#/components/schemas/ResponseFormat"},"temperature":{"type":"number","minimum":0,"maximum":2},"top_p":{"type":"number","minimum":0,"maximum":1},"n":{"type":"integer","minimum":1},"stop":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}]},"max_tokens":{"type":"integer","minimum":0,"exclusiveMinimum":true},"max_completion_tokens":{"type":"integer","minimum":0,"exclusiveMinimum":true},"frequency_penalty":{"type":"number","minimum":-2,"maximum":2},"presence_penalty":{"type":"number","minimum":-2,"maximum":2},"logit_bias":{"type":"object","additionalProperties":{"type":"number"}},"seed":{"type":"integer"},"logprobs":{"type":"boolean"},"top_logprobs":{"type":"integer","minimum":0,"maximum":20},"modalities":{"type":"array","items":{"type":"string","enum":["text","image","audio"]},"description":"Какие модальности должна вернуть модель. По умолчанию `[\"text\"]`. Для генерации изображений: `[\"image\",\"text\"]` (модели типа gemini-flash-image) либо `[\"image\"]` (модели типа flux/sdxl). Для голосового ответа: `[\"text\",\"audio\"]` вместе с полем `audio` и обязательным `stream: true`. Поддерживается только моделями, у которых соответствующая модальность есть в `output_modalities`.","example":["image","text"]},"audio":{"type":"object","properties":{"voice":{"type":"string","description":"Голос озвучки, например `alloy`.","example":"alloy"},"format":{"type":"string","description":"Формат аудио ответа: `wav`, `mp3`, `pcm16` и т.п.","example":"wav"}},"required":["voice","format"],"description":"Настройки голосового ответа. Требует `modalities: [\"text\",\"audio\"]` и `stream: true`."},"image_config":{"type":"object","additionalProperties":{"nullable":true},"description":"Параметры image-gen моделей: aspect_ratio (`1:1`, `16:9`, `9:16` и т.д.), image_size (`0.5K`, `1K`, `2K`, `4K`), а также model-specific поля. Конкретный набор зависит от модели — см. карточку модели в каталоге.","example":{"aspect_ratio":"16:9","image_size":"2K"}},"stream":{"type":"boolean"},"stream_options":{"$ref":"#/components/schemas/StreamOptions"},"user":{"type":"string"},"reasoning_effort":{"type":"string","enum":["none","minimal","low","medium","high","xhigh","max"]}},"required":["model","messages"]},"ImageGenerationRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"example":"black-forest-labs/flux.2-pro"},"prompt":{"type":"string","minLength":1,"example":"a red cube on a plain white background"},"n":{"type":"integer","minimum":1,"maximum":10,"description":"Сколько изображений (клиппится по лимиту модели).","example":1},"size":{"type":"string","description":"Размер, напр. \"1024x1024\" или тир \"2K\".","example":"1024x1024"},"response_format":{"type":"string","enum":["b64_json","url"],"description":"MVP всегда отдаёт b64_json."}},"required":["model","prompt"]},"ResponsesResponse":{"type":"object","properties":{"id":{"type":"string","example":"resp_abc123"},"object":{"type":"string","enum":["response"]},"created_at":{"type":"integer"},"model":{"type":"string"},"output":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}},"usage":{"$ref":"#/components/schemas/Usage"},"status":{"type":"string"}},"required":["id","object","created_at","model","output"]},"ResponsesErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorObject"}},"required":["error"]},"ResponsesRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"example":"openai/o1-mini"},"input":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}}],"description":"Строка или массив input-блоков (см. OpenAI Responses API)."},"stream":{"type":"boolean"}},"required":["model","input"]},"AnthropicCacheControl":{"type":"object","properties":{"type":{"type":"string","enum":["ephemeral"]},"ttl":{"type":"string","enum":["5m","1h"]}},"required":["type"]},"AnthropicTextBlock":{"type":"object","properties":{"type":{"type":"string","enum":["text"]},"text":{"type":"string"},"cache_control":{"$ref":"#/components/schemas/AnthropicCacheControl"},"citations":{"type":"array","items":{"type":"object","additionalProperties":{"nullable":true}}}},"required":["type","text"]},"AnthropicImageBlock":{"type":"object","properties":{"type":{"type":"string","enum":["image"]},"source":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["base64"]},"media_type":{"type":"string","enum":["image/jpeg","image/png","image/gif","image/webp"]},"data":{"type":"string"}},"required":["type","media_type","data"]},{"type":"object","properties":{"type":{"type":"string","enum":["url"]},"url":{"type":"string","format":"uri"}},"required":["type","url"]}]},"cache_control":{"$ref":"#/components/schemas/AnthropicCacheControl"}},"required":["type","source"]},"AnthropicToolUseBlock":{"type":"object","properties":{"type":{"type":"string","enum":["tool_use"]},"id":{"type":"string"},"name":{"type":"string"},"input":{"nullable":true},"cache_control":{"$ref":"#/components/schemas/AnthropicCacheControl"}},"required":["type","id","name"]},"AnthropicToolResultBlock":{"type":"object","properties":{"type":{"type":"string","enum":["tool_result"]},"tool_use_id":{"type":"string"},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/AnthropicTextBlock"},{"$ref":"#/components/schemas/AnthropicImageBlock"}]}}]},"is_error":{"type":"boolean"},"cache_control":{"$ref":"#/components/schemas/AnthropicCacheControl"}},"required":["type","tool_use_id"]},"AnthropicDocumentBlock":{"type":"object","properties":{"type":{"type":"string","enum":["document"]},"source":{"type":"object","additionalProperties":{"nullable":true}},"title":{"type":"string"},"context":{"type":"string"},"citations":{"type":"object","additionalProperties":{"nullable":true}},"cache_control":{"$ref":"#/components/schemas/AnthropicCacheControl"}},"required":["type","source"]},"AnthropicThinkingBlock":{"type":"object","properties":{"type":{"type":"string","enum":["thinking"]},"thinking":{"type":"string"},"signature":{"type":"string"}},"required":["type","thinking"]},"AnthropicRedactedThinkingBlock":{"type":"object","properties":{"type":{"type":"string","enum":["redacted_thinking"]},"data":{"type":"string"}},"required":["type","data"]},"AnthropicContentBlock":{"anyOf":[{"$ref":"#/components/schemas/AnthropicTextBlock"},{"$ref":"#/components/schemas/AnthropicImageBlock"},{"$ref":"#/components/schemas/AnthropicToolUseBlock"},{"$ref":"#/components/schemas/AnthropicToolResultBlock"},{"$ref":"#/components/schemas/AnthropicDocumentBlock"},{"$ref":"#/components/schemas/AnthropicThinkingBlock"},{"$ref":"#/components/schemas/AnthropicRedactedThinkingBlock"},{"type":"object","properties":{"type":{"type":"string"}},"required":["type"]}]},"AnthropicStopReason":{"type":"string","nullable":true,"enum":["end_turn","max_tokens","stop_sequence","tool_use","pause_turn","refusal"]},"AnthropicResponseUsage":{"type":"object","properties":{"input_tokens":{"type":"integer","minimum":0},"output_tokens":{"type":"integer","minimum":0},"cache_creation_input_tokens":{"type":"integer","nullable":true,"minimum":0},"cache_read_input_tokens":{"type":"integer","nullable":true,"minimum":0},"cache_creation":{"nullable":true},"service_tier":{"type":"string","nullable":true},"server_tool_use":{"nullable":true}},"required":["input_tokens","output_tokens"]},"AnthropicMessagesResponse":{"type":"object","properties":{"id":{"type":"string","example":"msg_01XYZ"},"type":{"type":"string","enum":["message"]},"role":{"type":"string","enum":["assistant"]},"content":{"type":"array","items":{"$ref":"#/components/schemas/AnthropicContentBlock"}},"model":{"type":"string"},"stop_reason":{"$ref":"#/components/schemas/AnthropicStopReason"},"stop_sequence":{"type":"string","nullable":true},"usage":{"$ref":"#/components/schemas/AnthropicResponseUsage"},"container":{"nullable":true}},"required":["id","type","role","content","model","stop_reason","stop_sequence","usage"]},"AnthropicErrorType":{"type":"string","enum":["invalid_request_error","authentication_error","permission_error","not_found_error","request_too_large","rate_limit_error","api_error","overloaded_error","billing_error","timeout_error"]},"AnthropicMessagesError":{"type":"object","properties":{"type":{"type":"string","enum":["error"]},"error":{"type":"object","properties":{"type":{"$ref":"#/components/schemas/AnthropicErrorType"},"message":{"type":"string"}},"required":["type","message"]}},"required":["type","error"]},"AnthropicMessage":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant","system"]},"content":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/AnthropicContentBlock"}}]}},"required":["role","content"]},"AnthropicSystem":{"anyOf":[{"type":"string"},{"type":"array","items":{"$ref":"#/components/schemas/AnthropicTextBlock"}}],"description":"Системный промпт. Строка или массив text-блоков (для гибкого cache_control)."},"AnthropicServerTool":{"type":"object","properties":{"type":{"type":"string","pattern":"^[a-z_]+_\\d{8}$"},"name":{"type":"string","minLength":1,"maxLength":128},"max_uses":{"type":"integer","minimum":0,"exclusiveMinimum":true},"allowed_domains":{"type":"array","items":{"type":"string"}},"blocked_domains":{"type":"array","items":{"type":"string"}},"user_location":{"type":"object","additionalProperties":{"nullable":true}},"cache_control":{"$ref":"#/components/schemas/AnthropicCacheControl"}},"required":["type","name"]},"AnthropicTool":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":128,"pattern":"^[a-zA-Z0-9_-]+$"},"description":{"type":"string"},"input_schema":{"type":"object","additionalProperties":{"nullable":true}},"cache_control":{"$ref":"#/components/schemas/AnthropicCacheControl"},"type":{"type":"string"}},"required":["name","input_schema"]},"AnthropicToolChoice":{"anyOf":[{"type":"object","properties":{"type":{"type":"string","enum":["auto"]},"disable_parallel_tool_use":{"type":"boolean"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["any"]},"disable_parallel_tool_use":{"type":"boolean"}},"required":["type"]},{"type":"object","properties":{"type":{"type":"string","enum":["tool"]},"name":{"type":"string"},"disable_parallel_tool_use":{"type":"boolean"}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["none"]}},"required":["type"]}]},"AnthropicMessagesRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"description":"Имя модели. Принимаются и Anthropic-имена (`claude-sonnet-4-5`, `claude-3-5-sonnet-20241022`, `claude-haiku-4-5-latest`), и каноничные OR-имена (`anthropic/claude-sonnet-4.6`). См. /docs/integrations/claude-code.","example":"claude-sonnet-4-5"},"models":{"type":"array","items":{"type":"string","minLength":1},"minItems":1,"maxItems":10,"description":"Список резервных моделей (расширение Hubris). Если `model` отвечает 429/5xx или не начинает ответ вовремя — запрос уходит к следующей по порядку. Модель, не принимающая содержимое запроса (картинки, документы), пропускается. Биллинг по фактически ответившей модели.","example":["claude-opus-4-1","anthropic/claude-sonnet-4.6"]},"max_tokens":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Максимальное число токенов в ответе. Обязательное поле.","example":1024},"messages":{"type":"array","items":{"$ref":"#/components/schemas/AnthropicMessage"},"minItems":1,"description":"Массив сообщений диалога. Чередование ролей user/assistant."},"system":{"$ref":"#/components/schemas/AnthropicSystem"},"metadata":{"type":"object","properties":{"user_id":{"type":"string"}}},"stop_sequences":{"type":"array","items":{"type":"string"}},"stream":{"type":"boolean"},"temperature":{"type":"number","minimum":0,"maximum":1},"top_p":{"type":"number","minimum":0,"maximum":1},"top_k":{"type":"integer","minimum":0,"exclusiveMinimum":true},"tools":{"type":"array","items":{"anyOf":[{"$ref":"#/components/schemas/AnthropicServerTool"},{"$ref":"#/components/schemas/AnthropicTool"}]}},"tool_choice":{"$ref":"#/components/schemas/AnthropicToolChoice"},"thinking":{"type":"object","properties":{"type":{"type":"string","enum":["enabled","disabled","adaptive"]},"budget_tokens":{"type":"integer","minimum":0}},"required":["type"],"description":"Extended thinking (Claude 4+). enabled + budget_tokens — бюджет на размышления; adaptive — режим Claude 5."},"service_tier":{"type":"string"}},"required":["model","max_tokens","messages"]},"Embedding":{"type":"object","properties":{"object":{"type":"string","enum":["embedding"]},"index":{"type":"integer","minimum":0},"embedding":{"nullable":true,"description":"Массив чисел при `encoding_format=float` или base64-строка при `encoding_format=base64`."}},"required":["object","index"]},"EmbeddingsUsage":{"type":"object","properties":{"prompt_tokens":{"type":"integer","minimum":0},"total_tokens":{"type":"integer","minimum":0}},"required":["prompt_tokens","total_tokens"]},"EmbeddingsResponse":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"$ref":"#/components/schemas/Embedding"}},"model":{"type":"string"},"usage":{"$ref":"#/components/schemas/EmbeddingsUsage"}},"required":["object","data","model","usage"]},"EmbeddingsErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorObject"}},"required":["error"]},"EmbeddingsRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"description":"ID embedding-модели — например, `openai/text-embedding-3-small`. Полный список: GET /v1/models, отфильтруйте по `output_modalities` содержащему `embeddings`.","example":"openai/text-embedding-3-small"},"input":{"anyOf":[{"type":"string"},{"type":"array","items":{"type":"string"}},{"type":"array","items":{"type":"integer"}},{"type":"array","items":{"type":"array","items":{"type":"integer"}}}],"description":"Текст для эмбеддинга. Принимает: одну строку, массив строк (батч), массив токен-ID или массив массивов токен-ID. Максимум 2048 элементов в батче.","example":"Привет, мир"},"encoding_format":{"type":"string","enum":["float","base64"],"description":"`float` (по умолчанию) — массив чисел в `embedding`. `base64` — base64-строка.","example":"float"},"dimensions":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Уменьшенная размерность вектора. Поддерживается только моделями `text-embedding-3-*`.","example":256},"user":{"type":"string","description":"Опциональный идентификатор конечного пользователя (для логов абьюза провайдера)."}},"required":["model","input"]},"DecisionAnswer":{"type":"object","properties":{"type":{"type":"string","enum":["noul","choice","score"]},"noul":{"type":"number","description":"Для `noul`: вероятность ответа «да», от 0 до 1."},"choice":{"type":"string","description":"Для `choice`: ключ выбранного варианта."},"score":{"type":"number","description":"Для `score`: ожидаемый уровень шкалы, дробное число от 0 до N−1."},"confidence":{"type":"number","description":"Уверенность модели в ответе, от 0 до 1."},"probabilities":{"type":"object","additionalProperties":{"type":"number"},"description":"Вероятность каждого варианта или уровня."},"legend":{"type":"object","additionalProperties":{"nullable":true},"description":"Для `score`: номер уровня → его описание из запроса."}},"required":["type"]},"DecisionsUsage":{"type":"object","properties":{"input_tokens":{"type":"integer","minimum":0},"output_tokens":{"type":"integer","minimum":0},"cost":{"type":"number","description":"Списано за запрос, в копейках."}},"required":["input_tokens","output_tokens"]},"DecisionsResponse":{"type":"object","properties":{"id":{"type":"string"},"model":{"type":"string"},"answers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/DecisionAnswer"}},"usage":{"$ref":"#/components/schemas/DecisionsUsage"}},"required":["model","answers","usage"]},"DecisionQuestion":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["noul"]},"instructions":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{"nullable":true}},{"type":"array","items":{"nullable":true}}]},"criteria":{"type":"object","properties":{"true":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{"nullable":true}},{"type":"array","items":{"nullable":true}}]},"false":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{"nullable":true}},{"type":"array","items":{"nullable":true}}]}},"required":["true","false"]}},"required":["type","instructions"]},{"type":"object","properties":{"type":{"type":"string","enum":["choice"]},"instructions":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{"nullable":true}},{"type":"array","items":{"nullable":true}}]},"criteria":{"type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{"nullable":true}},{"type":"array","items":{"nullable":true}}]}}},"required":["type","instructions","criteria"]},{"type":"object","properties":{"type":{"type":"string","enum":["score"]},"instructions":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{"nullable":true}},{"type":"array","items":{"nullable":true}}]},"criteria":{"type":"array","items":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{"nullable":true}},{"type":"array","items":{"nullable":true}}]},"minItems":1}},"required":["type","instructions","criteria"]}],"description":"Вопрос к модели. `noul` — да или нет, ответ — вероятность «да» от 0 до 1. `choice` — один вариант из `criteria` (объект «ключ → описание»). `score` — уровень на шкале из `criteria` (массив описаний уровней по порядку)."},"DecisionsRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"description":"ID модели решений, например `typesafe/jev-1.13`. Полный список: GET /v1/models, отфильтруйте по `output_modalities`, содержащему `decisions`.","example":"typesafe/jev-1.13"},"state":{"anyOf":[{"type":"string"},{"type":"object","additionalProperties":{"nullable":true}},{"type":"array","items":{"nullable":true}}],"description":"Данные, о которых задаются вопросы: строка, объект или массив.","example":"Третий день не проходит оплата на сайте, клиенты уходят."},"questions":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/DecisionQuestion"},"description":"Вопросы по ключам. Ключ возвращается в `answers`. Все вопросы решаются за один запрос."},"user":{"type":"string","maxLength":256,"description":"Опциональный идентификатор конечного пользователя."}},"required":["model","state","questions"]},"RerankResult":{"type":"object","properties":{"index":{"type":"integer","minimum":0,"description":"Номер документа во входном списке."},"relevance_score":{"type":"number","description":"Насколько документ подходит к запросу: чем больше, тем лучше."},"document":{"type":"object","properties":{"text":{"type":"string"},"image":{"type":"string"}}}},"required":["index","relevance_score"]},"RerankUsage":{"type":"object","properties":{"total_tokens":{"type":"integer","minimum":0},"search_units":{"type":"integer","minimum":0,"description":"Поисковые единицы — у моделей с оплатой за поиск (Cohere)."},"cost":{"type":"number","description":"Списано за запрос, в копейках."}}},"RerankResponse":{"type":"object","properties":{"id":{"type":"string"},"model":{"type":"string"},"results":{"type":"array","items":{"$ref":"#/components/schemas/RerankResult"}},"usage":{"$ref":"#/components/schemas/RerankUsage"}},"required":["model","results","usage"]},"RerankDocument":{"anyOf":[{"type":"string"},{"type":"object","properties":{"text":{"type":"string"},"image":{"type":"string","description":"URL или data URI картинки."}}}]},"RerankRequest":{"type":"object","properties":{"model":{"type":"string","minLength":1,"description":"ID реранкера, например `cohere/rerank-v3.5`. Полный список: GET /v1/models?output_modalities=rerank.","example":"cohere/rerank-v3.5"},"query":{"type":"string","minLength":1,"description":"Поисковый запрос, по которому сортируются документы.","example":"Как вернуть деньги за заказ?"},"documents":{"type":"array","items":{"$ref":"#/components/schemas/RerankDocument"},"minItems":1,"maxItems":1000,"description":"Документы для сортировки: строки или объекты `{ text, image }`.","example":["Возврат оформляется в личном кабинете.","Доставка занимает 3–5 дней."]},"top_n":{"type":"integer","minimum":0,"exclusiveMinimum":true,"description":"Сколько самых подходящих документов вернуть. По умолчанию все.","example":3},"user":{"type":"string","maxLength":256,"description":"Опциональный идентификатор конечного пользователя."}},"required":["model","query","documents"]},"UsagePeriod":{"type":"string","nullable":true,"enum":["today","24h","7d","30d","mtd"],"description":"Шорткат, если запрос был сделан через `?period=`. Иначе null."},"UsageGranularity":{"type":"string","nullable":true,"enum":["hour","day"],"description":"Если `granularity` был задан, тут он же. Иначе null."},"UsageBucket":{"type":"object","properties":{"bucket":{"type":"string","format":"date-time","description":"Начало интервала в ISO 8601 (UTC).","example":"2026-05-14T00:00:00.000Z"},"cost_rub":{"type":"number","description":"Стоимость за интервал в рублях. cost_kopecks/100.","example":12.34},"cost_kopecks":{"type":"string","description":"Стоимость за интервал в копейках (строка — чтобы пережить JSON без потери точности).","example":"1234"},"requests":{"type":"integer","minimum":0,"example":42}},"required":["bucket","cost_rub","cost_kopecks","requests"]},"UsageResponse":{"type":"object","properties":{"object":{"type":"string","enum":["usage"]},"period":{"type":"object","properties":{"from":{"type":"string","format":"date-time","description":"Начало периода (UTC, ISO 8601). Включительно.","example":"2026-05-13T00:00:00.000Z"},"to":{"type":"string","format":"date-time","description":"Конец периода (UTC, ISO 8601). Включительно.","example":"2026-05-14T00:00:00.000Z"},"shortcut":{"$ref":"#/components/schemas/UsagePeriod"}},"required":["from","to","shortcut"]},"scope":{"anyOf":[{"type":"object","properties":{"key_id":{"type":"string","format":"uuid"},"key_prefix":{"type":"string","example":"sk-gw-a1b2...c3d4"}},"required":["key_id","key_prefix"]},{"type":"object","properties":{"account":{"type":"boolean","enum":[true]},"key_id":{"type":"string","nullable":true,"format":"uuid"}},"required":["account","key_id"]}],"description":"Обычный ключ: расход только по нему. OAuth-токен: расход всего подключения приложения, `key_id` — текущий токен. Management-ключ: весь аккаунт (`account: true`), опционально суженный параметром `key_id`."},"totals":{"type":"object","properties":{"requests":{"type":"integer","minimum":0,"example":137},"prompt_tokens":{"type":"integer","minimum":0,"example":18420},"completion_tokens":{"type":"integer","minimum":0,"example":9610},"total_tokens":{"type":"integer","minimum":0,"example":28030},"cost_rub":{"type":"number","description":"Итоговая стоимость за период в рублях. Эквивалент cost_kopecks/100.","example":42.17},"cost_kopecks":{"type":"string","description":"Итоговая стоимость в копейках (строка для точности при сериализации bigint).","example":"4217"},"cache_read_tokens":{"type":"integer"},"cache_write_tokens":{"type":"integer"},"reasoning_tokens":{"type":"integer"},"cache_hit_rate":{"type":"number"},"cache_savings_kopecks":{"type":"string"},"cache_savings_rub":{"type":"number"}},"required":["requests","prompt_tokens","completion_tokens","total_tokens","cost_rub","cost_kopecks","cache_read_tokens","cache_write_tokens","reasoning_tokens","cache_hit_rate","cache_savings_kopecks","cache_savings_rub"]},"granularity":{"$ref":"#/components/schemas/UsageGranularity"},"buckets":{"type":"array","nullable":true,"items":{"$ref":"#/components/schemas/UsageBucket"},"description":"Точки графика. Null, если `granularity` не запрошен."},"by_key":{"type":"array","nullable":true,"items":{"type":"object","properties":{"key_id":{"type":"string","nullable":true,"format":"uuid"},"key_prefix":{"type":"string","nullable":true},"name":{"type":"string","nullable":true},"requests":{"type":"integer","minimum":0},"total_tokens":{"type":"integer","minimum":0},"cost_kopecks":{"type":"string","description":"Копейки строкой — как в totals.","example":"1234"}},"required":["key_id","key_prefix","name","requests","total_tokens","cost_kopecks"]},"description":"Разбивка по ключам аккаунта (`group_by=key`, только management-ключом). Иначе отсутствует."},"by_model":{"type":"array","nullable":true,"items":{"type":"object","properties":{"model":{"type":"string"},"requests":{"type":"integer","minimum":0},"prompt_tokens":{"type":"integer","minimum":0},"completion_tokens":{"type":"integer","minimum":0},"cost_kopecks":{"type":"string","description":"Копейки строкой — как в totals.","example":"1234"}},"required":["model","requests","prompt_tokens","completion_tokens","cost_kopecks"]},"description":"Разбивка по моделям (`group_by=model`, только management-ключом). Иначе отсутствует."}},"required":["object","period","scope","totals","granularity","buckets"]},"UsageErrorResponse":{"type":"object","properties":{"error":{"$ref":"#/components/schemas/ErrorObject"}},"required":["error"]}},"parameters":{}},"paths":{"/v1/audio/transcriptions":{"post":{"operationId":"createTranscription","tags":["Audio"],"summary":"Распознать речь в аудио","description":"OpenAI-совместимое распознавание речи: аудиозапись на входе, текст на выходе. Работает официальный SDK OpenAI (`audio.transcriptions.create`).\n\nДва формата тела с одинаковым результатом: `multipart/form-data` с файлом, как у OpenAI, или `application/json` с аудио в base64 (`input_audio`). Ссылки на аудио не принимаются.\n\nСтрима нет: `stream: true` — 400. `response_format` — только `json` или `verbose_json`.\n\nОплата по факту запроса: `usage.cost` — списано в копейках. Часть моделей тарифицируется по длительности записи, часть по токенам. Список моделей: `GET /v1/models?output_modalities=transcription`.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"multipart/form-data":{"schema":{"$ref":"#/components/schemas/TranscriptionMultipartRequest"}},"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptionJsonRequest"}}}},"responses":{"200":{"description":"Распознанный текст.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TranscriptionResponse"}}}},"400":{"description":"Невалидное тело: нет `model`, `file` или `input_audio`, `stream: true`, неподдерживаемый `response_format`; ключ BYOK."},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"402":{"description":"Недостаточно средств на балансе (`insufficient_balance`)."},"403":{"description":"Нет права `chat:write`: ключ только для чтения (`key_read_only`) или OAuth-токен без него (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"404":{"description":"Модель не найдена или это не модель распознавания (`model_not_found`)."},"413":{"description":"Тело запроса больше лимита (`request_too_large`)."},"429":{"description":"Исчерпан лимит расхода ключа (`daily_limit_exceeded`, `key_limit_exceeded`) или провайдер временно ограничил запросы. Пауза — в `Retry-After`."},"502":{"description":"Ошибка провайдера или не удалось определить стоимость (`pricing_unavailable`). Списания нет."},"503":{"description":"Курс ЦБ РФ временно недоступен (`exchange_rate_unavailable`)."},"504":{"description":"Таймаут распознавания (`upstream_timeout`)."}}}},"/v1/audio/speech":{"post":{"operationId":"createSpeech","tags":["Audio"],"summary":"Озвучить текст","description":"OpenAI-совместимая озвучка (TTS): текст на входе, байты аудио на выходе, а не JSON. Работает официальный SDK OpenAI (`audio.speech.create`).\n\nФормат — `response_format`: `mp3` (`audio/mpeg`) или `pcm` (`audio/pcm` с частотой и числом каналов в `Content-Type`, 16-bit LE без заголовка WAV). Без поля формат выбирает модель. Стрима нет.\n\n`voice` обязателен, если у модели в каталоге есть список голосов; голос не из списка отклоняется до обращения к модели.\n\nЦена — по единице модели в каталоге: символы или байты текста, секунды звука, токены. Списание по факту запроса; `usage` в ответе нет, расход — в журнале запросов. Перед запросом баланс сверяется с оценкой цены. Список моделей: `GET /v1/models?output_modalities=speech`.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SpeechRequest"}}}},"responses":{"200":{"description":"Аудио целиком.","headers":{"Content-Length":{"description":"Размер аудио в байтах.","schema":{"type":"integer"}}},"content":{"audio/mpeg":{"schema":{"type":"string","format":"binary"}},"audio/pcm":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Невалидное тело (`invalid_request`), не выбран голос (`voice_required`), голоса нет у модели (`voice_not_supported`); ключ BYOK. В тексте ошибки — доступные голоса."},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"402":{"description":"Баланса не хватает на оценку цены запроса (`insufficient_balance`)."},"403":{"description":"Нет права `chat:write`: ключ только для чтения (`key_read_only`) или OAuth-токен без него (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"404":{"description":"Модель не найдена или это не модель озвучки (`model_not_found`)."},"413":{"description":"Тело запроса больше 1 МБ (`request_too_large`)."},"429":{"description":"Исчерпан лимит расхода ключа (`daily_limit_exceeded`, `key_limit_exceeded`) или провайдер временно ограничил запросы. Пауза — в `Retry-After`."},"502":{"description":"Нечем посчитать цену (`pricing_unavailable`), модель вернула пустой ответ (`no_audio_returned`), не удалось перекодировать в mp3 (`transcode_failed`) или ошибка провайдера. Списания нет."},"503":{"description":"Курс ЦБ РФ временно недоступен (`exchange_rate_unavailable`)."},"504":{"description":"Таймаут озвучки (`upstream_timeout`)."}}}},"/v1/videos":{"post":{"operationId":"createVideo","tags":["Videos"],"summary":"Создать задачу генерации видео","description":"Асинхронная генерация: ответ 202 сразу приносит номер задачи и `polling_url`. Статус — `GET /v1/videos/{id}`, готовый ролик — `GET /v1/videos/{id}/content`.\n\nПеред запуском с баланса удерживается не меньше наибольшей возможной стоимости ролика. После готовности списывается факт (`usage.cost`), разница возвращается; при сбое удержание возвращается целиком. Готовый ролик хранится 72 часа.\n\nНужен обычный ключ: ключ только для чтения задачу не создаст. Модели, их оси и цены — `GET /v1/videos/models`.","security":[{"bearerAuth":[]},{"oauth2":["videos:write"]}],"parameters":[{"schema":{"type":"string","maxLength":255,"description":"Повтор с тем же ключом от того же аккаунта вернёт уже созданную задачу без нового удержания. Ключ длиннее 255 знаков не учитывается."},"required":false,"name":"Idempotency-Key","in":"header"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateVideoRequest"}}}},"responses":{"202":{"description":"Задача создана (или найдена по `Idempotency-Key`).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoJobCreated"}}}},"400":{"description":"Невалидное тело (`invalid_request`): ось, которой нет у модели, `callback_url`, неподходящие `input_references` или `provider.options`; ключ BYOK. Отказ модели принять вход приходит с её текстом."},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"402":{"description":"Не хватает средств на удержание под задачу (`insufficient_balance`)."},"403":{"description":"Нет права создавать задачи: ключ только для чтения (`key_read_only`). OAuth-токен без права `videos:write` (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"404":{"description":"Модель не найдена или это не видеомодель (`model_not_found`)."},"413":{"description":"Тело запроса больше лимита (`request_too_large`)."},"429":{"description":"Достигнут лимит одновременных видеозадач аккаунта или уже готовится другой исходник (`too_many_active_jobs`); удержание не помещается в остаток лимита расхода ключа или OAuth-приложения (`daily_limit_exceeded`, `key_limit_exceeded`)."},"500":{"description":"Внутренняя ошибка (`internal_error`)."},"502":{"description":"Провайдер не принял задачу (`upstream_error`). Удержание возвращается."},"503":{"description":"Курс ЦБ РФ временно недоступен — не посчитать удержание (`exchange_rate_unavailable`)."},"504":{"description":"Провайдер не ответил вовремя (`upstream_error`). Удержание возвращается."}}}},"/v1/videos/{id}":{"get":{"operationId":"getVideo","tags":["Videos"],"summary":"Статус задачи генерации видео","description":"Статус: `pending`, `in_progress`, `completed` или `failed`. При `completed` — `unsigned_urls` (адрес скачивания, нужен тот же ключ или токен) и `usage.cost`, итоговое списание в копейках; пока задача в работе — `usage.estimated_cost`, удержанная сумма.\n\nСтатус у провайдера запрашивается не чаще раза в 5 секунд на задачу, опрашивать чаще смысла нет. Подходит и ключ только для чтения.","security":[{"bearerAuth":[]},{"oauth2":["videos:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Номер задачи из ответа `POST /v1/videos`."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Задача.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoJob"}}}},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"403":{"description":"OAuth-токен без права `videos:read` (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"404":{"description":"Задачи нет или она принадлежит другому аккаунту (`not_found`)."}}}},"/v1/videos/{id}/content":{"get":{"operationId":"getVideoContent","tags":["Videos"],"summary":"Скачать готовое видео","description":"Байты готового ролика для задачи в статусе `completed` — только владельцу, тем же ключом или OAuth-токеном. Тип — сохранённый `video/*` (обычно `video/mp4`), иначе `application/octet-stream`; `Content-Disposition: attachment`. Range-запросы не поддерживаются.\n\nРолик хранится 72 часа с создания задачи. До готовности и после срока хранения — одинаково 404 `video_not_ready`. Подходит и ключ только для чтения.","security":[{"bearerAuth":[]},{"oauth2":["videos:read"]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"Номер задачи из ответа `POST /v1/videos`."},"required":true,"name":"id","in":"path"},{"schema":{"type":"integer","minimum":0,"maximum":0,"default":0,"description":"Номер ролика задачи. В v1 у задачи один ролик — `0`; больше нуля — 400 `index_out_of_range`."},"required":false,"name":"index","in":"query"}],"responses":{"200":{"description":"Ролик целиком.","content":{"video/mp4":{"schema":{"type":"string","format":"binary"}}}},"400":{"description":"Некорректный `index` (`invalid_request`) или больше нуля (`index_out_of_range`)."},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"403":{"description":"OAuth-токен без права `videos:read` (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"404":{"description":"Задачи нет или она чужая (`not_found`); ролик ещё не готов или срок хранения истёк (`video_not_ready`)."}}}},"/v1/video/transcriptions":{"post":{"operationId":"createVideoTranscription","tags":["Videos"],"summary":"Расшифровать ролик YouTube по ссылке","description":"Дословная расшифровка с таймкодами (`exact`) или пересказ (`fast`) публичного ролика YouTube. Ролик по ссылке смотрит модель `google/gemini-3.8-flash`, скачивать видео не нужно. Не путать с `/v1/videos` — там генерация.\n\nДо запроса к модели ролик проверяется: удалённый, приватный, открытый только по ссылке, прямой эфир и ролик длиннее 4 часов отклоняются без списания.\n\nОплата по токенам, как у запроса к модели: `usage.cost` — сумма в копейках. Если ответ в режиме `exact` упирается в лимит длины, Hubris сам запрашивает продолжение и склеивает куски — до 5 запросов к модели (`usage.requests`). Стрима нет, ответ приходит целиком.\n\nОшибки самого запроса к модели (402, 429, 5xx) приходят в том же виде, что у `/v1/chat/completions`.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoTranscriptionRequest"}}}},"responses":{"200":{"description":"Расшифровка или пересказ.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoTranscription"}}}},"400":{"description":"Невалидный JSON (`invalid_json`) или параметр (`invalid_parameter`), ссылка не на ролик YouTube (`invalid_video_url`), прямой эфир или премьера (`video_is_live`), ролик длиннее 4 часов (`video_too_long`)."},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"402":{"description":"Недостаточно средств на балансе (`insufficient_balance`)."},"403":{"description":"Нет права `chat:write`: ключ только для чтения (`key_read_only`) или OAuth-токен без него (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"404":{"description":"Ролик удалён, приватный или открыт только по ссылке (`video_unavailable`)."},"413":{"description":"Тело запроса больше 64 КБ (`request_too_large`)."},"429":{"description":"Исчерпан лимит расхода ключа (`daily_limit_exceeded`, `key_limit_exceeded`) или провайдер временно ограничил запросы. Пауза — в `Retry-After`."},"502":{"description":"Сбой модели (`upstream_error`)."},"503":{"description":"Проверка ролика временно недоступна (`video_lookup_unavailable`) или курс ЦБ РФ недоступен."}}}},"/v1/metrics":{"get":{"operationId":"getMetrics","tags":["Metrics"],"summary":"Метрики аккаунта для Prometheus","description":"Баланс, расход, число запросов, токены, время ответа и лимиты ключей аккаунта в текстовом формате Prometheus 0.0.4. Его читают Prometheus, Grafana Agent, VictoriaMetrics и Zabbix.\n\nПодходит любой обычный ключ, в том числе только для чтения — его и стоит класть в конфиг мониторинга. Management-ключ не подходит.\n\nЗначения обновляются раз в 45 секунд; не больше 30 запросов в минуту на аккаунт.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Метрики, `Content-Type: text/plain; version=0.0.4; charset=utf-8`.","content":{"text/plain":{"schema":{"type":"string","example":"# HELP hubris_balance_kopecks Остаток на балансе аккаунта, копейки.\n# TYPE hubris_balance_kopecks gauge\nhubris_balance_kopecks 128400\n"}}}},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"403":{"description":"Отказ в доступе: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"429":{"description":"Больше 30 запросов в минуту (`rate_limit_exceeded`).","headers":{"Retry-After":{"description":"Секунды до повтора.","schema":{"type":"integer"}}}}}}},"/v1/integrations/bitrix24/connectors":{"post":{"operationId":"createBitrix24Connector","tags":["Integrations"],"summary":"Создать коннектор Битрикс24","description":"Коннектор подключает модель Hubris к CoPilot (BitrixGPT) портала Битрикс24 как собственный движок. Под коннектор выпускается отдельный API-ключ «Битрикс24 · <имя>»: расход по нему виден отдельно, отзыв ключа выключает коннектор.\n\n`completions_url` из ответа передайте порталу в `ai.engine.register`. Адрес содержит секрет и показывается один раз.\n\nМодель закрепляется за коннектором; нужна другая — создайте второй коннектор. Сам вызов ничего не списывает, но требует права тратить: выпущенный ключ тратит баланс аккаунта.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bitrix24ConnectorCreateRequest"}}}},"responses":{"201":{"description":"Коннектор создан.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bitrix24ConnectorCreated"}}}},"400":{"description":"Невалидное тело. Ответ — результат проверки схемы (`success: false`, `error.issues`), а не `{ error: { message, type, code } }`."},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"403":{"description":"Нет права `chat:write`: ключ только для чтения (`key_read_only`) или OAuth-токен без него (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"404":{"description":"Модель не найдена (`model_not_found`)."},"429":{"description":"Исчерпан лимит расхода ключа, которым сделан запрос (`daily_limit_exceeded`, `key_limit_exceeded`)."},"503":{"description":"Коннекторы временно недоступны (`bitrix24_unavailable`)."}}},"get":{"operationId":"listBitrix24Connectors","tags":["Integrations"],"summary":"Список коннекторов Битрикс24","description":"Действующие коннекторы аккаунта, новые первыми: имя, модель, префикс выпущенного ключа, время создания и последнего использования. `completions_url` не возвращается — он показывается только при создании.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"responses":{"200":{"description":"Коннекторы.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bitrix24ConnectorList"}}}},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"403":{"description":"Нет права `chat:write`: ключ только для чтения (`key_read_only`) или OAuth-токен без него (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."}}}},"/v1/integrations/bitrix24/connectors/{id}":{"delete":{"operationId":"deleteBitrix24Connector","tags":["Integrations"],"summary":"Удалить коннектор Битрикс24","description":"Удаляет коннектор и отзывает выпущенный им ключ. Движок в портале уберите сами (`ai.engine.unregister`), иначе CoPilot продолжит слать запросы на несуществующий адрес.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"parameters":[{"schema":{"type":"string","format":"uuid","description":"ID коннектора из ответа создания или списка."},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Коннектор удалён.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Bitrix24ConnectorDeleted"}}}},"401":{"description":"Ключ не передан, невалиден, отозван или заморожен (`invalid_api_key`, `key_frozen_spike`)."},"403":{"description":"Нет права `chat:write`: ключ только для чтения (`key_read_only`) или OAuth-токен без него (`insufficient_scope`). Ещё причины: management-ключ (`inference_key_required`), запрос не с адреса, к которому привязан ключ (`key_ip_not_allowed`), или заблокированный аккаунт (`account_blocked`)."},"404":{"description":"Коннектора нет, он чужой или уже удалён (`not_found`)."}}}},"/v1/models":{"get":{"operationId":"listModels","tags":["Models"],"summary":"Список доступных моделей","description":"Возвращает активные модели с ценами в рублях за 1М токенов.\n\nБез параметра — только модели, которые отвечают текстом (в том числе с картинкой или голосом в ответе). Остальные категории — по фильтру `?output_modalities=`: `embeddings`, `image`, `video`, `speech`, `transcription`, `decisions`, `rerank`; весь каталог — `?output_modalities=all`.\n\nЕдиницу тарификации даёт `pricing.unit`: `token` — цены за 1М токенов, `unit` — оплата в других единицах (реальная цена в `pricing.per_unit`, токенные поля нулевые), `unknown` — тариф не публикуется, списывается фактическая стоимость. Не умножайте `input_rub_per_million` на токены, не проверив `unit`.\n\nКлюч необязателен: без него отдаётся публичный каталог, с ключом — тот же каталог плюс ваши цепочки резервных моделей `route/<slug>`.\n\nБесплатные модели помечены флагом `pricing.is_free`. Не определяйте бесплатность по `input_rub_per_million === 0`: у моделей с оплатой в других единицах (за изображение, за секунду видео) цена за токены нулевая, а запрос платный. У бесплатных есть лимиты на стороне провайдера модели, которые провайдер не публикует, поэтому в пиковые часы возможны ответы 429. Подробности: /docs/concepts/free-models.","security":[{},{"bearerAuth":[]},{"oauth2":["models:read"]}],"parameters":[{"schema":{"type":"string","maxLength":100,"description":"Фильтр по выходной модальности (CSV). Без параметра — `text`; `all` — весь каталог.","example":"decisions"},"required":false,"name":"output_modalities","in":"query"}],"responses":{"200":{"description":"OpenAI-совместимый список моделей.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelsList"}}}},"401":{"description":"Передан невалидный API-ключ (без ключа каталог отдаётся публично).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelsErrorResponse"}}}},"429":{"description":"Превышен дневной лимит ключа.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelsErrorResponse"}}}},"503":{"description":"Не удалось получить курс ЦБ РФ — каталог временно недоступен.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ModelsErrorResponse"}}}}}}},"/v1/videos/models":{"get":{"operationId":"listVideoModels","tags":["Videos"],"summary":"Каталог видео-моделей","description":"Активные видео-модели с ценами в рублях за единицу (секунда/видео).\nАпстрим-цены в USD и внутренние SKU не раскрываются.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Список видео-моделей.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoModelsList"}}}},"401":{"description":"Невалидный или отсутствующий API-ключ.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoModelsErrorResponse"}}}},"503":{"description":"Не удалось получить курс ЦБ РФ — каталог временно недоступен.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VideoModelsErrorResponse"}}}}}}},"/v1/chat/completions":{"post":{"operationId":"createChatCompletion","tags":["Chat"],"summary":"Создать chat completion","description":"OpenAI-совместимый chat completions endpoint.\n\nПри `stream: true` возвращает Server-Sent Events стрим из chunk-ов в формате `chat.completion.chunk`.\nПодробности SSE-формата — на странице [Streaming](/docs/api/streaming).\n\nHubris автоматически добавляет `stream_options: { include_usage: true }` ко всем stream-запросам, поэтому usage приходит в последнем chunk-е перед `[DONE]`.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionRequest"}}}},"responses":{"200":{"description":"Успешный ответ. При `stream: false` — `chat.completion`. При `stream: true` — `text/event-stream` с chunk-ами `chat.completion.chunk`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionResponse"}},"text/event-stream":{"schema":{"type":"string","description":"SSE-stream chunk-ов. См. /docs/api/streaming."}}}},"400":{"description":"Невалидное тело запроса","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionErrorResponse"}}}},"401":{"description":"Невалидный API-ключ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionErrorResponse"}}}},"402":{"description":"Недостаточно средств на балансе","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionErrorResponse"}}}},"404":{"description":"Модель не найдена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionErrorResponse"}}}},"429":{"description":"Превышен дневной лимит ключа","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionErrorResponse"}}}},"502":{"description":"Ошибка апстрима","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionErrorResponse"}}}},"503":{"description":"Курс ЦБ РФ временно недоступен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionErrorResponse"}}}},"504":{"description":"Таймаут апстрима","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ChatCompletionErrorResponse"}}}}}}},"/v1/images/generations":{"post":{"operationId":"createImage","tags":["Images"],"summary":"Сгенерировать изображение","description":"OpenAI Images API-совместимая генерация картинок по текстовому описанию. Картинки приходят в base64 (`b64_json`).\n\nМодели с генерацией изображений: `GET /v1/models?output_modalities=image`. Провайдер-специфичные поля (`aspect_ratio`, `resolution`, `seed`, `input_references`) передаются как есть. Списание — по итоговой стоимости картинок.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ImageGenerationRequest"}}}},"responses":{"200":{"description":"Сгенерированные изображения: `{ created, data: [{ b64_json }] }`"},"400":{"description":"Невалидный запрос"},"402":{"description":"Недостаточно средств"},"404":{"description":"Модель не найдена"},"502":{"description":"Ошибка апстрима / не удалось определить стоимость"},"503":{"description":"Курс валют недоступен"}}}},"/v1/responses":{"post":{"operationId":"createResponse","tags":["Responses"],"summary":"Создать response (beta)","description":"OpenAI-совместимый Responses API endpoint. **BETA** — schema нестабильна, поля могут меняться.\n\nПри `stream: true` возвращает Server-Sent Events стрим. Usage приходит в `response.completed` event.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesRequest"}}}},"responses":{"200":{"description":"Успешный ответ. При `stream: false` — JSON. При `stream: true` — `text/event-stream`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesResponse"}},"text/event-stream":{"schema":{"type":"string","description":"SSE-stream events (см. /docs/api/responses, beta)."}}}},"400":{"description":"Невалидное тело","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesErrorResponse"}}}},"401":{"description":"Невалидный API-ключ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesErrorResponse"}}}},"402":{"description":"Недостаточно средств","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesErrorResponse"}}}},"404":{"description":"Модель не найдена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesErrorResponse"}}}},"429":{"description":"Превышен дневной лимит ключа","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesErrorResponse"}}}},"502":{"description":"Ошибка апстрима","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesErrorResponse"}}}},"503":{"description":"Курс ЦБ РФ недоступен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesErrorResponse"}}}},"504":{"description":"Таймаут апстрима","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResponsesErrorResponse"}}}}}}},"/v1/messages":{"post":{"operationId":"createMessage","tags":["Messages"],"summary":"Создать сообщение (Anthropic Messages API)","description":"Anthropic-совместимый endpoint. Принимает как Anthropic-имена моделей\n(`claude-sonnet-4-5`, `claude-3-5-sonnet-20241022`, `claude-haiku-4-5-latest`),\nтак и каноничные (`anthropic/claude-sonnet-4.6`). Поддерживает Bearer и\nx-api-key заголовки. Используется Claude Code и любыми Anthropic SDK\nчерез `ANTHROPIC_BASE_URL=https://api.hubris.pw`.\n\nПри `stream: true` — Server-Sent Events в нативном Anthropic-формате\n(`message_start` / `content_block_*` / `message_delta` / `message_stop`).\n\nPrivacy Mode на этом эндпоинте не поддерживается. Для маскирования PII\nиспользуйте `/v1/chat/completions`.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesRequest"}}}},"responses":{"200":{"description":"Успешный ответ. При `stream: false` — JSON. При `stream: true` — `text/event-stream`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesResponse"}},"text/event-stream":{"schema":{"type":"string","description":"Anthropic SSE-stream events (см. /docs/api/messages)."}}}},"400":{"description":"Невалидное тело","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesError"}}}},"401":{"description":"Невалидный API-ключ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesError"}}}},"402":{"description":"Недостаточно средств","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesError"}}}},"404":{"description":"Модель не найдена","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesError"}}}},"429":{"description":"Превышен дневной лимит ключа","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesError"}}}},"502":{"description":"Ошибка апстрима","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesError"}}}},"503":{"description":"Курс ЦБ РФ недоступен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesError"}}}},"504":{"description":"Таймаут апстрима","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AnthropicMessagesError"}}}}}}},"/v1/embeddings":{"post":{"operationId":"createEmbedding","tags":["Embeddings"],"summary":"Создать эмбеддинги","description":"OpenAI-совместимый embeddings endpoint. Превращает текст в вектор фиксированной длины — для семантического поиска, RAG, классификации.\n\nПринимает строку, массив строк (батч до 2048), массив токен-ID или массив массивов токен-ID. Биллинг — только по `prompt_tokens` (output всегда 0).\n\nСтрима нет. Полный список embedding-моделей: `GET /v1/models` с фильтром `output_modalities=embeddings`.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsRequest"}}}},"responses":{"200":{"description":"Успешный ответ — список эмбеддингов в порядке `input`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsResponse"}}}},"400":{"description":"Невалидное тело запроса","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsErrorResponse"}}}},"401":{"description":"Невалидный API-ключ","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsErrorResponse"}}}},"402":{"description":"Недостаточно средств на балансе","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsErrorResponse"}}}},"404":{"description":"Модель не найдена или не поддерживает embeddings","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsErrorResponse"}}}},"429":{"description":"Превышен дневной лимит ключа","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsErrorResponse"}}}},"502":{"description":"Ошибка апстрима","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsErrorResponse"}}}},"503":{"description":"Курс ЦБ РФ временно недоступен","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsErrorResponse"}}}},"504":{"description":"Таймаут апстрима","content":{"application/json":{"schema":{"$ref":"#/components/schemas/EmbeddingsErrorResponse"}}}}}}},"/v1/decisions":{"post":{"operationId":"createDecision","tags":["Decisions"],"summary":"Задать вопросы модели решений","description":"Модели решений (например, `typesafe/jev-1.13`) не пишут текст. Вы передаёте данные (`state`) и вопросы (`questions`), модель возвращает ответы с вероятностями.\n\nТипы вопросов: `noul` — да или нет, `choice` — вариант из списка, `score` — уровень на шкале. Все вопросы решаются за один запрос.\n\nПлатится только вход (`usage.input_tokens`), выход бесплатный. `usage.cost` — списано в копейках. Стрима нет.\n\nСписок моделей: `GET /v1/models`, фильтр по `output_modalities`, содержащему `decisions`.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionsRequest"}}}},"responses":{"200":{"description":"Ответы на все вопросы.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DecisionsResponse"}}}},"400":{"description":"Невалидное тело запроса"},"401":{"description":"Невалидный API-ключ"},"402":{"description":"Недостаточно средств на балансе"},"404":{"description":"Модель не найдена или это не модель решений"},"429":{"description":"Превышен лимит запросов"},"502":{"description":"Ошибка апстрима"},"503":{"description":"Курс валют временно недоступен"},"504":{"description":"Таймаут апстрима"}}}},"/v1/rerank":{"post":{"operationId":"createRerank","tags":["Rerank"],"summary":"Отсортировать документы по запросу","description":"Реранкер (например, `cohere/rerank-v3.5`) сортирует документы по тому, насколько они отвечают на запрос: `results` — номера документов во входном списке и оценка `relevance_score`, лучшие первыми.\n\nОплата у Cohere — за поиск (`usage.search_units`), у остальных — за токены входа. `usage.cost` — списано в копейках. Стрима нет.\n\nСписок моделей: `GET /v1/models?output_modalities=rerank`.","security":[{"bearerAuth":[]},{"oauth2":["chat:write"]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RerankRequest"}}}},"responses":{"200":{"description":"Документы, отсортированные по близости к запросу.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/RerankResponse"}}}},"400":{"description":"Невалидное тело запроса"},"401":{"description":"Невалидный API-ключ"},"402":{"description":"Недостаточно средств на балансе"},"404":{"description":"Модель не найдена или это не реранкер"},"429":{"description":"Превышен лимит запросов"},"502":{"description":"Ошибка апстрима"},"503":{"description":"Курс валют временно недоступен"},"504":{"description":"Таймаут апстрима"}}}},"/v1/usage":{"get":{"operationId":"getUsage","tags":["Usage"],"summary":"Расход по API-ключу за период","description":"Возвращает итоговые расходы (рубли + копейки + токены + количество запросов) по тому API-ключу, которым сделан запрос; OAuth-токену — по всему подключению приложения (токен меняется каждый час, сумма — по всем токенам подключения). По умолчанию — последние 24 часа. Можно передать шорткат `?period=` либо явные `?from=&to=` (ISO 8601, UTC). Опциональный `?granularity=` добавит массив `buckets` для построения графика.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","enum":["today","24h","7d","30d","mtd"],"description":"Шорткат периода. `today` = с 00:00 UTC текущих суток. `24h` = последние 24ч. `7d`/`30d` = последние N суток. `mtd` = с 1-го числа текущего месяца UTC. Несовместим с `from`/`to`."},"required":false,"name":"period","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Начало периода, ISO 8601. Если задан — `to` тоже обязателен."},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Конец периода, ISO 8601. Если задан — `from` тоже обязателен."},"required":false,"name":"to","in":"query"},{"schema":{"type":"string","enum":["hour","day"],"description":"Если указан — в ответе появится массив `buckets` с агрегатами по этому шагу."},"required":false,"name":"granularity","in":"query"},{"schema":{"type":"string","format":"uuid","description":"Только management-ключом: сузить аккаунт-скоуп до одного API-ключа."},"required":false,"name":"key_id","in":"query"},{"schema":{"type":"string","enum":["key","model"],"description":"Только management-ключом: добавить разбивку `by_key` или `by_model`."},"required":false,"name":"group_by","in":"query"}],"responses":{"200":{"description":"Расход по ключу за указанный период.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageResponse"}}}},"400":{"description":"Невалидные параметры периода (range_invalid / range_too_long / period_invalid).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageErrorResponse"}}}},"401":{"description":"Невалидный или отсутствующий API-ключ.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageErrorResponse"}}}},"429":{"description":"Превышен дневной лимит ключа.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/UsageErrorResponse"}}}}}}},"/v1/keys":{"get":{"operationId":"listApiKeys","tags":["Management"],"summary":"Список API-ключей аккаунта","description":"Возвращает активные inference-ключи аккаунта. Требует management-ключ (sk-gw-mgmt-...). Полные ключи не возвращаются — только маскированные префиксы.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0},"required":false,"name":"offset","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":100},"required":false,"name":"limit","in":"query"}],"responses":{"200":{"description":"Страница ключей.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"key_prefix":{"type":"string","example":"sk-gw-ab12...cd34"},"disabled":{"type":"boolean"},"limit_kopecks":{"type":"integer","nullable":true,"description":"Лимит расхода ключа в копейках за период `limit_period`. null = без лимита."},"limit_period":{"type":"string","enum":["day","week","month","none"],"description":"Период сброса лимита: day — календарные сутки (00:00 МСК), week — с понедельника, month — с 1-го числа, none — без сброса (лимит на весь расход ключа)."},"spent_period_kopecks":{"type":"integer","description":"Потрачено этим ключом в текущем периоде, в копейках."},"limit_remaining_kopecks":{"type":"integer","nullable":true,"description":"Сколько ещё можно потратить в текущем периоде: лимит минус траты минус резервы роликов в работе, не меньше 0. null — без лимита."},"period_reset_at":{"type":"string","nullable":true,"description":"Момент следующего сброса (ISO 8601); null для limit_period=none."},"daily_limit_kopecks":{"type":"integer","nullable":true,"description":"Устаревшее. Равно limit_kopecks при limit_period=day, иначе null. Используйте limit_kopecks."},"spent_24h_kopecks":{"type":"integer","description":"Устаревшее. Равно spent_period_kopecks. Используйте spent_period_kopecks."},"read_only":{"type":"boolean","description":"Ключ только для чтения: каталог моделей, баланс и статистика доступны, запросы к моделям (всё, что тратит баланс) — 403 key_read_only."},"allowed_ips":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Привязка к адресу: IPv4/IPv6-адреса и подсети (CIDR), с которых ключ принимает запросы; null — с любого адреса. Запрос с другого адреса — 403 key_ip_not_allowed.","example":["203.0.113.5","198.51.100.0/24"]},"disabled_reason":{"type":"string","nullable":true,"enum":["manual","spike"],"description":"Почему ключ отключён: manual — вручную, spike — заморозка при всплеске трат; null — включён."},"disabled_until":{"type":"string","nullable":true,"description":"Момент автоматического включения после заморозки (ISO 8601); null — до ручного включения или ключ включён."},"spike_limit_kopecks":{"type":"integer","nullable":true,"description":"Защита от всплеска: порог расхода в копейках за окно spike_window_minutes; null — выключена."},"spike_window_minutes":{"type":"integer","nullable":true,"description":"Окно защиты от всплеска: 1, 5, 15, 30 или 60 минут."},"spike_cooldown_minutes":{"type":"integer","nullable":true,"description":"Период охлаждения: через сколько минут ключ включится снова (15, 60, 360, 1440); null — до ручного включения."},"privacy_mask_default":{"type":"string","enum":["inherit","off","on","required"]},"last_used_at":{"type":"string","nullable":true},"created_at":{"type":"string"}},"required":["id","name","key_prefix","disabled","limit_kopecks","limit_period","spent_period_kopecks","limit_remaining_kopecks","period_reset_at","daily_limit_kopecks","spent_24h_kopecks","read_only","allowed_ips","disabled_reason","disabled_until","spike_limit_kopecks","spike_window_minutes","spike_cooldown_minutes","privacy_mask_default","last_used_at","created_at"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]}}}},"401":{"description":"Невалидный ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"403":{"description":"Нужен management-ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"429":{"description":"Превышен rate limit (60/мин).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}}}},"post":{"operationId":"createApiKey","tags":["Management"],"summary":"Создать API-ключ","description":"Создаёт новый inference-ключ. Полный ключ возвращается один раз в поле `key` — сохраните его сразу, повторно получить его нельзя. Лимиты: 30 созданий в час, не более 500 активных ключей на аккаунт.","security":[{"bearerAuth":[]}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"limit_kopecks":{"type":"integer","nullable":true,"minimum":1,"maximum":10000000000},"limit_period":{"type":"string","enum":["day","week","month","none"],"description":"Период сброса лимита: day (по умолчанию), week, month, none — без сброса."},"daily_limit_kopecks":{"type":"integer","nullable":true,"minimum":1,"maximum":10000000000},"read_only":{"type":"boolean","description":"Ключ только для чтения — без запросов к моделям. По умолчанию false."},"allowed_ips":{"type":"array","nullable":true,"items":{"type":"string","maxLength":64},"maxItems":100,"description":"Привязка к адресу: до 32 записей — IPv4/IPv6-адрес или подсеть (CIDR). null или [] — снять привязку (любой адрес).","example":["203.0.113.5","198.51.100.0/24"]},"privacy_mask_default":{"type":"string","enum":["inherit","off","on","required"]}},"required":["name"]}}}},"responses":{"201":{"description":"Ключ создан. Поле `key` — полный ключ, показывается один раз.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"key_prefix":{"type":"string","example":"sk-gw-ab12...cd34"},"disabled":{"type":"boolean"},"limit_kopecks":{"type":"integer","nullable":true,"description":"Лимит расхода ключа в копейках за период `limit_period`. null = без лимита."},"limit_period":{"type":"string","enum":["day","week","month","none"],"description":"Период сброса лимита: day — календарные сутки (00:00 МСК), week — с понедельника, month — с 1-го числа, none — без сброса (лимит на весь расход ключа)."},"spent_period_kopecks":{"type":"integer","description":"Потрачено этим ключом в текущем периоде, в копейках."},"limit_remaining_kopecks":{"type":"integer","nullable":true,"description":"Сколько ещё можно потратить в текущем периоде: лимит минус траты минус резервы роликов в работе, не меньше 0. null — без лимита."},"period_reset_at":{"type":"string","nullable":true,"description":"Момент следующего сброса (ISO 8601); null для limit_period=none."},"daily_limit_kopecks":{"type":"integer","nullable":true,"description":"Устаревшее. Равно limit_kopecks при limit_period=day, иначе null. Используйте limit_kopecks."},"spent_24h_kopecks":{"type":"integer","description":"Устаревшее. Равно spent_period_kopecks. Используйте spent_period_kopecks."},"read_only":{"type":"boolean","description":"Ключ только для чтения: каталог моделей, баланс и статистика доступны, запросы к моделям (всё, что тратит баланс) — 403 key_read_only."},"allowed_ips":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Привязка к адресу: IPv4/IPv6-адреса и подсети (CIDR), с которых ключ принимает запросы; null — с любого адреса. Запрос с другого адреса — 403 key_ip_not_allowed.","example":["203.0.113.5","198.51.100.0/24"]},"disabled_reason":{"type":"string","nullable":true,"enum":["manual","spike"],"description":"Почему ключ отключён: manual — вручную, spike — заморозка при всплеске трат; null — включён."},"disabled_until":{"type":"string","nullable":true,"description":"Момент автоматического включения после заморозки (ISO 8601); null — до ручного включения или ключ включён."},"spike_limit_kopecks":{"type":"integer","nullable":true,"description":"Защита от всплеска: порог расхода в копейках за окно spike_window_minutes; null — выключена."},"spike_window_minutes":{"type":"integer","nullable":true,"description":"Окно защиты от всплеска: 1, 5, 15, 30 или 60 минут."},"spike_cooldown_minutes":{"type":"integer","nullable":true,"description":"Период охлаждения: через сколько минут ключ включится снова (15, 60, 360, 1440); null — до ручного включения."},"privacy_mask_default":{"type":"string","enum":["inherit","off","on","required"]},"last_used_at":{"type":"string","nullable":true},"created_at":{"type":"string"},"key":{"type":"string","description":"Полный API-ключ. Показывается ТОЛЬКО в этом ответе — сохраните его сразу.","example":"sk-gw-…"}},"required":["id","name","key_prefix","disabled","limit_kopecks","limit_period","spent_period_kopecks","limit_remaining_kopecks","period_reset_at","daily_limit_kopecks","spent_24h_kopecks","read_only","allowed_ips","disabled_reason","disabled_until","spike_limit_kopecks","spike_window_minutes","spike_cooldown_minutes","privacy_mask_default","last_used_at","created_at","key"]}}}},"400":{"description":"Невалидное тело запроса.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"401":{"description":"Невалидный ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"403":{"description":"Нужен management-ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"404":{"description":"Ключ не найден (гонка с параллельным отзывом).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"429":{"description":"Превышен лимит созданий или потолок ключей.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}}}}},"/v1/keys/{id}":{"get":{"operationId":"getApiKey","tags":["Management"],"summary":"Один API-ключ","description":"Ключ аккаунта по id: имя, префикс, лимит расхода и период его сброса, расход в текущем периоде, статус. Полный ключ не возвращается никогда — только при создании. Требует management-ключ (sk-gw-mgmt-...).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"key_prefix":{"type":"string","example":"sk-gw-ab12...cd34"},"disabled":{"type":"boolean"},"limit_kopecks":{"type":"integer","nullable":true,"description":"Лимит расхода ключа в копейках за период `limit_period`. null = без лимита."},"limit_period":{"type":"string","enum":["day","week","month","none"],"description":"Период сброса лимита: day — календарные сутки (00:00 МСК), week — с понедельника, month — с 1-го числа, none — без сброса (лимит на весь расход ключа)."},"spent_period_kopecks":{"type":"integer","description":"Потрачено этим ключом в текущем периоде, в копейках."},"limit_remaining_kopecks":{"type":"integer","nullable":true,"description":"Сколько ещё можно потратить в текущем периоде: лимит минус траты минус резервы роликов в работе, не меньше 0. null — без лимита."},"period_reset_at":{"type":"string","nullable":true,"description":"Момент следующего сброса (ISO 8601); null для limit_period=none."},"daily_limit_kopecks":{"type":"integer","nullable":true,"description":"Устаревшее. Равно limit_kopecks при limit_period=day, иначе null. Используйте limit_kopecks."},"spent_24h_kopecks":{"type":"integer","description":"Устаревшее. Равно spent_period_kopecks. Используйте spent_period_kopecks."},"read_only":{"type":"boolean","description":"Ключ только для чтения: каталог моделей, баланс и статистика доступны, запросы к моделям (всё, что тратит баланс) — 403 key_read_only."},"allowed_ips":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Привязка к адресу: IPv4/IPv6-адреса и подсети (CIDR), с которых ключ принимает запросы; null — с любого адреса. Запрос с другого адреса — 403 key_ip_not_allowed.","example":["203.0.113.5","198.51.100.0/24"]},"disabled_reason":{"type":"string","nullable":true,"enum":["manual","spike"],"description":"Почему ключ отключён: manual — вручную, spike — заморозка при всплеске трат; null — включён."},"disabled_until":{"type":"string","nullable":true,"description":"Момент автоматического включения после заморозки (ISO 8601); null — до ручного включения или ключ включён."},"spike_limit_kopecks":{"type":"integer","nullable":true,"description":"Защита от всплеска: порог расхода в копейках за окно spike_window_minutes; null — выключена."},"spike_window_minutes":{"type":"integer","nullable":true,"description":"Окно защиты от всплеска: 1, 5, 15, 30 или 60 минут."},"spike_cooldown_minutes":{"type":"integer","nullable":true,"description":"Период охлаждения: через сколько минут ключ включится снова (15, 60, 360, 1440); null — до ручного включения."},"privacy_mask_default":{"type":"string","enum":["inherit","off","on","required"]},"last_used_at":{"type":"string","nullable":true},"created_at":{"type":"string"}},"required":["id","name","key_prefix","disabled","limit_kopecks","limit_period","spent_period_kopecks","limit_remaining_kopecks","period_reset_at","daily_limit_kopecks","spent_24h_kopecks","read_only","allowed_ips","disabled_reason","disabled_until","spike_limit_kopecks","spike_window_minutes","spike_cooldown_minutes","privacy_mask_default","last_used_at","created_at"]}}}},"401":{"description":"Невалидный ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"403":{"description":"Нужен management-ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"404":{"description":"Ключ не найден.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"429":{"description":"Превышен rate limit.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}}}},"patch":{"operationId":"updateApiKey","tags":["Management"],"summary":"Изменить API-ключ","description":"Частичное обновление: имя, обратимое отключение (`disabled`), лимит расхода (`limit_kopecks`, null — снять) и период его сброса (`limit_period`), режим «только чтение», привязка к адресу (`allowed_ips`, null — снять), защита от всплеска, режим приватности. Устаревшее `daily_limit_kopecks` = лимит с периодом day.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":100},"disabled":{"type":"boolean"},"limit_kopecks":{"type":"integer","nullable":true,"minimum":1,"maximum":10000000000},"limit_period":{"type":"string","enum":["day","week","month","none"],"description":"Период сброса лимита: day (по умолчанию), week, month, none — без сброса."},"daily_limit_kopecks":{"type":"integer","nullable":true,"minimum":1,"maximum":10000000000},"read_only":{"type":"boolean","description":"Переключить «только чтение»; обратимо."},"allowed_ips":{"type":"array","nullable":true,"items":{"type":"string","maxLength":64},"maxItems":100,"description":"Привязка к адресу: до 32 записей — IPv4/IPv6-адрес или подсеть (CIDR). null или [] — снять привязку (любой адрес).","example":["203.0.113.5","198.51.100.0/24"]},"spike_limit_kopecks":{"type":"integer","nullable":true,"minimum":100,"maximum":10000000,"description":"Защита от всплеска: порог в копейках; null — выключить. Вместе с ним обязателен spike_window_minutes."},"spike_window_minutes":{"type":"integer","description":"Окно защиты: 1, 5, 15, 30 или 60 минут."},"spike_cooldown_minutes":{"type":"integer","nullable":true,"description":"Охлаждение: 15, 60, 360, 1440 минут или null — до ручного включения."},"privacy_mask_default":{"type":"string","enum":["inherit","off","on","required"]}}}}}},"responses":{"200":{"description":"Обновлённый ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"name":{"type":"string"},"key_prefix":{"type":"string","example":"sk-gw-ab12...cd34"},"disabled":{"type":"boolean"},"limit_kopecks":{"type":"integer","nullable":true,"description":"Лимит расхода ключа в копейках за период `limit_period`. null = без лимита."},"limit_period":{"type":"string","enum":["day","week","month","none"],"description":"Период сброса лимита: day — календарные сутки (00:00 МСК), week — с понедельника, month — с 1-го числа, none — без сброса (лимит на весь расход ключа)."},"spent_period_kopecks":{"type":"integer","description":"Потрачено этим ключом в текущем периоде, в копейках."},"limit_remaining_kopecks":{"type":"integer","nullable":true,"description":"Сколько ещё можно потратить в текущем периоде: лимит минус траты минус резервы роликов в работе, не меньше 0. null — без лимита."},"period_reset_at":{"type":"string","nullable":true,"description":"Момент следующего сброса (ISO 8601); null для limit_period=none."},"daily_limit_kopecks":{"type":"integer","nullable":true,"description":"Устаревшее. Равно limit_kopecks при limit_period=day, иначе null. Используйте limit_kopecks."},"spent_24h_kopecks":{"type":"integer","description":"Устаревшее. Равно spent_period_kopecks. Используйте spent_period_kopecks."},"read_only":{"type":"boolean","description":"Ключ только для чтения: каталог моделей, баланс и статистика доступны, запросы к моделям (всё, что тратит баланс) — 403 key_read_only."},"allowed_ips":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Привязка к адресу: IPv4/IPv6-адреса и подсети (CIDR), с которых ключ принимает запросы; null — с любого адреса. Запрос с другого адреса — 403 key_ip_not_allowed.","example":["203.0.113.5","198.51.100.0/24"]},"disabled_reason":{"type":"string","nullable":true,"enum":["manual","spike"],"description":"Почему ключ отключён: manual — вручную, spike — заморозка при всплеске трат; null — включён."},"disabled_until":{"type":"string","nullable":true,"description":"Момент автоматического включения после заморозки (ISO 8601); null — до ручного включения или ключ включён."},"spike_limit_kopecks":{"type":"integer","nullable":true,"description":"Защита от всплеска: порог расхода в копейках за окно spike_window_minutes; null — выключена."},"spike_window_minutes":{"type":"integer","nullable":true,"description":"Окно защиты от всплеска: 1, 5, 15, 30 или 60 минут."},"spike_cooldown_minutes":{"type":"integer","nullable":true,"description":"Период охлаждения: через сколько минут ключ включится снова (15, 60, 360, 1440); null — до ручного включения."},"privacy_mask_default":{"type":"string","enum":["inherit","off","on","required"]},"last_used_at":{"type":"string","nullable":true},"created_at":{"type":"string"}},"required":["id","name","key_prefix","disabled","limit_kopecks","limit_period","spent_period_kopecks","limit_remaining_kopecks","period_reset_at","daily_limit_kopecks","spent_24h_kopecks","read_only","allowed_ips","disabled_reason","disabled_until","spike_limit_kopecks","spike_window_minutes","spike_cooldown_minutes","privacy_mask_default","last_used_at","created_at"]}}}},"400":{"description":"Невалидное тело запроса.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"401":{"description":"Невалидный ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"403":{"description":"Нужен management-ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"404":{"description":"Ключ не найден.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"429":{"description":"Превышен rate limit.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}}}},"delete":{"operationId":"deleteApiKey","tags":["Management"],"summary":"Отозвать API-ключ","description":"Необратимый отзыв. Идемпотентно: повторный вызов по уже отозванному ключу тоже вернёт 200.","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"string","format":"uuid"},"required":true,"name":"id","in":"path"}],"responses":{"200":{"description":"Ключ отозван.","content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"deleted":{"type":"boolean","enum":[true]}},"required":["id","deleted"]}}}},"401":{"description":"Невалидный ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"403":{"description":"Нужен management-ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"404":{"description":"Ключ не найден.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"429":{"description":"Превышен rate limit.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}}}}},"/v1/key":{"get":{"operationId":"getCurrentKey","tags":["Management"],"summary":"Информация о текущем ключе","description":"Самоинтроспекция ключа, которым сделан запрос: имя, лимит расхода и период его сброса, расход в текущем периоде, остаток лимита и баланс аккаунта. Работает с обычным API-ключом — management-ключ не нужен.","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Данные текущего ключа.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"name":{"type":"string"},"key_prefix":{"type":"string","example":"sk-gw-ab12...cd34"},"key_type":{"type":"string","enum":["inference","management"]},"disabled":{"type":"boolean"},"limit_kopecks":{"type":"integer","nullable":true,"description":"Лимит расхода ключа в копейках за период limit_period. null = без лимита."},"limit_period":{"type":"string","enum":["day","week","month","none"]},"spent_period_kopecks":{"type":"integer","description":"Потрачено ключом в текущем периоде, в копейках."},"limit_remaining_kopecks":{"type":"integer","nullable":true,"description":"Сколько ещё можно потратить в текущем периоде: лимит минус траты минус резервы роликов в работе, не меньше 0. null — без лимита."},"period_reset_at":{"type":"string","nullable":true,"description":"Момент следующего сброса (ISO 8601); null для limit_period=none."},"daily_limit_kopecks":{"type":"integer","nullable":true,"description":"Устаревшее: limit_kopecks при limit_period=day, иначе null."},"spent_24h_kopecks":{"type":"integer","description":"Устаревшее: равно spent_period_kopecks."},"read_only":{"type":"boolean","description":"Ключ только для чтения: запросы к моделям ему запрещены (403 key_read_only)."},"allowed_ips":{"type":"array","nullable":true,"items":{"type":"string"},"description":"Привязка к адресу: адреса и подсети, с которых ключ принимает запросы; null — с любого."},"balance_kopecks":{"type":"integer","description":"Текущий баланс аккаунта в копейках."},"created_at":{"type":"string"}},"required":["name","key_prefix","key_type","disabled","limit_kopecks","limit_period","spent_period_kopecks","limit_remaining_kopecks","period_reset_at","daily_limit_kopecks","spent_24h_kopecks","read_only","allowed_ips","balance_kopecks","created_at"]}},"required":["data"]}}}},"401":{"description":"Невалидный ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"403":{"description":"OAuth-токены не поддерживаются этим эндпоинтом.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}}}}},"/v1/credits":{"get":{"operationId":"getCredits","tags":["Management"],"summary":"Баланс аккаунта","description":"Основной и бонусный балансы аккаунта в копейках. Требует management-ключ (sk-gw-mgmt-...).","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Балансы аккаунта.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"object","properties":{"balance_kopecks":{"type":"integer","description":"Основной баланс в копейках."},"bonus_balance_kopecks":{"type":"integer","description":"Доступный для списания бонусный баланс в копейках (невыводимые кредиты; реферальная часть может быть временно недоступна до первой оплаты аккаунта)."},"currency":{"type":"string","enum":["RUB"]}},"required":["balance_kopecks","bonus_balance_kopecks","currency"]}},"required":["data"]}}}},"401":{"description":"Невалидный ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"403":{"description":"Нужен management-ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"429":{"description":"Превышен rate limit (60/мин).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}}}}},"/v1/transactions":{"get":{"operationId":"listTransactions","tags":["Management"],"summary":"История транзакций","description":"Пополнения, списания, возвраты и бонусные операции аккаунта, свежие сверху. Требует management-ключ (sk-gw-mgmt-...).","security":[{"bearerAuth":[]}],"parameters":[{"schema":{"type":"integer","nullable":true,"minimum":0,"default":0},"required":false,"name":"offset","in":"query"},{"schema":{"type":"integer","minimum":1,"maximum":100,"default":50},"required":false,"name":"limit","in":"query"},{"schema":{"type":"string","enum":["topup","usage","refund","adjustment","mcp_debit","mcp_refund","referral_bonus","bonus_accrual","bonus_spend","bonus_expire","bonus","video_precharge","video_reconcile"]},"required":false,"name":"type","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Начало периода, ISO 8601."},"required":false,"name":"from","in":"query"},{"schema":{"type":"string","format":"date-time","description":"Конец периода, ISO 8601."},"required":false,"name":"to","in":"query"}],"responses":{"200":{"description":"Страница транзакций.","content":{"application/json":{"schema":{"type":"object","properties":{"object":{"type":"string","enum":["list"]},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"type":{"type":"string","enum":["topup","usage","refund","adjustment","mcp_debit","mcp_refund","referral_bonus","bonus_accrual","bonus_spend","bonus_expire","bonus","video_precharge","video_reconcile"]},"status":{"type":"string","enum":["pending","succeeded","failed","cancelled"]},"amount_kopecks":{"type":"integer","description":"Сумма операции в копейках: положительная — зачисление, отрицательная — списание."},"balance_after_kopecks":{"type":"integer"},"payment_method":{"type":"string","nullable":true,"enum":["sbp","card","invoice"],"description":"Способ пополнения; null для не-topup операций."},"created_at":{"type":"string"}},"required":["id","type","status","amount_kopecks","balance_after_kopecks","payment_method","created_at"]}},"has_more":{"type":"boolean"}},"required":["object","data","has_more"]}}}},"400":{"description":"Невалидные параметры.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"401":{"description":"Невалидный ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"403":{"description":"Нужен management-ключ.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}},"429":{"description":"Превышен rate limit (60/мин).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"message":{"type":"string"},"type":{"type":"string"},"code":{"type":"string"}},"required":["message","type","code"]}},"required":["error"]}}}}}}}}}