Подарок
10 генераций Nano Banana 2 в подарок за первое пополнение от 500 ₽
Пополните баланс на 500 ₽ или больше, и первые 10 картинок лучшей модели Google будут за наш счёт.
Пополнить и забратьЗабрать
QVORA
API · v2

Документация API QVORA

Один ключ и один баланс в рублях для текстовых моделей, эмбеддингов и медиа-генераций. Совместимо с OpenAI SDK (Chat Completions, Responses), Anthropic SDK и Claude Code (Messages), Cursor, Continue, Cline, Codex CLI, n8n и Make.

Быстрый старт

Base URL — https://qvora.ru/api/v1. Ключ создаётся в кабинете компании → «Ключи» (формат shds-…, показывается один раз). Заголовок — Authorization: Bearer shds-… или x-api-key.

curl 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":"Привет!"}]}'
from openai import OpenAI
client = OpenAI(base_url="https://qvora.ru/api/v1", api_key="shds-…")
r = client.chat.completions.create(model="claude-sonnet", messages=[{"role": "user", "content": "Привет!"}])
print(r.choices[0].message.content, r.usage, r.model_extra["qvora"]["cost_rub"])
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://qvora.ru/api/v1", apiKey: process.env.QVORA_API_KEY });
const stream = await client.chat.completions.create({ model: "gpt-5-mini", messages: [{ role: "user", content: "Привет!" }], stream: true });
for await (const chunk of stream) process.stdout.write(chunk.choices[0]?.delta?.content ?? "");

