QVORA API
Один API.
Все ваши модели.
Текст, изображения, видео и аудио через один ключ.
Подключите привычный SDK и платите за использование в рублях.
https://qvora.ru/api/v1Быстрый старт
Первый запрос за несколько шагов
Для начала понадобятся аккаунт компании, API-ключ и средства на балансе организации. Примеры ниже выполняются на вашем сервере или компьютере.
Создайте ключ
Откройте кабинет компании → «Ключи». Создайте ключ со скоупом chat и сохраните его: полный ключ показывается один раз. Пополните баланс компании в кабинете.
Подготовьте окружение
Сохраните ключ в переменной окружения. Для cURL установка SDK не требуется.
export QVORA_API_KEY="shds-ВАШ_КЛЮЧ"python -m pip install openaiКоманды cURL на этой странице используют синтаксис Bash. В Windows запустите их в WSL / Git Bash или выберите пример Python.
Отправьте сообщение
Выберите язык и скопируйте пример. Python сохраните в example.py и запустите python example.py; JavaScript — в example.mjs, запуск node example.mjs.
curl --fail-with-body "https://qvora.ru/api/v1/chat/completions" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5-mini",
"messages": [
{
"role": "user",
"content": "Ответь одним словом: привет!"
}
],
"max_completion_tokens": 1024
}'SDK выведет приветствие модели. В cURL текст находится в choices[0].message.content, расход — в qvora.cost_rub.
Посмотреть полный пример ответа
{
"id": "chatcmpl-example",
"object": "chat.completion",
"created": 1790000000,
"model": "gpt-5-mini",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Привет!"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 18,
"completion_tokens": 4,
"total_tokens": 22,
"prompt_tokens_details": {
"cached_tokens": 0
},
"completion_tokens_details": {
"reasoning_tokens": 0
}
},
"qvora": {
"served_model": "gpt-5-mini",
"cost_rub": 0.1,
"cache_saved_rub": 0,
"request_ref": "reservation_example"
}
}Идентификаторы, токены и суммы в примерах условные. Фактическую стоимость возвращает API.
Авторизация и права ключа
Передавайте ключ организации в каждом запросе. Основной способ — заголовок Authorization; x-api-key подходит для клиентов Anthropic. Используйте один из вариантов.
Authorization: Bearer shds-ВАШ_КЛЮЧ| Скоуп | Что разрешает |
|---|---|
chat | Chat Completions, Responses, Messages и count_tokens |
embeddings | Получение эмбеддингов |
media | Каталог медиа, создание и чтение задач, отмена, транскрибация |
usage | Сводка расходов и детализация запросов организации |
admin | Управление ключами, группами и сотрудниками, аудит и расходы |
GET /models, GET /models/{id} и GET /balance требуют действующий ключ без дополнительного скоупа. OpenAPI-схема доступна без авторизации.
Ключ списывает средства с баланса своей организации. В настройках доступны денежные лимиты, RPM, TPM, число параллельных запросов, разрешённые модели, IP-адреса и срок действия. Изменения применяются следующим запросом. Отзыв действует сразу, при ротации старый ключ по умолчанию живёт ещё 24 часа.
Модели и возможности
/modelsКаталог возвращает текстовые модели и эмбеддинги по прайс-буку вашего контракта. Передавайте data[].id в поле model. Псевдонимы перечислены в qvora.aliases; фактически выбранная модель указана в ответе генерации.
curl --fail-with-body "https://qvora.ru/api/v1/models" \
-H "Authorization: Bearer $QVORA_API_KEY"| Поле объекта модели | Как использовать |
|---|---|
id | Идентификатор для запроса, например gpt-5-mini или claude-sonnet |
qvora.type | text или embedding |
qvora.capabilities | vision, tools, json_schema, reasoning, streaming и список protocols |
qvora.context_tokens / max_output_tokens | Контекст и максимум ответа модели |
qvora.price_rub_per_1k | Цена в ₽ за 1 000 входных, кэшированных и выходных токенов |
Поддержка возможностей зависит от модели. Для инструментов проверьте tools, для JSON Schema — json_schema, для изображений во входе — vision. Allowlist ключа дополнительно ограничивает запуск. Медиа-модели и параметры их операций доступны в GET /media/models.
Текстовые модели
Chat Completions
/chat/completionsскоуп: chatПередайте историю диалога в messages. API возвращает сообщение ассистента, число токенов и стоимость. Историю хранит ваше приложение: в следующем запросе отправьте предыдущие сообщения вместе с новым.
Параметры запроса
modelstringid из /models или псевдоним (gpt-5.5, claude-sonnet-5, …)
messagesobject[]обязательноПоля messages[]
role"system" | "developer" | "user" | "assistant" | "tool"contentstring | any[] | nulltool_callsany[]tool_call_idstringnamestringtoolsobject[]Поля tools[]
type"function"functionobjectПоля function
namestringdescriptionstringparametersobjectstrictbooleantool_choice"auto" | "none" | "required" | objectparallel_tool_callsbooleanresponse_formatobjectПоля response_format
type"text" | "json_object" | "json_schema"json_schemaobjecttemperaturenumberМинимум: 0. Максимум: 2.
top_pnumbermax_tokensintegermax_completion_tokensintegerstopstring | any[]seedintegerpresence_penaltynumberfrequency_penaltynumberreasoning_effort"low" | "medium" | "high"streambooleanstream_optionsobjectПоля stream_options
include_usagebooleanuserstringИдентификатор конечного пользователя — попадает в /usage (end_user)
obfuscateboolean | "placeholder" | "surrogate" | "off" | objectМаскировка персональных данных перед отправкой провайдеру и восстановление в ответе (в т.ч. в стриме и в аргументах tool_calls). `true`/`"placeholder"` — метки `<<PER0>>`, `<<PHONE1>>`; `"surrogate"` — правдоподобные подмены для ФИО, почты и телефонов (модель склоняет имя, мы восстанавливаем в том же падеже), остальное — метками. Если организация включила обязательную маскировку, `false` её не выключает. Альтернатива телу — заголовок `x-qvora-obfuscate: placeholder|surrogate|off`.
obfuscate_patternsobject[]Свои регулярные выражения (JS RegExp; `(?P<name>…)` и `(?i)` из Python принимаются). С группами — маскируется содержимое групп.
Поля obfuscate_patterns[]
patternstringобязательноДо 500 символов.
labelstringПо умолчанию: "CUSTOM".
obfuscate_types"PER" | "ORG" | "LOC" | "PHONE" | "EMAIL" | "CARD" | "ID" | "MSC"[]Какие типы маскировать (по умолчанию — все или по политике организации)
obfuscate_allowstring[]Значения, которые не маскировать (названия ваших продуктов, публичные лица)
| Параметр | Что передавать |
|---|---|
model | ID или псевдоним модели. Лучше задавать явно. |
messages | Непустой массив; роли system, developer, user, assistant, tool. |
max_completion_tokens | Предел ответа. По умолчанию 2 048, с ограничением максимумом модели. Алиас — max_tokens. |
temperature / top_p | 0–2 и 0–1 соответственно; доступность зависит от модели. |
user | Ваш идентификатор конечного пользователя, до 128 символов. Появится в usage как end_user. |
Изображение во входном сообщении
Для анализа изображения используйте image_url в сообщении пользователя. Поддерживаются URL и data: URI. Замените адрес ниже на доступное модели изображение.
curl --fail-with-body "https://qvora.ru/api/v1/chat/completions" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5-mini",
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": "Что изображено на фотографии?"
},
{
"type": "image_url",
"image_url": {
"url": "https://example.com/photo.jpg"
}
}
]
}
]
}'Поля ответа
choices[0].finish_reason объясняет завершение: stop — ответ закончен, length — достигнут предел, tool_calls — нужно выполнить инструмент. Поля usage и qvora позволяют сопоставить результат с расходами.
Потоковые ответы
Установите stream: true, чтобы получать ответ по мере генерации через Server-Sent Events. Для итоговых токенов и стоимости добавьте stream_options.include_usage: true.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["QVORA_API_KEY"],
base_url="https://qvora.ru/api/v1",
)
stream = client.chat.completions.create(
model="gpt-5-mini",
messages=[{"role": "user", "content": "Напиши короткое приветствие."}],
stream=True,
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices:
print(chunk.choices[0].delta.content or "", end="", flush=True)
if chunk.usage:
print("\nТокены:", chunk.usage.total_tokens)| Событие Chat Completions | Действие клиента |
|---|---|
choices[].delta.content | Добавить фрагмент к тексту. |
choices[].delta.tool_calls | Собирать имя и аргументы по index; id и type приходят в первой дельте вызова. |
choices: [], usage, qvora | Сохранить итоговые токены и стоимость, если запрошен include_usage. |
data: [DONE] | Поток завершён. |
Не разбирайте поток по сетевым пакетам: один JSON может прийти несколькими пакетами. SDK делает сборку событий за вас. Ошибка после начала стрима передаётся внутри потока — проверяйте события, даже если HTTP-статус уже 200.
Разрыв соединения останавливает генерацию; списание рассчитывается по фактически учтённому использованию. При обрыве итоговый чанк может не дойти: проверяйте расход в журнале запросов.
Вызов инструментов и структурированный JSON
Модель выбирает функцию и формирует аргументы. Ваш сервер выполняет функцию и возвращает результат в следующем запросе. QVORA не запускает код ваших функций.
Полный пример: статус заказа на Python
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["QVORA_API_KEY"],
base_url="https://qvora.ru/api/v1",
)
import json
messages = [{"role": "user", "content": "Где заказ 1042?"}]
tools = [{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Узнать статус заказа по номеру",
"parameters": {
"type": "object",
"properties": {"order_id": {"type": "string"}},
"required": ["order_id"],
"additionalProperties": False,
},
},
}]
first = client.chat.completions.create(
model="gpt-5-mini", messages=messages, tools=tools,
tool_choice={"type": "function", "function": {"name": "get_order_status"}},
)
assistant = first.choices[0].message
messages.append(assistant.model_dump(exclude_none=True))
for call in assistant.tool_calls or []:
if call.function.name != "get_order_status":
raise ValueError("Неизвестный инструмент")
args = json.loads(call.function.arguments)
# Демонстрационные данные. Здесь вызывается ваша система заказов.
result = {"order_id": args["order_id"], "status": "Передан в доставку"}
messages.append({
"role": "tool", "tool_call_id": call.id,
"content": json.dumps(result, ensure_ascii=False),
})
final = client.chat.completions.create(
model="gpt-5-mini", messages=messages, tools=tools, tool_choice="none",
)
print(final.choices[0].message.content)Сохраняйте tool_calls в сообщении ассистента и передавайте соответствующий tool_call_id в каждом ответе с ролью tool. Проверяйте имя функции, аргументы и права пользователя перед выполнением.
Ответ по JSON Schema
Используйте response_format.type: json_schema и модель с возможностью json_schema. Для JSON без фиксированной схемы есть json_object.
curl --fail-with-body "https://qvora.ru/api/v1/chat/completions" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5-mini",
"messages": [
{
"role": "user",
"content": "Извлеки город: доставка в Москву."
}
],
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "delivery",
"strict": true,
"schema": {
"type": "object",
"properties": {
"city": {
"type": "string"
}
},
"required": [
"city"
],
"additionalProperties": false
}
}
}
}'JSON возвращается строкой в choices[0].message.content. Разберите его через JSON.parse или json.loads, предварительно проверив завершение ответа.
Маскировка персональных данных
Параметр obfuscate скрывает персональные данные до отправки провайдеру и возвращает настоящие значения в ответе — в обычном и потоковом режиме, а также в аргументах tool_calls. Работает одинаково в Chat Completions, Responses и Messages. Бесплатно.
curl --fail-with-body "https://qvora.ru/api/v1/chat/completions" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5-mini",
"obfuscate": true,
"messages": [
{
"role": "user",
"content": "Составь письмо: Иванов Пётр Сергеевич, ИНН 500100732259, тел. +7 916 245-33-18"
}
]
}'Провайдер получит Иванов Пётр Сергеевич как <<PER0>>, ИНН как <<ID1>>, телефон как <<PHONE2>>; вы получите ответ с исходными значениями. Одинаковые значения в запросе получают одну метку, поэтому модель различает людей и связи между ними. При повторной отправке той же истории метки не меняются, поэтому кэш промпта продолжает работать.
| Значение obfuscate | Что видит модель |
|---|---|
true | То же, что "placeholder". |
"placeholder" | Метки <<PER0>>, <<PHONE1>>. Совместимо с другими шлюзами. |
"surrogate" | Правдоподобные подмены для ФИО, почты и телефонов: «Иванову Петру» → «Лаврову Андрею». Модель склоняет имя как обычное, а мы возвращаем настоящее в том же падеже. Остальные типы — метками. |
false | Без маскировки. Если организация включила обязательную маскировку, false её не отключает. |
| Тип | Что находим |
|---|---|
PER | ФИО в любом падеже, в том числе строчными буквами и с инициалами |
ORG | Организации, банки, ведомства (публичные бренды и названия моделей не трогаем) |
LOC | Города, адреса (улица, дом, квартира), индексы |
PHONE | Российские и международные номера |
EMAIL | Почта и @-аккаунты |
CARD | Номера карт (проверка Луна), срок действия, CVV |
ID | Паспорт, ИНН, СНИЛС, ОГРН/ОГРНИП, счета, IBAN, водительское удостоверение, полис ОМС, IP-адреса, API-ключи, JWT, пароли |
MSC | Даты рождения, коды подтверждения |
Числа проверяем по контрольным суммам (ИНН, СНИЛС, карта, IBAN) или по слову-подсказке рядом, чтобы не маскировать номера заказов и прочие случайные числа. Ограничить типы можно параметром obfuscate_types, исключить значения — obfuscate_allow.
Свои шаблоны
{
"obfuscate": true,
"obfuscate_patterns": [
{
"pattern": "ДП-\\d{4}/\\d{4}",
"label": "CONTRACT"
},
{
"pattern": "EMP-(\\d+)",
"label": "EMPLOYEE"
}
]
}До 20 выражений по 500 символов. Если в выражении есть группы, маскируется только их содержимое. Метка: 1–16 символов A–Z, 0–9, _, по умолчанию CUSTOM. Синтаксис JavaScript RegExp; Python-формы (?P<name>…) и (?i) тоже принимаются. Некорректное или слишком медленное выражение — 400 invalid_obfuscate_patterns.
Без изменения тела запроса
Если клиент не даёт добавить поле в тело (Claude Code, Codex, готовые SDK), передайте заголовок x-qvora-obfuscate: placeholder или surrogate. Для Claude Code: ANTHROPIC_CUSTOM_HEADERS="x-qvora-obfuscate: placeholder".
Проверка без модели
/pii/detectскоуп: chatcurl --fail-with-body "https://qvora.ru/api/v1/pii/detect" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "Иванов Пётр, +7 916 245-33-18, договор ДП-2026/0142",
"mode": "placeholder",
"patterns": [
{
"pattern": "ДП-\\d{4}/\\d{4}",
"label": "CONTRACT"
}
]
}'Возвращает masked — текст в том виде, в каком его получит модель, — и список найденного. Бесплатно; значения не журналируются.
Политика организации
В кабинете компании (раздел «Защита данных») владелец или администратор включает маскировку по умолчанию для всех ключей и для чата сотрудников. Режим «Обязательно» нельзя отключить параметром запроса. Изменения политики записываются в журнал аудита.
В ответе qvora.obfuscation и заголовок x-qvora-obfuscation показывают режим и число скрытых значений по типам, без самих значений.
Responses API
/responsesскоуп: chatПротокол для client.responses.create и агентных клиентов. В input передайте строку или массив элементов, в instructions — системную инструкцию.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["QVORA_API_KEY"],
base_url="https://qvora.ru/api/v1",
)
response = client.responses.create(
model="gpt-5-mini",
instructions="Отвечай кратко и по-русски.",
input="Что такое API?",
)
print(response.output_text)Параметры Responses
modelstringinputstring | any[]обязательноinstructionsstringtoolsany[]tool_choiceobjectparallel_tool_callsbooleantextobjectreasoningobjectПоля reasoning
effortstringmax_output_tokensintegertemperaturenumbertop_pnumberstreambooleanstorebooleanпринимается, всегда false
userstringobfuscateboolean | "placeholder" | "surrogate" | "off" | objectМаскировка персональных данных перед отправкой провайдеру и восстановление в ответе (в т.ч. в стриме и в аргументах tool_calls). `true`/`"placeholder"` — метки `<<PER0>>`, `<<PHONE1>>`; `"surrogate"` — правдоподобные подмены для ФИО, почты и телефонов (модель склоняет имя, мы восстанавливаем в том же падеже), остальное — метками. Если организация включила обязательную маскировку, `false` её не выключает. Альтернатива телу — заголовок `x-qvora-obfuscate: placeholder|surrogate|off`.
obfuscate_patternsobject[]Свои регулярные выражения (JS RegExp; `(?P<name>…)` и `(?i)` из Python принимаются). С группами — маскируется содержимое групп.
Поля obfuscate_patterns[]
patternstringобязательноДо 500 символов.
labelstringПо умолчанию: "CUSTOM".
obfuscate_types"PER" | "ORG" | "LOC" | "PHONE" | "EMAIL" | "CARD" | "ID" | "MSC"[]Какие типы маскировать (по умолчанию — все или по политике организации)
obfuscate_allowstring[]Значения, которые не маскировать (названия ваших продуктов, публичные лица)
Инструменты имеют плоскую структуру: {type: "function", name, parameters}. Верните результат как function_call_output с исходным call_id. В стриме используйте типы событий response.created, response.output_text.delta и response.completed.
Anthropic Messages
/messagesскоуп: chatДля Anthropic SDK используйте Base URL https://qvora.ru/api: SDK сам добавляет /v1/messages. Установите пакет командой python -m pip install anthropic.
import os
from anthropic import Anthropic
client = Anthropic(
api_key=os.environ["QVORA_API_KEY"],
base_url="https://qvora.ru/api",
)
message = client.messages.create(
model="claude-sonnet", max_tokens=256,
messages=[{"role": "user", "content": "Привет!"}],
)
for block in message.content:
if block.type == "text":
print(block.text)Параметры Messages
modelstringобязательноmax_tokensintegerобязательноsystemstring | any[]messagesany[]обязательноtoolsany[]tool_choiceobjectthinkingobjectstop_sequencesany[]temperaturenumbertop_pnumberstreambooleanmetadataobjectobfuscateboolean | "placeholder" | "surrogate" | "off" | objectМаскировка персональных данных перед отправкой провайдеру и восстановление в ответе (в т.ч. в стриме и в аргументах tool_calls). `true`/`"placeholder"` — метки `<<PER0>>`, `<<PHONE1>>`; `"surrogate"` — правдоподобные подмены для ФИО, почты и телефонов (модель склоняет имя, мы восстанавливаем в том же падеже), остальное — метками. Если организация включила обязательную маскировку, `false` её не выключает. Альтернатива телу — заголовок `x-qvora-obfuscate: placeholder|surrogate|off`.
obfuscate_patternsobject[]Свои регулярные выражения (JS RegExp; `(?P<name>…)` и `(?i)` из Python принимаются). С группами — маскируется содержимое групп.
Поля obfuscate_patterns[]
patternstringобязательноДо 500 символов.
labelstringПо умолчанию: "CUSTOM".
obfuscate_types"PER" | "ORG" | "LOC" | "PHONE" | "EMAIL" | "CARD" | "ID" | "MSC"[]Какие типы маскировать (по умолчанию — все или по политике организации)
obfuscate_allowstring[]Значения, которые не маскировать (названия ваших продуктов, публичные лица)
Поддерживаются блоки text, image, tool_use, tool_result, системная инструкция и поток событий Anthropic. В usage.input_tokens не входят токены cache_read_input_tokens.
POST /messages/count_tokens возвращает бесплатную приблизительную оценку входа. Для расчёта итоговой стоимости используйте фактический usage после генерации.
Эмбеддинги
/embeddingsскоуп: embeddingsПреобразуйте текст в векторы для поиска, сравнения и RAG. Передайте строку или до 2 048 непустых строк; общий размер входа — до 2 млн символов, дополнительно действует контекст модели.
import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["QVORA_API_KEY"],
base_url="https://qvora.ru/api/v1",
)
response = client.embeddings.create(
model="text-embedding-3-small",
input=["Оплата по счёту", "Как получить закрывающие документы?"],
encoding_format="float",
)
for item in response.data:
print(item.index, len(item.embedding))Результаты находятся в data[].embedding, порядок определяется по index. Поддерживаются encoding_format: float | base64; OpenAI Python SDK умеет декодировать base64 автоматически. dimensions можно задавать для моделей, поддерживающих изменение размерности. Массивы числовых токенов во входе не принимаются.
Оплачиваются только входные токены; минимальное списание — 0,1 ₽ за запрос. Доступные модели имеют qvora.type: embedding в GET /models.
Медиа-задачи
Изображения, видео, музыка и озвучка
Медиа создаются асинхронно: получите ID задачи, затем опрашивайте её состояние или дождитесь вебхука. Изображения генерируются через /media/tasks, а не через OpenAI Images API.
1. Выберите модель и параметры
/media/modelsскоуп: mediacurl --fail-with-body "https://qvora.ru/api/v1/media/models/nano-banana" \
-H "Authorization: Bearer $QVORA_API_KEY"В operations перечислены операции модели. Объект schemas[operation] содержит JSON Schema для params, допустимые роли inputs, обязательность промпта, формат результата и правило цены price. Значения длительности, голоса и разрешения выбирайте из каталога конкретной модели.
2. Создайте задачу
/media/tasksскоуп: mediacurl --fail-with-body "https://qvora.ru/api/v1/media/tasks" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana",
"operation": "generate",
"prompt": "Красный куб на белом фоне, предметная фотография",
"params": {
"aspect": "16:9",
"count": 1
},
"idempotency_key": "image-order-1042",
"wait": 0
}'Ответ 202: задача принята
{
"id": "task_example",
"object": "media.task",
"status": "queued",
"model": "nano-banana",
"served_model": "nano-banana",
"operation": "generate",
"created_at": 1790000000,
"finished_at": null,
"progress": {
"done": 0,
"total": 1
},
"request": {
"model": "nano-banana",
"operation": "generate",
"prompt": "Красный куб на белом фоне, предметная фотография",
"params": {
"aspect": "16:9",
"count": 1
},
"inputs": {}
},
"results": [],
"error": null,
"cost": {
"charged_rub": 13,
"refunded_rub": 0,
"currency": "RUB"
},
"webhook_url": null,
"idempotency_key": "image-order-1042"
}Цена здесь иллюстративная. Проверяйте каталог перед запуском и cost в ответе.
Параметры создания задачи
modelstringобязательноoperation"generate" | "edit" | "animate" | "upscale" | "remove_background"promptstringparamsobjectinputsobjectidempotency_keystringДо 255 символов.
webhook_urlstringwaitnumberМинимум: 0. Максимум: 60.
userstringwait — необязательное ожидание до 60 секунд. Даже если задача завершилась за это время, новый запрос возвращает 202; всегда проверяйте поле status. Повтор с тем же idempotency_key и телом возвращает ту же задачу с 200.
3. Получите результат
curl --fail-with-body "https://qvora.ru/api/v1/media/tasks/task_example" \
-H "Authorization: Bearer $QVORA_API_KEY"Терминальные статусы — succeeded, failed, cancelled. При успехе заберите файлы из results[].url; при ошибке проверьте error и cost.refunded_rub. Для нескольких результатов сверяйте списание и возврат по задаче.
Полный пример создания и опроса на Python
import json
import os
import time
import uuid
from urllib.request import Request, urlopen
base = "https://qvora.ru/api/v1"
headers = {
"Authorization": "Bearer " + os.environ["QVORA_API_KEY"],
"Content-Type": "application/json",
}
body = {
"model": "nano-banana", "operation": "generate",
"prompt": "Красный куб на белом фоне",
"params": {"aspect": "16:9", "count": 1},
"idempotency_key": str(uuid.uuid4()),
}
# Сохраните body с ключом, чтобы безопасно повторить POST при обрыве связи.
request = Request(base + "/media/tasks", data=json.dumps(body).encode(), headers=headers)
with urlopen(request, timeout=90) as response:
task = json.load(response)
print("Задача:", task["id"])
deadline = time.monotonic() + 600
while task["status"] in ("queued", "running"):
if time.monotonic() >= deadline:
raise TimeoutError("Продолжите опрос задачи " + task["id"])
time.sleep(5)
request = Request(base + "/media/tasks/" + task["id"], headers=headers)
with urlopen(request, timeout=30) as response:
task = json.load(response)
if task["status"] != "succeeded":
raise RuntimeError(task.get("error") or task["status"])
for result in task["results"]:
print(result["url"], "действует до", result["expires_at"])Редактирование изображения
Передайте исходник в inputs.image. Все URL в примерах замените на свои публичные HTTPS-адреса.
curl --fail-with-body "https://qvora.ru/api/v1/media/tasks" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana",
"operation": "edit",
"prompt": "Сделай фон белым, сохрани предмет без изменений",
"inputs": {
"image": "https://example.com/product.jpg"
},
"params": {
"aspect": "1:1",
"count": 1
},
"idempotency_key": "edit-order-1042"
}'| Задача | Операция и входы |
|---|---|
| Картинка по тексту | generate + prompt |
| Редактирование картинки | edit + inputs.image |
| Оживление фотографии | animate; роли image / first_frame — по схеме выбранной модели |
| Видео с референсами | Операция и роли reference_images / reference_videos / reference_audio — по каталогу |
| Музыка или озвучка | generate + prompt и параметры модели (голос, язык и другие) |
| Апскейл / удаление фона | upscale / remove_background, если операция есть в operations |
Вебхуки
Добавьте webhook_url при создании медиа-задачи. После завершения QVORA отправит POST на публичный HTTPS-адрес с событием media.task.succeeded, media.task.failed или media.task.cancelled.
Полный пример события media.task.succeeded
{
"id": "evt_example",
"type": "media.task.succeeded",
"created_at": 1790000060,
"data": {
"id": "task_example",
"object": "media.task",
"status": "succeeded",
"model": "nano-banana",
"served_model": "nano-banana",
"operation": "generate",
"created_at": 1790000000,
"finished_at": 1790000060,
"progress": {
"done": 1,
"total": 1
},
"request": {
"model": "nano-banana",
"operation": "generate",
"prompt": "Красный куб на белом фоне, предметная фотография",
"params": {
"aspect": "16:9",
"count": 1
},
"inputs": {}
},
"results": [
{
"type": "image",
"url": "https://files.example.com/result.png",
"preview_url": null,
"thumbnail_url": null,
"expires_at": 1790003660
}
],
"error": null,
"cost": {
"charged_rub": 13,
"refunded_rub": 0,
"currency": "RUB"
},
"webhook_url": "https://example.com/hooks/qvora",
"idempotency_key": "image-order-1042"
}
}| Заголовок | Назначение |
|---|---|
X-Qvora-Event | Тип события |
X-Qvora-Delivery-Id | ID доставки для журнала и диагностики |
X-Qvora-Timestamp | Unix-время подписи в секундах |
X-Qvora-Signature | t=<timestamp>,v1=<HMAC-SHA256 в hex> |
Проверка подписи
Секрет webhook_secret выдаётся при создании ключа через Admin API. Получить новый можно через POST /admin/keys/{id}/webhook-secret: старый секрет сразу перестанет действовать. Подписывается строка timestamp + "." + rawBody.
import { createHmac, timingSafeEqual } from "node:crypto";
// rawBody — исходный Buffer HTTP-запроса, до JSON.parse().
export function verifyWebhook(secret, signature, rawBody) {
const match = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(signature ?? "");
if (!match) return false;
const timestamp = Number(match[1]);
const now = Math.floor(Date.now() / 1000);
if (!Number.isFinite(timestamp) || Math.abs(now - timestamp) > 300) {
return false;
}
const expected = createHmac("sha256", secret)
.update(match[1] + ".")
.update(rawBody)
.digest();
return timingSafeEqual(expected, Buffer.from(match[2], "hex"));
}Проверяйте исходные байты до JSON-разбора. Например, в Express используйте express.raw({type: "application/json"}) на маршруте вебхука до общего express.json(). После успешной проверки разберите тело и надёжно сохраните событие.
Верните 2xx в течение 10 секунд после приёма события. При сбое или другом статусе доставка повторяется через 5 с, 20 с, 1, 3, 10 и 30 минут. Обработка должна выдерживать дубли: сохраняйте уникальную пару data.id + type. Для истёкшей ссылки на результат повторно запросите задачу.
История: GET /media/tasks/{id}/webhooks. Повтор вручную: POST /admin/webhooks/deliveries/{id}/retry со скоупом admin.
Транскрибация аудио
/audio/transcriptionsскоуп: mediaПередайте аудио/видеофайл в multipart-поле file или публичный URL в JSON. Операция синхронная, дедлайн — до 10 минут.
curl --fail-with-body "https://qvora.ru/api/v1/audio/transcriptions" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-F "file=@recording.mp3" \
-F "model=whisper-1" \
-F "language=ru" \
-F "response_format=verbose_json"Модели: whisper-1, whisper-large-v3. Форматы: json — текст и стоимость, verbose_json — также длительность, язык и сегменты, text — обычный текст. Размер файла — до 200 МБ. Стоимость возвращается в заголовке x-qvora-cost-rub; длительность округляется вверх до целой минуты.
Подключение
SDK, IDE и автоматизации
| Клиент / протокол | Base URL | Ключ |
|---|---|---|
| OpenAI SDK · Chat / Responses / Embeddings | https://qvora.ru/api/v1 | QVORA_API_KEY → api_key / apiKey |
| Anthropic SDK · Messages | https://qvora.ru/api | QVORA_API_KEY → api_key |
| Codex CLI · Responses | https://qvora.ru/api/v1 | env_key = QVORA_API_KEY |
| Claude Code · Messages | https://qvora.ru/api | ANTHROPIC_AUTH_TOKEN |
Codex CLI
Задайте QVORA_API_KEY в окружении и добавьте настройки в пользовательский ~/.codex/config.toml. Если эти параметры уже есть, обновите их значения.
# ~/.codex/config.toml
model = "gpt-5-mini"
model_provider = "qvora"
web_search = "disabled"
[model_providers.qvora]
name = "QVORA"
base_url = "https://qvora.ru/api/v1"
env_key = "QVORA_API_KEY"
wire_api = "responses"Встроенный веб-поиск через QVORA недоступен. Справочник конфигурации Codex ↗
Claude Code
export ANTHROPIC_BASE_URL="https://qvora.ru/api"
export ANTHROPIC_AUTH_TOKEN="$QVORA_API_KEY"
export ANTHROPIC_MODEL="claude-sonnet"
claudeCursor, Continue и Cline
В настройках клиента выберите подключение к OpenAI-совместимому API: Base URL https://qvora.ru/api/v1, ключ QVORA и ID модели из каталога. Если клиент запрашивает полный URL метода, используйте https://qvora.ru/api/v1/chat/completions. Доступность переопределения URL и отдельных функций зависит от версии и тарифа клиента; серверные функции OpenAI и Anthropic автоматически не появляются.
n8n и Make через HTTP-запрос
Настройте HTTP Request / Make a request: метод POST, URL https://qvora.ru/api/v1/chat/completions, JSON-тело из быстрого старта. В заголовках — Authorization: Bearer … и Content-Type: application/json. Храните ключ в credentials / секретах платформы.
Извлекайте текст по пути choices[0].message.content. Для медиа сохраните id из POST /media/tasks, затем используйте ожидание с опросом или входящий вебхук. При повторах одной операции сохраняйте её ключ идемпотентности.
Пакеты и базовые вызовы SDK: документация OpenAI ↗. Поддерживаемые возможности QVORA перечислены на этой странице.
Стоимость, баланс и кэш
/balanceДеньги во внешнем API выражены в рублях. Текст тарифицируется по фактическим токенам; перед запросом резервируется сумма, а после завершения разница возвращается. Цена зависит от прайс-бука вашего контракта.
curl --fail-with-body "https://qvora.ru/api/v1/balance" \
-H "Authorization: Bearer $QVORA_API_KEY"| Поле | Значение |
|---|---|
balance_rub | Баланс после вычета открытых резервов |
credit_limit_rub | Кредитный лимит организации |
available_rub | Доступно для новых запросов: balance_rub + credit_limit_rub |
reserved_rub | Средства в открытых резервах; повторно вычитать из available_rub не нужно |
key.monthly_limit_rub / spent_month_rub | Месячный лимит ключа и учтённый расход |
Стоимость одного запроса
qvora.cost_rub — списанная сумма, qvora.served_model — публичный ID модели, qvora.request_ref — ID для сопоставления с журналом. В потоковом Chat Completions блок приходит вместе с итоговым usage, если включён include_usage.
Ставки текста находятся в GET /models → data[].qvora.price_rub_per_1k: input, cached_input, cache_write, output. Кэш провайдера применяется при наличии совпадающего входа; попадание в кэш не гарантируется. Учтённые токены видны в usage, экономия — в qvora.cache_saved_rub.
Для медиа проверяйте правило schemas[operation].price до запуска, а после — cost.charged_rub и cost.refunded_rub. У некоторых операций цена зависит от параметров или длительности входного файла. При 402 insufficient_balance ответ содержит требуемую и доступную суммы.
Лимиты, идемпотентность и повторы
| Ограничение | Как обрабатывать |
|---|---|
| RPM / TPM | Ограничить частоту запросов / токенов. После 429 использовать экспоненциальную задержку со случайным разбросом. |
| Параллельные запросы | Уменьшить число одновременно выполняемых операций и дождаться завершения текущих. |
| Дневной / месячный бюджет | Увеличить лимит в кабинете или дождаться следующего периода. Сутки и месяц считаются по Москве (UTC+3). |
| Контекст Chat Completions | До 500 сообщений, 1,5 млн символов, 8 изображений и 512 инструментов; дополнительно — контекст модели. |
| Время ожидания | Стрим: до 90 секунд простоя и 15 минут всего. Синхронные операции: до 10 минут; конкретный метод может иметь меньший таймаут. |
Защита от повторного списания
| Операция | Ключ идемпотентности | Поведение |
|---|---|---|
| Chat Completions без стрима | Idempotency-Key: order-1042 | Ответ сохраняется на 24 часа; повтор возвращает сохранённый результат. |
| Медиа-задача | idempotency_key в JSON-теле | Повтор возвращает ту же задачу; не переносите правило 24 часов с текстового API на медиа. |
Выдавайте новый ключ каждой новой операции и сохраняйте его при повторе после сетевого сбоя. Подтверждение повтора — Idempotent-Replayed: true. То же значение с другим телом: 409 idempotency_key_reused; ещё выполняющийся текстовый запрос: 409 idempotency_in_flight.
curl --fail-with-body "https://qvora.ru/api/v1/chat/completions" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Idempotency-Key: order-1042" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5-mini",
"messages": [
{
"role": "user",
"content": "Ответь одним словом: привет!"
}
],
"max_completion_tokens": 1024
}'Расходы и управление организацией
/usageскоуп: usage или adminСводка включает API-расходы организации. group_by: day, model, key, group, member, api, end_user. Фильтры: key_id, model, api, end_user.
curl --fail-with-body "https://qvora.ru/api/v1/usage?from=2026-09-01&to=2026-09-30&group_by=day" \
-H "Authorization: Bearer $QVORA_API_KEY"Даты from и to задаются в формате YYYY-MM-DD по Москве; to включительно. Используйте диапазон с to позже from, не более 400 дней. По умолчанию API берёт последние примерно 30 дней.
/usage/requestsскоуп: usage или admincurl --fail-with-body "https://qvora.ru/api/v1/usage/requests?limit=100&api=chat" \
-H "Authorization: Bearer $QVORA_API_KEY"Ответ: data[] и has_more. Для следующей страницы передайте before — Unix-время в секундах из created_at последней строки. limit — от 1 до 1 000, по умолчанию 100.
Создание ключа с лимитами
Нужен скоуп admin. Новый ключ не может получить скоупы шире ключа, который его создаёт: для примера ниже у ключа администратора должны быть admin, chat и usage.
curl --fail-with-body "https://qvora.ru/api/v1/admin/keys" \
-H "Authorization: Bearer $QVORA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "Интеграция CRM",
"scopes": [
"chat",
"usage"
],
"monthly_limit_rub": 5000,
"daily_limit_rub": 500,
"rpm": 60,
"concurrency": 5
}'В ответе 201 сохраните key и webhook_secret: повторно они не показываются. Настройки меняются через PATCH /admin/keys/{id}, ротация — POST /admin/keys/{id}/rotate, отзыв — DELETE /admin/keys/{id}.
Группы, сотрудники, аудит и журнал вебхуков описаны в справочнике методов. Admin API не меняет владельца организации, прайс-бук или кредитный лимит.
Ошибки и диагностика
Проверяйте HTTP-статус и машиночитаемый error.code. Для поддержки сохраните trace_id из тела и заголовок x-request-id.
{
"error": {
"message": "Неверный или отозванный API-ключ",
"type": "authentication_error",
"code": "invalid_api_key",
"param": null,
"trace_id": "req_example"
}
}| HTTP | Коды | Что делать |
|---|---|---|
| 400 | invalid_value, missing_parameter, unsupported_parameter, unsupported_operation, context_length_exceeded, too_many_*, invalid_input_file, forbidden_address, invalid_obfuscate_patterns | Исправить поле из param, сократить вход или выбрать поддерживаемую возможность. |
| 401 | invalid_api_key | Проверить значение ключа, срок действия, enabled и отзыв. |
| 402 | insufficient_balance | Проверить required_amount_rub и available_amount_rub в error, пополнить баланс. |
| 403 | insufficient_scope, ip_not_allowed, member_disabled, organization_deactivated, scope_escalation | Проверить скоупы, IP и настройки организации / сотрудника. |
| 404 | model_not_found, task_not_found, key_not_found | Проверить ID, доступ ключа и принадлежность объекта организации. |
| 409 | idempotency_key_reused, idempotency_in_flight, task_not_cancellable, request_expired, key_revoked | При in_flight — подождать; при reused — сверить тело; при остальных — проверить состояние операции. |
| 413 | file_too_large | Уменьшить входной файл. |
| 429 | rate_limit_exceeded, tpm_limit_exceeded, concurrency_limit_exceeded | Снизить нагрузку, повторить с задержкой. |
| 429 | daily_limit_exceeded, monthly_limit_exceeded, group_limit_exceeded, member_limit_exceeded | Изменить бюджет или дождаться нового периода. |
| 503 | model_unavailable, obfuscation_unavailable | Повторить позже или выбрать другую модель. При obfuscation_unavailable запрос не отправлен модели. |
| 504 | deadline_exceeded | Проверить состояние / расход операции перед повтором, уменьшить объём работы. |
| 500 | internal_error | Сохранить trace_id и обратиться в поддержку. |
У Messages формат Anthropic: {type: "error", error: {type, message, code}, request_id}. У медиа-задачи, принятой с 202, ошибка генерации приходит позже в поле error объекта задачи или в вебхуке.
Полный контракт
Справочник методов API
Методов в справочнике: 35. Для каждого приведены параметры и схемы ответов. Пути указаны относительно https://qvora.ru/api/v1. Для каждого метода нужен ключ организации; дополнительные права указаны рядом с путём.
OpenAPI 3.1 · версия описания 2.0.0. Открыть JSON-схему ↗
Chat Completions
POST/chat/completionsChat Completions (stream и non-stream, tools, vision, json_schema, reasoning_effort)
Авторизация: Bearer или x-api-key. Скоуп: chat. Ссылка на метод
Совместимо с openai-SDK. Поддержаны: messages (system/developer/user/assistant/tool), tools/tool_choice/parallel_tool_calls, response_format text|json_object|json_schema, temperature/top_p/max_tokens|max_completion_tokens/stop/seed/presence_penalty/frequency_penalty, reasoning_effort, stream + stream_options.include_usage, `user`. Неподдержанный параметр → 400 unsupported_parameter с `param`. Заголовок `Idempotency-Key` (только non-stream) даёт повтор без второго списания в течение 24 ч.
Тело запроса · application/json
modelstringid из /models или псевдоним (gpt-5.5, claude-sonnet-5, …)
messagesobject[]обязательноПоля messages[]
role"system" | "developer" | "user" | "assistant" | "tool"contentstring | any[] | nulltool_callsany[]tool_call_idstringnamestringtoolsobject[]Поля tools[]
type"function"functionobjectПоля function
namestringdescriptionstringparametersobjectstrictbooleantool_choice"auto" | "none" | "required" | objectparallel_tool_callsbooleanresponse_formatobjectПоля response_format
type"text" | "json_object" | "json_schema"json_schemaobjecttemperaturenumberМинимум: 0. Максимум: 2.
top_pnumbermax_tokensintegermax_completion_tokensintegerstopstring | any[]seedintegerpresence_penaltynumberfrequency_penaltynumberreasoning_effort"low" | "medium" | "high"streambooleanstream_optionsobjectПоля stream_options
include_usagebooleanuserstringИдентификатор конечного пользователя — попадает в /usage (end_user)
obfuscateboolean | "placeholder" | "surrogate" | "off" | objectМаскировка персональных данных перед отправкой провайдеру и восстановление в ответе (в т.ч. в стриме и в аргументах tool_calls). `true`/`"placeholder"` — метки `<<PER0>>`, `<<PHONE1>>`; `"surrogate"` — правдоподобные подмены для ФИО, почты и телефонов (модель склоняет имя, мы восстанавливаем в том же падеже), остальное — метками. Если организация включила обязательную маскировку, `false` её не выключает. Альтернатива телу — заголовок `x-qvora-obfuscate: placeholder|surrogate|off`.
obfuscate_patternsobject[]Свои регулярные выражения (JS RegExp; `(?P<name>…)` и `(?i)` из Python принимаются). С группами — маскируется содержимое групп.
Поля obfuscate_patterns[]
patternstringобязательноДо 500 символов.
labelstringПо умолчанию: "CUSTOM".
obfuscate_types"PER" | "ORG" | "LOC" | "PHONE" | "EMAIL" | "CARD" | "ID" | "MSC"[]Какие типы маскировать (по умолчанию — все или по политике организации)
obfuscate_allowstring[]Значения, которые не маскировать (названия ваших продуктов, публичные лица)
Успешный ответ
200chat.completion либо SSE `chat.completion.chunk` (при stream=true)
application/json
idstringobject"chat.completion"modelstringchoicesany[]usageobjectПоля usage
prompt_tokensintegercompletion_tokensintegertotal_tokensintegerprompt_tokens_detailsobjectПоля prompt_tokens_details
cached_tokensintegercompletion_tokens_detailsobjectПоля completion_tokens_details
reasoning_tokensintegerqvoraobjectНаши поля сверх спеки: за что списано
Поля qvora
served_modelstringcost_rubnumbercache_saved_rubnumberrequest_refstringid записи расхода для /usage/requests
obfuscationobjectМаскировка была: режим и число уникальных значений по типам (самих значений здесь нет)
Поля obfuscation
mode"placeholder" | "surrogate"entitiesobjectreplacedintegertext/event-stream
string
Ошибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
Responses
POST/responsesResponses API (input items, function tools, SSE-события)
Авторизация: Bearer или x-api-key. Скоуп: chat. Ссылка на метод
Совместимо с Codex CLI и openai-SDK `responses.create`. previous_response_id/background/conversation не поддержаны (400). Хостовые инструменты (web_search и т.п.) игнорируются с заголовком `x-qvora-dropped-tools`. reasoning-items входа с encrypted_content выбрасываются.
Тело запроса · application/json
modelstringinputstring | any[]обязательноinstructionsstringtoolsany[]tool_choiceobjectparallel_tool_callsbooleantextobjectreasoningobjectПоля reasoning
effortstringmax_output_tokensintegertemperaturenumbertop_pnumberstreambooleanstorebooleanпринимается, всегда false
userstringobfuscateboolean | "placeholder" | "surrogate" | "off" | objectМаскировка персональных данных перед отправкой провайдеру и восстановление в ответе (в т.ч. в стриме и в аргументах tool_calls). `true`/`"placeholder"` — метки `<<PER0>>`, `<<PHONE1>>`; `"surrogate"` — правдоподобные подмены для ФИО, почты и телефонов (модель склоняет имя, мы восстанавливаем в том же падеже), остальное — метками. Если организация включила обязательную маскировку, `false` её не выключает. Альтернатива телу — заголовок `x-qvora-obfuscate: placeholder|surrogate|off`.
obfuscate_patternsobject[]Свои регулярные выражения (JS RegExp; `(?P<name>…)` и `(?i)` из Python принимаются). С группами — маскируется содержимое групп.
Поля obfuscate_patterns[]
patternstringобязательноДо 500 символов.
labelstringПо умолчанию: "CUSTOM".
obfuscate_types"PER" | "ORG" | "LOC" | "PHONE" | "EMAIL" | "CARD" | "ID" | "MSC"[]Какие типы маскировать (по умолчанию — все или по политике организации)
obfuscate_allowstring[]Значения, которые не маскировать (названия ваших продуктов, публичные лица)
Успешный ответ
200Объект response либо SSE-события response.created → … → response.completed
application/json
idstringobject"response"status"completed" | "incomplete" | "failed" | "in_progress"outputany[]usageobjectqvoraobjectНаши поля сверх спеки: за что списано
Поля qvora
served_modelstringcost_rubnumbercache_saved_rubnumberrequest_refstringid записи расхода для /usage/requests
obfuscationobjectМаскировка была: режим и число уникальных значений по типам (самих значений здесь нет)
Поля obfuscation
mode"placeholder" | "surrogate"entitiesobjectreplacedintegertext/event-stream
string
Ошибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
Messages
POST/messagesAnthropic Messages API (system/image/tool_use/tool_result, SSE Anthropic)
Авторизация: Bearer или x-api-key. Скоуп: chat. Ссылка на метод
Совместимо с anthropic-SDK и Claude Code. Модели Claude обслуживаются нативно (заголовок ответа `x-qvora-mode: native`): тело запроса и SSE-события Anthropic проходят без конвертации — thinking-блоки с `signature` возвращаются и принимаются обратно, `cache_control` работает на любых блоках (в т.ч. tool_result, image, tools) и на верхнем уровне, `context_management`, `output_config`, `tool_choice` исполняются как у Anthropic. `usage` — полностью: input_tokens, cache_creation_input_tokens, cache_read_input_tokens, cache_creation.ephemeral_5m_input_tokens / ephemeral_1h_input_tokens, output_tokens; цена — по четырём категориям входа (см. /models price_rub_per_1k). Серверные инструменты Anthropic (web_search_*, bash_*, code_execution_*, computer_*, mcp_toolset) не исполняются и пропускаются с `x-qvora-dropped-tools`; поля и беты, меняющие цену или модель (speed, fallbacks, inference_geo, service_tier, fast-mode, server-side-fallback), не исполняются — `x-qvora-ignored-params`. Не-Claude модели, маскировка ПДн и заголовок `x-qvora-anthropic-mode: compat` — режим совместимости (`x-qvora-mode: compat`): thinking-блоки там не возвращаются. Ошибки — в конверте Anthropic `{type:"error", error:{type,message}}`.
Тело запроса · application/json
modelstringобязательноmax_tokensintegerобязательноsystemstring | any[]messagesany[]обязательноtoolsany[]tool_choiceobjectthinkingobjectstop_sequencesany[]temperaturenumbertop_pnumberstreambooleanmetadataobjectobfuscateboolean | "placeholder" | "surrogate" | "off" | objectМаскировка персональных данных перед отправкой провайдеру и восстановление в ответе (в т.ч. в стриме и в аргументах tool_calls). `true`/`"placeholder"` — метки `<<PER0>>`, `<<PHONE1>>`; `"surrogate"` — правдоподобные подмены для ФИО, почты и телефонов (модель склоняет имя, мы восстанавливаем в том же падеже), остальное — метками. Если организация включила обязательную маскировку, `false` её не выключает. Альтернатива телу — заголовок `x-qvora-obfuscate: placeholder|surrogate|off`.
obfuscate_patternsobject[]Свои регулярные выражения (JS RegExp; `(?P<name>…)` и `(?i)` из Python принимаются). С группами — маскируется содержимое групп.
Поля obfuscate_patterns[]
patternstringобязательноДо 500 символов.
labelstringПо умолчанию: "CUSTOM".
obfuscate_types"PER" | "ORG" | "LOC" | "PHONE" | "EMAIL" | "CARD" | "ID" | "MSC"[]Какие типы маскировать (по умолчанию — все или по политике организации)
obfuscate_allowstring[]Значения, которые не маскировать (названия ваших продуктов, публичные лица)
Успешный ответ
200message либо SSE message_start → content_block_* → message_delta → message_stop
application/json
idstringtype"message"role"assistant"modelstringcontentany[]stop_reason"end_turn" | "max_tokens" | "stop_sequence" | "tool_use" | "refusal"usageobjectПоля usage
input_tokensintegeroutput_tokensintegercache_read_input_tokensintegercache_creation_input_tokensintegercache_creationobjectПоля cache_creation
ephemeral_5m_input_tokensintegerephemeral_1h_input_tokensintegertext/event-stream
string
Ошибки: 400, 401, 402, 429. Коды и действия при ошибке →
POST/messages/count_tokensЧисло входных токенов (бесплатно; для Claude — точный счёт модели, иначе оценка)
Авторизация: Bearer или x-api-key. Скоуп: chat. Ссылка на метод
Тело запроса · application/json
modelstringобязательноmax_tokensintegerобязательноsystemstring | any[]messagesany[]обязательноtoolsany[]tool_choiceobjectthinkingobjectstop_sequencesany[]temperaturenumbertop_pnumberstreambooleanmetadataobjectobfuscateboolean | "placeholder" | "surrogate" | "off" | objectМаскировка персональных данных перед отправкой провайдеру и восстановление в ответе (в т.ч. в стриме и в аргументах tool_calls). `true`/`"placeholder"` — метки `<<PER0>>`, `<<PHONE1>>`; `"surrogate"` — правдоподобные подмены для ФИО, почты и телефонов (модель склоняет имя, мы восстанавливаем в том же падеже), остальное — метками. Если организация включила обязательную маскировку, `false` её не выключает. Альтернатива телу — заголовок `x-qvora-obfuscate: placeholder|surrogate|off`.
obfuscate_patternsobject[]Свои регулярные выражения (JS RegExp; `(?P<name>…)` и `(?i)` из Python принимаются). С группами — маскируется содержимое групп.
Поля obfuscate_patterns[]
patternstringобязательноДо 500 символов.
labelstringПо умолчанию: "CUSTOM".
obfuscate_types"PER" | "ORG" | "LOC" | "PHONE" | "EMAIL" | "CARD" | "ID" | "MSC"[]Какие типы маскировать (по умолчанию — все или по политике организации)
obfuscate_allowstring[]Значения, которые не маскировать (названия ваших продуктов, публичные лица)
Успешный ответ
200OK
application/json
input_tokensintegerОшибки: зависят от запроса. Коды и действия при ошибке →
Эмбеддинги
POST/embeddingsЭмбеддинги (batch input, dimensions)
Авторизация: Bearer или x-api-key. Скоуп: embeddings. Ссылка на метод
Тело запроса · application/json
modelstringПо умолчанию: "text-embedding-3-small".
inputstring | string[]обязательноdimensionsintegerencoding_format"float" | "base64"base64: float32 little-endian; OpenAI Python SDK декодирует автоматически
По умолчанию: "float".
userstringУспешный ответ
200OK
application/json
object"list"dataobject[]Поля data[]
object"embedding"indexintegerembeddingnumber[] | stringmodelstringusageobjectqvoraobjectНаши поля сверх спеки: за что списано
Поля qvora
served_modelstringcost_rubnumbercache_saved_rubnumberrequest_refstringid записи расхода для /usage/requests
obfuscationobjectМаскировка была: режим и число уникальных значений по типам (самих значений здесь нет)
Поля obfuscation
mode"placeholder" | "surrogate"entitiesobjectreplacedintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
Каталог моделей
GET/modelsТекстовые и embedding-модели, доступные ключу, с ценами ₽/1k токенов, capabilities и псевдонимами
Авторизация: Bearer или x-api-key. Дополнительный скоуп не требуется. Ссылка на метод
Тело запроса не требуется.
Успешный ответ
200OK
application/json
object"list"dataobject[]Поля data[]
idstringobject"model"owned_by"qvora"qvoraobjectПоля qvora
titlestringtype"text" | "embedding"aliasesstring[]context_tokensinteger | nullmax_output_tokensinteger | nullcapabilitiesobjectПоля capabilities
visionbooleanreasoningbooleantoolsbooleanjson_modebooleanjson_schemabooleanstreamingbooleanprotocolsstring[]price_rub_per_1kobjectcached_input = cache_read (чтение из кэша), cache_write = cache_write_5m
Поля price_rub_per_1k
inputnumbercached_inputnumbercache_readnumbercache_writenumbercache_write_5mnumbercache_write_1hnumberoutputnumberdeprecatedbooleanqvoraobjectПоля qvora
price_bookstringОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/models/{id}Одна модель (принимает псевдонимы)
Авторизация: Bearer или x-api-key. Дополнительный скоуп не требуется. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноid или псевдоним модели
Тело запроса не требуется.
Успешный ответ
200OK
application/json
idstringobject"model"owned_by"qvora"qvoraobjectПоля qvora
titlestringtype"text" | "embedding"aliasesstring[]context_tokensinteger | nullmax_output_tokensinteger | nullcapabilitiesobjectПоля capabilities
visionbooleanreasoningbooleantoolsbooleanjson_modebooleanjson_schemabooleanstreamingbooleanprotocolsstring[]price_rub_per_1kobjectcached_input = cache_read (чтение из кэша), cache_write = cache_write_5m
Поля price_rub_per_1k
inputnumbercached_inputnumbercache_readnumbercache_writenumbercache_write_5mnumbercache_write_1hnumberoutputnumberdeprecatedbooleanОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
Медиа-задачи
GET/media/modelsКаталог медиа-моделей со схемами параметров, входов и правилами цены (строится из каталога продукта)
Авторизация: Bearer или x-api-key. Скоуп: media. Ссылка на метод
Тело запроса не требуется.
Успешный ответ
200OK
application/json
object"list"dataobject[]Поля data[]
idstringobject"model"type"image" | "video" | "music" | "speech"titlestringprovider_familystringoperations"generate" | "edit" | "animate" | "upscale" | "remove_background"[]schemasobjectdeprecatedbooleanqvoraobjectПоля qvora
price_bookstringresult_url_ttl_secintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/media/models/{id}Одна медиа-модель
Авторизация: Bearer или x-api-key. Скоуп: media. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноid модели
Тело запроса не требуется.
Успешный ответ
200OK
application/json
idstringobject"model"type"image" | "video" | "music" | "speech"titlestringprovider_familystringoperations"generate" | "edit" | "animate" | "upscale" | "remove_background"[]schemasobjectdeprecatedbooleanОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
POST/media/tasksСоздать медиа-задачу (асинхронно, 202)
Авторизация: Bearer или x-api-key. Скоуп: media. Ссылка на метод
model + operation (generate|edit|animate|upscale|remove_background; по умолчанию выводится из inputs) + prompt + params по схеме модели + inputs с ролями (image, first_frame, last_frame, video, reference_images, reference_videos, reference_audio, source_task). Входы — https-URL публичного адреса или data:-URI (≤200 МБ). idempotency_key: повтор возвращает ту же задачу (200 + Idempotent-Replayed), другое тело — 409. webhook_url: https, события media.task.succeeded|failed|cancelled с подписью X-Qvora-Signature. wait (0–60 с): дождаться результата, не теряя асинхронности.
Тело запроса · application/json
modelstringобязательноoperation"generate" | "edit" | "animate" | "upscale" | "remove_background"promptstringparamsobjectinputsobjectidempotency_keystringДо 255 символов.
webhook_urlstringwaitnumberМинимум: 0. Максимум: 60.
userstringУспешный ответ
200Повтор по idempotency_key
application/json
idstringobject"media.task"status"queued" | "running" | "succeeded" | "failed" | "cancelled"modelstringserved_modelstringoperationstringcreated_atintegerfinished_atinteger | nullprogressobjectПоля progress
doneintegertotalintegerrequestobjectresultsobject[]Поля results[]
typestringurlstringpreview_urlstring | nullthumbnail_urlstring | nullexpires_atintegererrorobject | nullПоля error
codestringmessagestringcostobjectПоля cost
charged_rubnumberrefunded_rubnumbercurrency"RUB"webhook_urlstring | nullidempotency_keystring | null202Задача принята
application/json
idstringobject"media.task"status"queued" | "running" | "succeeded" | "failed" | "cancelled"modelstringserved_modelstringoperationstringcreated_atintegerfinished_atinteger | nullprogressobjectПоля progress
doneintegertotalintegerrequestobjectresultsobject[]Поля results[]
typestringurlstringpreview_urlstring | nullthumbnail_urlstring | nullexpires_atintegererrorobject | nullПоля error
codestringmessagestringcostobjectПоля cost
charged_rubnumberrefunded_rubnumbercurrency"RUB"webhook_urlstring | nullidempotency_keystring | nullОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/media/tasksСписок задач организации
Авторизация: Bearer или x-api-key. Скоуп: media. Ссылка на метод
Параметры пути и строки запроса
limitquery · integer1..100
afterquery · stringid задачи-курсора
Тело запроса не требуется.
Успешный ответ
200OK
application/json
object"list"dataobject[]Поля data[]
idstringobject"media.task"status"queued" | "running" | "succeeded" | "failed" | "cancelled"modelstringserved_modelstringoperationstringcreated_atintegerfinished_atinteger | nullprogressobjectПоля progress
doneintegertotalintegerrequestobjectresultsobject[]Поля results[]
typestringurlstringpreview_urlstring | nullthumbnail_urlstring | nullexpires_atintegererrorobject | nullПоля error
codestringmessagestringcostobjectПоля cost
charged_rubnumberrefunded_rubnumbercurrency"RUB"webhook_urlstring | nullidempotency_keystring | nullhas_morebooleanОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/media/tasks/{id}Статус и результаты задачи (URL результатов подписаны, действуют 1 ч — expires_at)
Авторизация: Bearer или x-api-key. Скоуп: media. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноtask_…
Тело запроса не требуется.
Успешный ответ
200OK
application/json
idstringobject"media.task"status"queued" | "running" | "succeeded" | "failed" | "cancelled"modelstringserved_modelstringoperationstringcreated_atintegerfinished_atinteger | nullprogressobjectПоля progress
doneintegertotalintegerrequestobjectresultsobject[]Поля results[]
typestringurlstringpreview_urlstring | nullthumbnail_urlstring | nullexpires_atintegererrorobject | nullПоля error
codestringmessagestringcostobjectПоля cost
charged_rubnumberrefunded_rubnumbercurrency"RUB"webhook_urlstring | nullidempotency_keystring | nullОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
POST/media/tasks/{id}/cancelОтменить задачу, пока она в очереди (деньги возвращаются); взятую в работу отменить нельзя — 409
Авторизация: Bearer или x-api-key. Скоуп: media. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноtask_…
Тело запроса не требуется.
Успешный ответ
200OK
application/json
idstringobject"media.task"status"queued" | "running" | "succeeded" | "failed" | "cancelled"modelstringserved_modelstringoperationstringcreated_atintegerfinished_atinteger | nullprogressobjectПоля progress
doneintegertotalintegerrequestobjectresultsobject[]Поля results[]
typestringurlstringpreview_urlstring | nullthumbnail_urlstring | nullexpires_atintegererrorobject | nullПоля error
codestringmessagestringcostobjectПоля cost
charged_rubnumberrefunded_rubnumbercurrency"RUB"webhook_urlstring | nullidempotency_keystring | nullОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/media/tasks/{id}/webhooksЖурнал доставок вебхуков задачи
Авторизация: Bearer или x-api-key. Скоуп: media. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноtask_…
Тело запроса не требуется.
Успешный ответ
200OK
application/json
object"list"dataobject[]Поля data[]
idstringobject"webhook.delivery"eventstringstatus"pending" | "delivered" | "failed"attemptsintegerlast_statusinteger | nulllast_errorstring | nullnext_attempt_atinteger | nulldelivered_atinteger | nullcreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
Транскрибация
POST/audio/transcriptionsТранскрибация (OpenAI multipart `file` или JSON {url}); синхронно, дедлайн до 10 минут
Авторизация: Bearer или x-api-key. Скоуп: media. Ссылка на метод
model: whisper-1 | whisper-large-v3; response_format: json | verbose_json | text; language. Цена — за минуту аудио, списание по факту длительности. Заголовок ответа x-qvora-cost-rub.
Тело запроса · multipart/form-data
model"whisper-1" | "whisper-large-v3"По умолчанию: "whisper-1".
response_format"json" | "verbose_json" | "text"По умолчанию: "json".
languagestringКод языка, например ru или en
filestringобязательноАудио/видеофайл, не более 200 МБ
Тело запроса · application/json
model"whisper-1" | "whisper-large-v3"По умолчанию: "whisper-1".
response_format"json" | "verbose_json" | "text"По умолчанию: "json".
languagestringКод языка, например ru или en
urlstringобязательноПубличный HTTPS URL или data: URI аудио/видеофайла
Успешный ответ
200JSON или обычный текст при response_format=text; стоимость в x-qvora-cost-rub
application/json
textstringlanguagestringdurationnumbersegmentsany[]qvoraobjectНаши поля сверх спеки: за что списано
Поля qvora
served_modelstringcost_rubnumbercache_saved_rubnumberrequest_refstringid записи расхода для /usage/requests
obfuscationobjectМаскировка была: режим и число уникальных значений по типам (самих значений здесь нет)
Поля obfuscation
mode"placeholder" | "surrogate"entitiesobjectreplacedintegertext/plain
string
Ошибки: 400, 401, 402, 403, 404, 409, 429, 503, 504. Коды и действия при ошибке →
Баланс и расходы
GET/balanceБаланс организации, кредитный лимит, открытые резервы, лимит ключа
Авторизация: Bearer или x-api-key. Дополнительный скоуп не требуется. Ссылка на метод
Тело запроса не требуется.
Успешный ответ
200OK
application/json
object"balance"balance_rubnumbercredit_limit_rubnumberavailable_rubnumberreserved_rubnumberОткрытые резервы запросов в полёте
keyobjectПоля key
monthly_limit_rubnumberspent_month_rubnumbermonthstring | nullscopesstring[]Ошибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/usageСводка расходов по срезам (день, модель, ключ, группа, сотрудник, протокол, end_user)
Авторизация: Bearer или x-api-key. Скоуп: usage | admin. Ссылка на метод
Параметры пути и строки запроса
fromquery · stringYYYY-MM-DD (МСК)
toquery · stringYYYY-MM-DD включительно
group_byquery · "day" | "model" | "key" | "group" | "member" | "api" | "end_user"day|model|key|group|member|api|end_user
key_idquery · stringфильтр
modelquery · stringфильтр
apiquery · stringchat|responses|messages|embeddings|audio|media
end_userquery · stringзначение поля user запроса
Тело запроса не требуется.
Успешный ответ
200OK
application/json
object"usage.summary"fromstringtostringgroup_bystringcurrency"RUB"totalobjectdataobject[]Поля data[]
cost_rubnumberrequestsintegerfailedintegertokensobjectОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/usage/requestsДетализация по запросам (токены, стоимость, ключ, сотрудник, end_user)
Авторизация: Bearer или x-api-key. Скоуп: usage | admin. Ссылка на метод
Параметры пути и строки запроса
fromquery · stringtoquery · stringlimitquery · integer1..1000
beforequery · stringunix-время курсора
key_idquery · stringmodelquery · stringapiquery · stringend_userquery · stringТело запроса не требуется.
Успешный ответ
200OK
application/json
object"list"has_morebooleandataobject[]Поля data[]
idstringobjectstringcreated_atintegerapistringmodelstringstatusstringkey_idstringgroup_idstring | nullmember_user_idstring | nullend_userstring | nulltokensobject | nullcost_rubnumberОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
Управление организацией
GET/admin/keysСписок ключей
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
include_revokedquery · stringtrue — включая отозванные
Тело запроса не требуется.
Успешный ответ
200OK
application/json
object"list"dataobject[]Поля data[]
idstringobject"api_key"namestringprefixstringscopesstring[]enabledbooleanrevoked_atinteger | nullexpires_atinteger | nulllimitsobjectПоля limits
monthly_limit_rubnumberspent_month_rubnumberdaily_limit_rubnumberspent_day_rubnumberrpmintegertpmintegerconcurrencyintegerip_allowliststring[]allowed_modelsstring[]group_idstring | nullmember_user_idstring | nullwebhook_secret_setbooleancalls_monthintegerlast_used_atinteger | nullcreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
POST/admin/keysСоздать ключ (полный ключ и webhook_secret возвращаются один раз)
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Скоупы нового ключа не могут быть шире скоупов ключа-актора (403 scope_escalation).
Тело запроса · application/json
namestringscopes"chat" | "embeddings" | "media" | "admin" | "usage"[]monthly_limit_rubnumber | nulldaily_limit_rubnumber | nullrpminteger | nulltpminteger | nullconcurrencyinteger | nullip_allowlistarray | string | nullallowed_modelsarray | nullexpires_atstring | nullgroup_idstring | nullmember_user_idstring | nullenabledbooleanУспешный ответ
201OK
application/json
idstringobject"api_key"namestringprefixstringscopesstring[]enabledbooleanrevoked_atinteger | nullexpires_atinteger | nulllimitsobjectПоля limits
monthly_limit_rubnumberspent_month_rubnumberdaily_limit_rubnumberspent_day_rubnumberrpmintegertpmintegerconcurrencyintegerip_allowliststring[]allowed_modelsstring[]group_idstring | nullmember_user_idstring | nullwebhook_secret_setbooleancalls_monthintegerlast_used_atinteger | nullcreated_atintegerkeystringПолный ключ — показывается один раз
webhook_secretstringСекрет подписи вебхуков — показывается один раз
Ошибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/admin/keys/{id}Ключ
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноТело запроса не требуется.
Успешный ответ
200OK
application/json
idstringobject"api_key"namestringprefixstringscopesstring[]enabledbooleanrevoked_atinteger | nullexpires_atinteger | nulllimitsobjectПоля limits
monthly_limit_rubnumberspent_month_rubnumberdaily_limit_rubnumberspent_day_rubnumberrpmintegertpmintegerconcurrencyintegerip_allowliststring[]allowed_modelsstring[]group_idstring | nullmember_user_idstring | nullwebhook_secret_setbooleancalls_monthintegerlast_used_atinteger | nullcreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
PATCH/admin/keys/{id}Изменить ключ (применяется следующим запросом: кэша авторизации нет)
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноТело запроса · application/json
namestringscopes"chat" | "embeddings" | "media" | "admin" | "usage"[]monthly_limit_rubnumber | nulldaily_limit_rubnumber | nullrpminteger | nulltpminteger | nullconcurrencyinteger | nullip_allowlistarray | string | nullallowed_modelsarray | nullexpires_atstring | nullgroup_idstring | nullmember_user_idstring | nullenabledbooleanУспешный ответ
200OK
application/json
idstringobject"api_key"namestringprefixstringscopesstring[]enabledbooleanrevoked_atinteger | nullexpires_atinteger | nulllimitsobjectПоля limits
monthly_limit_rubnumberspent_month_rubnumberdaily_limit_rubnumberspent_day_rubnumberrpmintegertpmintegerconcurrencyintegerip_allowliststring[]allowed_modelsstring[]group_idstring | nullmember_user_idstring | nullwebhook_secret_setbooleancalls_monthintegerlast_used_atinteger | nullcreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
DELETE/admin/keys/{id}Отозвать ключ (мгновенно; журнал сохраняется)
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноТело запроса не требуется.
Успешный ответ
200OK
application/json
idstringobject"api_key"namestringprefixstringscopesstring[]enabledbooleanrevoked_atinteger | nullexpires_atinteger | nulllimitsobjectПоля limits
monthly_limit_rubnumberspent_month_rubnumberdaily_limit_rubnumberspent_day_rubnumberrpmintegertpmintegerconcurrencyintegerip_allowliststring[]allowed_modelsstring[]group_idstring | nullmember_user_idstring | nullwebhook_secret_setbooleancalls_monthintegerlast_used_atinteger | nullcreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
POST/admin/keys/{id}/rotateРотация: новый ключ с теми же настройками, старый истекает через grace_hours (по умолчанию 24)
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноТело запроса · application/json
grace_hoursnumberМинимум: 0. Максимум: 168.
Успешный ответ
201OK
application/json
idstringobject"api_key"namestringprefixstringscopesstring[]enabledbooleanrevoked_atinteger | nullexpires_atinteger | nulllimitsobjectПоля limits
monthly_limit_rubnumberspent_month_rubnumberdaily_limit_rubnumberspent_day_rubnumberrpmintegertpmintegerconcurrencyintegerip_allowliststring[]allowed_modelsstring[]group_idstring | nullmember_user_idstring | nullwebhook_secret_setbooleancalls_monthintegerlast_used_atinteger | nullcreated_atintegerkeystringПолный ключ — показывается один раз
webhook_secretstringСекрет подписи вебхуков — показывается один раз
Ошибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
POST/admin/keys/{id}/webhook-secretНовый секрет подписи вебхуков (показывается один раз, старый перестаёт действовать)
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноТело запроса не требуется.
Успешный ответ
201OK
application/json
idstringwebhook_secretstringОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/admin/groupsГруппы ключей
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Тело запроса не требуется.
Успешный ответ
200OK
application/json
dataobject[]Поля data[]
idstringobject"key_group"namestringmonthly_limit_rubnumberspent_month_rubnumberkeysintegercreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
POST/admin/groupsСоздать группу с месячным лимитом
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Тело запроса · application/json
namestringmonthly_limit_rubnumber | nullУспешный ответ
201OK
application/json
idstringobject"key_group"namestringmonthly_limit_rubnumberspent_month_rubnumberkeysintegercreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
PATCH/admin/groups/{id}Изменить группу
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноТело запроса · application/json
namestringmonthly_limit_rubnumber | nullУспешный ответ
200OK
application/json
idstringobject"key_group"namestringmonthly_limit_rubnumberspent_month_rubnumberkeysintegercreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
DELETE/admin/groups/{id}Удалить группу (ключи остаются без группы)
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноТело запроса не требуется.
Успешный ответ
200OK
application/json
idstringdeletedbooleanОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/admin/membersСотрудники организации с лимитами и расходом месяца
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Тело запроса не требуется.
Успешный ответ
200OK
application/json
dataobject[]Поля data[]
user_idstringobject"member"emailstring | nullnamestring | nullrolestringdeptstring | nullmonthly_limit_rubnumberspent_month_rubnumberdisabledbooleanОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
PATCH/admin/members/{userId}Лимит / блокировка / отдел сотрудника (владельца ограничить нельзя)
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
userIdpath · stringобязательноТело запроса · application/json
monthly_limit_rubnumber | nulldisabledbooleandeptstring | nullУспешный ответ
200OK
application/json
user_idstringobject"member"emailstring | nullnamestring | nullrolestringdeptstring | nullmonthly_limit_rubnumberspent_month_rubnumberdisabledbooleanОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/admin/auditАудит действий администратора и жизненного цикла ключей
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
limitquery · integer1..200
beforequery · stringunix-время курсора
Тело запроса не требуется.
Успешный ответ
200OK
application/json
dataobject[]Поля data[]
idstringobject"audit_event"actionstringtargetstring | nullactorobject | nulldiffobjectipstring | nullcreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
GET/admin/webhooks/deliveriesЖурнал доставок вебхуков
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
taskquery · stringtask_…
statusquery · stringpending|delivered|failed
limitquery · integerТело запроса не требуется.
Успешный ответ
200OK
application/json
dataobject[]Поля data[]
idstringobject"webhook.delivery"eventstringstatus"pending" | "delivered" | "failed"attemptsintegerlast_statusinteger | nulllast_errorstring | nullnext_attempt_atinteger | nulldelivered_atinteger | nullcreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
POST/admin/webhooks/deliveries/{id}/retryПовторить доставку вручную (новая доставка с новым id)
Авторизация: Bearer или x-api-key. Скоуп: admin. Ссылка на метод
Параметры пути и строки запроса
idpath · stringобязательноwhd_…
Тело запроса не требуется.
Успешный ответ
201OK
application/json
idstringobject"webhook.delivery"eventstringstatus"pending" | "delivered" | "failed"attemptsintegerlast_statusinteger | nulllast_errorstring | nullnext_attempt_atinteger | nulldelivered_atinteger | nullcreated_atintegerОшибки: 400, 401, 402, 403, 404, 409, 429, 503. Коды и действия при ошибке →
Версии и миграция
Сентябрь 2026 · описание API 2.0. Chat Completions с инструментами и JSON Schema, Responses и Messages, эмбеддинги, медиа-задачи и вебхуки, транскрибация, управление ключами и расходы.
Версия описания 2.0 не меняет префикс URL: используйте https://qvora.ru/api/v1. Старые пути /api/v1/ext/* сохраняются для существующих интеграций. Вместо удалённого qvora.channel используйте qvora.served_model.
Документация сверена с контрактом API 20 сентября 2026 года. Поля и методы справочника проверяются вместе со схемой при обновлении API.