Легаси-префикс /api/v1/ext/* эквивалентен /api/v1/* и сохраняется для существующих интеграций.

Ключи и скоупы

Ключ принадлежит организации и списывает с её баланса. У ключа есть скоупы — ручка вне скоупа отвечает 403 insufficient_scope:

  • chat — Chat Completions, Responses, Messages; embeddings; media — медиа-задачи и транскрибация;
  • usage — чтение расходов; admin — управление ключами, группами, сотрудниками, аудит.

Настройки ключа — месячный и дневной лимит в ₽, запросов и токенов в минуту, одновременных запросов, allowlist моделей, IP-allowlist, срок действия, группа и сотрудник — применяются следующим запросом: кэша авторизации нет. Отзыв — мгновенный. Ключ хранится как SHA-256, восстановить его нельзя — только ротация (старый живёт ещё 24 часа).

Маршруты

МетодПутьНазначениеСкоуп ключа
POST/chat/completionsChat Completionschat
POST/responsesResponses APIchat
POST/messagesAnthropic Messages APIchat
POST/embeddingsЭмбеддингиembeddings
GET/modelsМодели и цены
POST/media/tasksМедиа-задачаmedia

Загружаем схему… Полная схема: /api/v1/openapi.json.

Chat Completions

POST /v1/chat/completions. Поддержано: роли system/developer/user/assistant/tool, текст и картинки (image_url, включая data:), tools / tool_choice / parallel_tool_calls с полным циклом tool_calls → role:tool, 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. Молчаливого игнора нет. В стриме tool_calls идут дельтами по index (первая — с id и type), в конце — чанк с usage и data: [DONE].

// ответ: стандартный chat.completion + блок qvora
{
  "choices": [{ "message": { "role": "assistant", "content": null,
    "tool_calls": [{ "id": "call_1", "type": "function", "function": { "name": "get_weather", "arguments": "{\"city\":\"Москва\"}" } }] },
    "finish_reason": "tool_calls" }],
  "usage": { "prompt_tokens": 120, "completion_tokens": 18, "total_tokens": 138,
    "prompt_tokens_details": { "cached_tokens": 96 }, "completion_tokens_details": { "reasoning_tokens": 0 } },
  "qvora": { "served_model": "gpt-5-mini", "cost_rub": 0.02, "cache_saved_rub": 0.01, "request_ref": "…" }
}

Идемпотентность. Заголовок Idempotency-Key (только non-stream) в течение 24 часов возвращает сохранённый ответ без второго списания (Idempotent-Replayed: true). Тот же ключ с другим телом — 409 idempotency_key_reused. Отмена. Разрыв соединения в стриме останавливает генерацию — платите только за полученное.

Responses API и Codex

POST /v1/responses: строка или items во input, instructions, плоские function-tools, циклfunction_call → function_call_output, text.format (json_schema), reasoning.effort, стрим событиямиresponse.created → … → response.completed со сквозным sequence_number. previous_response_id и background не поддержаны (400). Хостовые инструменты (web_search и т.п.) игнорируются, о чём сообщает заголовок x-qvora-dropped-tools.

# ~/.codex/config.toml — Codex CLI через QVORA
model = "gpt-5-mini"
model_provider = "qvora"
[model_providers.qvora]
name = "QVORA"
base_url = "https://qvora.ru/api/v1"
env_key = "QVORA_API_KEY"
wire_api = "responses"

Anthropic Messages и Claude Code

POST /v1/messages и /v1/messages/count_tokens: system, блоки text/image/tool_use/tool_result,tools/tool_choice, stop_sequences, thinking, стрим событиями Anthropic (message_start → content_block_* → message_delta → message_stop), ошибки в конверте Anthropic. usage.input_tokens не включаетcache_read_input_tokens — как у Anthropic. Через этот протокол доступны любые модели каталога, не только Claude.

export ANTHROPIC_BASE_URL=https://qvora.ru/api
export ANTHROPIC_AUTH_TOKEN=shds-…     # или ANTHROPIC_API_KEY
export ANTHROPIC_MODEL=claude-sonnet-5  # любой Claude из GET /v1/models (псевдонимы понимаются)
claude

Серверные инструменты Anthropic (web_search, computer и т.п.) исполняются у Anthropic и через QVORA недоступны — они игнорируются с заголовком x-qvora-dropped-tools. Thinking-блоки в ответ не возвращаются.

Эмбеддинги

POST /v1/embeddingsinput строка или массив (до 2048), dimensions где модель умеет, encoding_format: float. Модели и цены — в GET /v1/models с type: embedding. Списание только за вход, минимум 0,1 ₽ за запрос.

Медиа-задачи

Все медиа-операции асинхронные. Каталог GET /v1/media/models для каждой модели отдаёт операции (generate, edit, animate, upscale, remove_background), JSON Schema параметров (длительности, разрешения, соотношения сторон, голоса, число вариаций), роли входов (image, first_frame, last_frame,video, reference_*) с ограничениями и правило цены. Схема строится из того же каталога, что и Студия — второго списка параметров нет.

# создать картинку и подождать до 60 с
curl -X POST https://qvora.ru/api/v1/media/tasks -H "Authorization: Bearer $QVORA_API_KEY" -H "Content-Type: application/json" -d '{
  "model": "nano-banana", "prompt": "красный куб на белом фоне", "params": { "aspect": "16:9", "count": 1 },
  "idempotency_key": "order-1042", "webhook_url": "https://example.com/hooks/qvora", "wait": 60 }'
# → 202 { "id": "task_…", "status": "queued|running|succeeded", "results": [{ "url": "…", "expires_at": … }], "cost": { "charged_rub": 13 } }
curl https://qvora.ru/api/v1/media/tasks/task_… -H "Authorization: Bearer $QVORA_API_KEY"
  • Входы — публичные https-URL или data:-URI (до 200 МБ); тип определяется по содержимому.
  • Статусы: queued → running → succeeded | failed | cancelled; progress, cost.charged_rub / refunded_rub, error.code.
  • Отмена POST /media/tasks/:id/cancel — пока задача в очереди; деньги возвращаются. Взятую в работу отменить нельзя (409).
  • URL результатов подписаны и действуют 1 час (expires_at) — заберите файл или запросите задачу снова.
  • idempotency_key: повтор возвращает ту же задачу (200 + Idempotent-Replayed), другое тело — 409.

Вебхуки

При webhook_url (только https, публичный адрес) по завершении задачи приходит POST с событиемmedia.task.succeeded | failed | cancelled. Заголовки: X-Qvora-Event, X-Qvora-Delivery-Id, X-Qvora-Timestamp,X-Qvora-Signature: t=<ts>,v1=<hex>, где v1 = HMAC-SHA256(secret, `${ts}.${rawBody}`). Секрет выдаётся вместе с ключом (и по POST /admin/keys/:id/webhook-secret), повторно не показывается.

import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(secret, signature, rawBody, now = Math.floor(Date.now() / 1000)) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(signature); if (!m) return false;
  if (Math.abs(now - Number(m[1])) > 300) return false;                 // защита от replay: 5 минут
  const expected = createHmac("sha256", secret).update(`${m[1]}.${rawBody}`).digest("hex");
  return timingSafeEqual(Buffer.from(expected, "hex"), Buffer.from(m[2], "hex"));
}

Доставка at-least-once: дедуплицируйте по data.id + type. Ретраи при не-2xx: 5 с, 20 с, 1, 3, 10, 30 мин; журнал — GET /media/tasks/:id/webhooks, ручной повтор — в admin API.

Транскрибация

POST /v1/audio/transcriptions — multipart file (как в OpenAI SDK) или JSON { "url": "https://…" }; model: whisper-1; response_format: json | verbose_json | text; language. Синхронно, дедлайн до 10 минут; цена за минуту аудио, списание по факту, стоимость — в x-qvora-cost-rub.

Цены, кэш, биллинг

  • Цены — в GET /v1/models (price_rub_per_1k: input / cached_input / cache_write / output) и в медиа-каталоге (price) — по прайс-буку вашего контракта.
  • Текст: резерв под максимум запроса → списание по фактическим токенам → возврат разницы. Токены из кэша провайдера (cached_tokens) тарифицируются по ставке cached_input; экономия видна в qvora.cache_saved_rub.
  • Медиа: цена известна до запуска (кроме апскейла видео — по длительности исходника); при ошибке или отмене деньги возвращаются.
  • Баланс, резерв, расход и возврат — разные сущности: GET /v1/balance показывает balance_rub, credit_limit_rub, available_rub, reserved_rub.
  • Нехватка средств — 402 insufficient_balance с required_amount_rub и available_amount_rub. Постоплата — через кредитный лимит организации.
  • В ответе всегда qvora.served_model — наш публичный id модели; request_ref — ссылка на строку в /v1/usage/requests.

Лимиты

ЛимитГде задаётсяКод при превышении
Запросов в минуту (rpm)ключ429 rate_limit_exceeded
Токенов в минуту (tpm)ключ429 tpm_limit_exceeded
Одновременных запросовключ429 concurrency_limit_exceeded
Расход в день / месяц, ₽ключ429 daily_limit_exceeded / monthly_limit_exceeded
Расход группы в месяцгруппа ключей429 group_limit_exceeded
Расход сотрудника в месяцсотрудник (ключ с member_user_id)429 member_limit_exceeded
Моделиallowlist ключа ∩ прайс-бук404 model_not_found
IPallowlist ключа403 ip_not_allowed
Контекст500 сообщений, 1,5 млн символов, 8 картинок, 512 инструментов400 context_length_exceeded и др.
Таймаутыстрим: 90 с простоя / 15 мин всего; синхронные вызовы: до 10 мин504 deadline_exceeded

Admin API и usage

Ключ со скоупом admin управляет ключами (/v1/admin/keys: создание, изменение, ротация, отзыв, секрет вебхуков), группами (/admin/groups), лимитами сотрудников (/admin/members), читает аудит (/admin/audit: кто, когда, что изменил — без секретов) и журнал вебхуков. Он не может выдать скоупы шире своих и не трогает владельца, прайс-бук и кредитный лимит.

# расходы за месяц по сотрудникам и по конечным пользователям (поле user в запросах)
curl "https://qvora.ru/api/v1/usage?from=2026-09-01&to=2026-09-30&group_by=member" -H "Authorization: Bearer $QVORA_API_KEY"
curl "https://qvora.ru/api/v1/usage/requests?limit=100&api=chat" -H "Authorization: Bearer $QVORA_API_KEY"

Коды ошибок

Конверт: { "error": { "message", "type", "code", "param", "trace_id" } }. trace_id = заголовок x-request-id — присылайте в поддержку. Для /v1/messages — конверт Anthropic (type: error).

HTTPcodeКогда
400invalid_value, missing_parameter, unsupported_parameter, unsupported_operation, context_length_exceeded, too_many_*, invalid_input_file, forbidden_addressОшибка запроса; param указывает поле
401invalid_api_keyНет ключа, отозван, истёк
402insufficient_balanceНе хватает средств (с required_amount_rub, available_amount_rub)
403insufficient_scope, ip_not_allowed, member_disabled, organization_deactivated, scope_escalationДоступ
404model_not_found, task_not_found, key_not_foundОбъект недоступен ключу
409idempotency_key_reused, idempotency_in_flight, task_not_cancellable, request_expired, key_revokedКонфликт состояния
413file_too_largeВходной файл больше лимита
429rate_limit_exceeded, tpm_limit_exceeded, concurrency_limit_exceeded, daily_limit_exceeded, monthly_limit_exceeded, group_limit_exceeded, member_limit_exceededЛимиты — повторите позже
503model_unavailableМодель временно недоступна — повторите или смените модель
504deadline_exceededСинхронная операция не уложилась в дедлайн
500internal_errorНаша ошибка — пришлите trace_id

Изменения

  • v2 (сентябрь 2026) — tools/tool_calls и json_schema в Chat Completions; /v1/responses; /v1/messages (+count_tokens); /v1/embeddings; медиа-задачи с каталогом схем, вебхуками и идемпотентностью; транскрибация; admin API, группы, дневные/TPM/concurrency-лимиты; /v1/usage; Idempotency-Key; псевдонимы моделей; qvora.served_model вместо внутреннего названия канала.
  • Миграция с v1: пути /ext/* продолжают работать. Поле qvora.channel удалено — используйте qvora.served_model. Лимиты сообщений/символов увеличены. Ошибки те же, добавлены новые коды.

Схема OpenAPI 3.1: /api/v1/openapi.json. Вопросы — support@qvora.ru.