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

Содержание

Обзор

Ocelotiq — это платформа, предоставляющая единый OpenAI-совместимый API для доступа к различным AI-моделям: GPT-4o, Claude, Gemini, Llama и другим.

Вам не нужно заводить аккаунты у каждого провайдера — достаточно одного API-ключа Ocelotiq.

Base URLhttps://ai.ocelotiq.ru/v1
Форматapplication/json

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

  1. Зарегистрируйтесь и подтвердите email.
  2. Перейдите в API-ключи и создайте ключ. Скопируйте его — он показывается один раз.
  3. Убедитесь, что на балансе есть средства (раздел Личный кабинет).
  4. Отправьте первый запрос:
Python — OpenAI SDK
from openai import OpenAI

client = OpenAI(
    base_url="https://ai.ocelotiq.ru/v1",
    api_key="ocelotiq_ваш_ключ",
)

response = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Привет!"}],
)

print(response.choices[0].message.content)
cURL
curl https://ai.ocelotiq.ru/v1/chat/completions \
  -H "Authorization: Bearer ocelotiq_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [
      {"role": "user", "content": "Привет!"}
    ]
  }'
Node.js — OpenAI SDK
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://ai.ocelotiq.ru/v1",
  apiKey: "ocelotiq_ваш_ключ",
});

const response = await client.chat.completions.create({
  model: "openai/gpt-4o-mini",
  messages: [{ role: "user", content: "Привет!" }],
});

console.log(response.choices[0].message.content);

Аутентификация

Запросы генерации и персональные каталоги на ai.ocelotiq.ru авторизуются через пользовательский API-ключ в заголовке:

Authorization: Bearer ocelotiq_ваш_ключ

API-ключи создаются в личном кабинете. Вы можете создать несколько ключей для разных проектов.

Важно: полный API-ключ показывается только один раз при создании. Сохраните его в надёжное место. Если ключ утерян — отзовите старый и создайте новый.

Chat Completions

POST/v1/chat/completions

Основной эндпоинт для генерации текста. Поддерживаемые параметры зависят от выбранной модели и перечислены в её supported_parameters.

Параметры запроса

ПараметрТипОписание
modelstringSlug модели, например openai/gpt-4o-mini
messagesarrayМассив сообщений с полями role и content
streambooleanВключить стриминг ответа (SSE). По умолчанию false
temperaturenumberТемпература генерации (0–2). Необязательный
max_tokensnumberМаксимум токенов в ответе. Необязательный
top_pnumberNucleus sampling. Необязательный
reasoningobjectПараметры reasoning для совместимой модели
toolsarrayОписания клиентских функций и встроенных инструментов
tool_choicestring | objectАвтовыбор, обязательный вызов или конкретная функция
parallel_tool_callsbooleanРазрешить модели вернуть несколько вызовов функций
response_formatobjectТекст, JSON object или JSON Schema
providerobjectНастройки маршрутизации для выбранной модели
service_tierstringТариф обработки: auto, default, flex, priority или scale
modelsarrayПубличные slug резервных моделей из каталога Ocelotiq
pluginsarrayДополнительные возможности обработки ответа

Роли сообщений

  • system — системная инструкция для модели
  • user — сообщение пользователя
  • assistant — предыдущий ответ модели (для контекста)
  • tool — результат клиентской функции с соответствующим tool_call_id
Пример запроса
{
  "model": "openai/gpt-4o-mini",
  "messages": [
    {
      "role": "system",
      "content": "Ты полезный ассистент."
    },
    {
      "role": "user",
      "content": "Объясни что такое API"
    }
  ],
  "temperature": 0.7
}
Пример ответа
{
  "id": "chatcmpl-abc123",
  "object": "chat.completion",
  "created": 1741540000,
  "model": "openai/gpt-4o-mini",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "API (Application Programming Interface) — это..."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 24,
    "completion_tokens": 156,
    "total_tokens": 180
  }
}

Мультимодальный ввод

В POST /v1/chat/completions поле content сообщения пользователя может быть массивом текста и медиа. Допустимы image_url, file для PDF, input_audio и video_url. Обычные и потоковые ответы используют один формат запроса.

Совместимость модели

Проверьте architecture.input_modalities в GET /v1/models: для запроса нужны соответственно image, file, audio или video. Все модальности должны поддерживать основная и каждая резервная модель из models, иначе API вернёт 400 до начала обработки.

Форматы

ТипФорматыПередача
image_urlPNG, JPEG, WebP, GIFHTTPS или data:image/...;base64,...
filePDF (application/pdf)HTTPS или data:application/pdf;base64,...
input_audioWAV, MP3, AIFF, AAC, OGG, FLAC, M4A, PCM16, PCM24Только raw Base64 и отдельное поле format
video_urlMP4, MPEG, MOV, WebMHTTPS или data:video/...;base64,...

Для URL разрешён только HTTPS без логина и пароля в адресе. Сервер по ссылке должен вернуть поддерживаемый MIME type. Поддержка YouTube и прямых video URL зависит от выбранной модели и маршрута; если ссылка не принимается, используйте Base64.

Лимиты запроса

ДанныеМаксимум
Одно изображение20 MiB после декодирования
Один PDF32 MiB после декодирования
Один аудиофайл25 MiB после декодирования
Одно видео64 MiB после декодирования
Все встроенные медиа64 MiB после декодирования
JSON-тело Chat Completions96 MiB

Base64 увеличивает JSON примерно на треть, поэтому лимит тела больше лимита декодированных данных. HTTPS-ссылки учитываются только как текст JSON, но у модели или провайдера могут быть дополнительные ограничения на размер, длительность, разрешение и количество файлов.

Конфиденциальность

Ocelotiq не создаёт постоянное файловое хранилище для этих запросов и не записывает Base64, содержимое документов или URL из тела запроса в access log. Медиа передаётся выбранной модели для обработки. Для закрытых данных используйте Base64 либо короткоживущую подписанную HTTPS-ссылку без долговременных секретов.

Ошибки до отправки

Некорректная структура, схема URL, MIME type, Base64, сигнатура файла, формат или несовместимая модель возвращают 400. Превышение лимита возвращает 413. Тело ошибки не содержит исходные медиа и приватные URL.

JSON — изображение по URL
{
  "model": "google/gemini-2.5-flash",
  "messages": [{
    "role": "user",
    "content": [
      {"type": "text", "text": "Что изображено на фотографии?"},
      {
        "type": "image_url",
        "image_url": {
          "url": "https://cdn.example.com/photo.webp",
          "detail": "auto"
        }
      }
    ]
  }]
}
Python — изображение в Base64
import base64

with open("photo.jpg", "rb") as file:
    image = base64.b64encode(file.read()).decode("ascii")

response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Извлеки текст с изображения"},
            {
                "type": "image_url",
                "image_url": {
                    "url": f"data:image/jpeg;base64,{image}"
                },
            },
        ],
    }],
)
Python — PDF
import base64

with open("report.pdf", "rb") as file:
    document = base64.b64encode(file.read()).decode("ascii")

response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Составь резюме документа"},
            {
                "type": "file",
                "file": {
                    "filename": "report.pdf",
                    "file_data": f"data:application/pdf;base64,{document}",
                },
            },
        ],
    }],
)

# Для общедоступного PDF file_data может быть HTTPS-ссылкой.
Python — аудио
import base64

with open("meeting.wav", "rb") as file:
    audio = base64.b64encode(file.read()).decode("ascii")

response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Перечисли принятые решения"},
            {
                "type": "input_audio",
                "input_audio": {"data": audio, "format": "wav"},
            },
        ],
    }],
)
JSON — видео по URL и стриминг
{
  "model": "google/gemini-2.5-flash",
  "messages": [{
    "role": "user",
    "content": [
      {"type": "text", "text": "Опиши ключевые события видео"},
      {
        "type": "video_url",
        "video_url": {
          "url": "https://www.youtube.com/watch?v=VIDEO_ID"
        }
      }
    ]
  }],
  "stream": true
}
Python — видео в Base64
import base64

with open("clip.mp4", "rb") as file:
    video = base64.b64encode(file.read()).decode("ascii")

response = client.chat.completions.create(
    model="google/gemini-2.5-flash",
    messages=[{
        "role": "user",
        "content": [
            {"type": "text", "text": "Опиши ключевые события видео"},
            {
                "type": "video_url",
                "video_url": {
                    "url": f"data:video/mp4;base64,{video}"
                },
            },
        ],
    }],
)
Примеры ошибок
{
  "error": "input modality video is not supported by model example/text-model"
}

{
  "error": "messages[0].content[1].input_audio.data contains invalid base64 data"
}

{
  "error": "messages[0].content[1].video_url.url exceeds its decoded size limit"
}

Reasoning

Параметр reasoning управляет объёмом рассуждений, а include_reasoning запрашивает доступные reasoning-данные. Используйте модель, у которой reasoning, reasoning_effort или include_reasoning указан в supported_parameters; точные режимы перечислены в reasoning_capabilities.

Ответ сохраняет reasoning, reasoning_details, finish_reason и usage.completion_tokens_details.reasoning_tokens. Reasoning-токены входят в выходные токены и оплачиваются по цене output выбранной модели.

Стриминг

При stream: true поля delta.reasoning и delta.reasoning_details могут приходить отдельными чанками. Собирайте элементы в порядке получения и не пытайтесь расшифровывать подписанные или зашифрованные блоки. Для продолжения после tool call передайте полученные reasoning_details в assistant-сообщении без изменений.

Если модель или один из fallback-провайдеров не поддерживает запрошенный reasoning-параметр, API вернёт 400 до отправки запроса.
cURL — reasoning
curl https://ai.ocelotiq.ru/v1/chat/completions \
  -H "Authorization: Bearer ocelotiq_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "google/gemini-2.5-flash",
    "messages": [
      {"role": "user", "content": "Найди ошибку в этом доказательстве: ..."}
    ],
    "reasoning": {"effort": "high"},
    "include_reasoning": true
  }'
Ответ и reasoning usage
{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": "Ошибка находится в переходе...",
      "reasoning_details": [
        {"type": "reasoning.encrypted", "data": "..."}
      ]
    },
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 84,
    "completion_tokens": 412,
    "total_tokens": 496,
    "completion_tokens_details": {"reasoning_tokens": 330}
  }
}

Function Calling

Передайте функции в tools. Модель вернёт один или несколько message.tool_calls и finish_reason: "tool_calls". Ocelotiq не запускает клиентские функции: приложение проверяет имя и аргументы, выполняет разрешённый код и отправляет результат сообщением role: "tool" с исходным tool_call_id.

tool_choice: "required" требует хотя бы один вызов; объект {"type":"function","function":{"name":"..."}} выбирает конкретную функцию. parallel_tool_calls: true разрешает несколько вызовов в одном ответе — результат нужен для каждого ID.

Стриминг

В потоке delta.tool_calls может разбивать function.arguments на несколько строк. Объединяйте аргументы по index и выполняйте функции только после завершения вызова. reasoning_details также нужно сохранить при следующем запросе.

Модель должна содержать tools в supported_parameters; для tool_choice и параллельных вызовов проверяются соответствующие capability. Неверная схема функции, неизвестное имя в forced choice или отсутствующий tool_call_id возвращают 400.
Python — полный клиентский tool loop
import json
from openai import OpenAI

client = OpenAI(
    base_url="https://ai.ocelotiq.ru/v1",
    api_key="ocelotiq_ваш_ключ",
)

tools = [{
    "type": "function",
    "function": {
        "name": "get_weather",
        "description": "Получить текущую погоду в городе",
        "parameters": {
            "type": "object",
            "properties": {"city": {"type": "string"}},
            "required": ["city"],
            "additionalProperties": False,
        },
    },
}]

messages = [{"role": "user", "content": "Какая погода в Казани?"}]
first = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=messages,
    tools=tools,
    tool_choice="required",
    parallel_tool_calls=True,
)

assistant = first.choices[0].message
# model_dump сохраняет tool_calls и reasoning_details для продолжения.
messages.append(assistant.model_dump(exclude_none=True))

for call in assistant.tool_calls or []:
    arguments = json.loads(call.function.arguments)
    if call.function.name != "get_weather":
        raise ValueError("Неизвестная функция")
    result = {"city": arguments["city"], "temp_c": 18, "condition": "cloudy"}
    messages.append({
        "role": "tool",
        "tool_call_id": call.id,
        "content": json.dumps(result, ensure_ascii=False),
    })

final = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=messages,
    tools=tools,
)
print(final.choices[0].message.content)
Ответ с одним tool call
{
  "choices": [{
    "message": {
      "role": "assistant",
      "content": null,
      "tool_calls": [{
        "id": "call_weather_1",
        "type": "function",
        "function": {
          "name": "get_weather",
          "arguments": "{\"city\":\"Казань\"}"
        }
      }]
    },
    "finish_reason": "tool_calls"
  }]
}

Structured Outputs

response_format.type: "json_object" гарантирует JSON-объект, но не фиксирует набор полей. Явно попросите модель вернуть JSON. Режим json_schema проверяет форму ответа по переданной схеме.

Для strict: true корневая схема должна иметь type: "object", каждый ключ из properties должен входить в required, а additionalProperties должен быть false. Некорректная схема возвращает 400 с путём проблемного поля.

Выберите модель с response_format или structured_outputs в supported_parameters. Параметр provider.require_parameters включается автоматически; если совместимого маршрута нет, запрос завершится ошибкой, а не неструктурированным ответом.

Стриминг и биллинг

При stream: true JSON приходит фрагментами: объедините весь delta.content и разбирайте документ после finish_reason. Structured Outputs оплачиваются как обычные входные и выходные токены; plugin response-healing доступен только без стриминга.

cURL — JSON object
curl https://ai.ocelotiq.ru/v1/chat/completions \
  -H "Authorization: Bearer ocelotiq_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [{"role": "user", "content": "Верни JSON с полями name и year"}],
    "response_format": {"type": "json_object"}
  }'
cURL — strict JSON Schema
curl https://ai.ocelotiq.ru/v1/chat/completions \
  -H "Authorization: Bearer ocelotiq_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini",
    "messages": [{"role": "user", "content": "Извлеки имя и год из: Анна окончила вуз в 2024 году"}],
    "response_format": {
      "type": "json_schema",
      "json_schema": {
        "name": "graduation",
        "strict": true,
        "schema": {
          "type": "object",
          "properties": {
            "name": {"type": "string"},
            "year": {"type": "integer"}
          },
          "required": ["name", "year"],
          "additionalProperties": false
        }
      }
    }
  }'

Маршрутизация

Настройки маршрута

Объект provider ограничивает маршруты обработки для выбранной модели. Он не управляет API-ключами Ocelotiq.

Разрешены order, only, ignore, allow_fallbacks, require_parameters, data_collection, zdr, quantizations и sort. Остальные поля отклоняются до отправки запроса.

provider.require_parameters автоматически становится true, если запрос использует параметры, зависящие от возможностей модели, например tools или response_format.

Service tiers

service_tier принимает auto, default, flex, priority или scale. Tier доступен только для маршрута с автоматической ценой и может изменить стоимость и доступность.

Fallback-модели

В models передаются публичные slug резервных моделей в порядке попыток. Каждая модель должна быть включена в каталог Ocelotiq и поддерживать параметры, входные модальности и streaming-режим текущего запроса.

Основная модель остаётся в model и не повторяется в models. В ответе поле model, журнал usage и списание относятся к модели, которая фактически обработала запрос.

Дополнительные возможности

Доступны web search и восстановление структурированного ответа через response-healing. Web search работает только с моделями с автоматической ценой, а response-healing не поддерживается при stream: true.

Проверка запроса

Неизвестные поля, неподдерживаемые параметры и несовместимый multimodal content возвращают 400. Запрещённый маршрут, дополнительная возможность или несовместимый способ расчёта цены возвращает 403. Проверка выполняется до начала обработки и не раскрывает ключи или внутренние model IDs.

Настройки маршрута и service tier
{
  "model": "openai/gpt-4o-mini",
  "messages": [{"role": "user", "content": "Ответь в JSON"}],
  "response_format": {"type": "json_object"},
  "provider": {
    "order": ["openai", "google-vertex"],
    "allow_fallbacks": true,
    "data_collection": "deny"
  },
  "service_tier": "priority"
}
Fallback-модели и streaming
{
  "model": "openai/gpt-4o-mini",
  "models": [
    "google/gemini-2.5-flash",
    "anthropic/claude-3.5-haiku"
  ],
  "messages": [{"role": "user", "content": "Кратко объясни DNS"}],
  "stream": true
}

Guardrails и приватность

Администратор может назначить ограничения для всех аккаунтов, отдельного пользователя или конкретного API-ключа. Если подходят несколько политик, Ocelotiq применяет самое строгое сочетание: минимальный бюджет, пересечение разрешающих списков и все запреты.

Свои политики

На странице «Guardrails» пользователь может создать переиспользуемую политику, а на странице «API-ключи» выбрать её для одного или нескольких ключей. Одному ключу можно назначить несколько политик; их активные ограничения объединяются. Выключенная политика сохраняет назначения, но временно не применяется.

Своя политика может ужесточить, но не ослабить системные правила. При удалении политики её назначения ключам удаляются автоматически.

Бюджеты

Дневной, недельный и месячный бюджеты учитывают завершённые списания и суммы, зарезервированные активными запросами. Свои лимиты для ключа можно задать на странице «API-ключи»; они могут только ужесточить системные ограничения. Пустое поле снимает личный лимит для периода.

Периоды сбрасываются по UTC: день в 00:00, неделя в понедельник, месяц в первый день. При исчерпании бюджета API возвращает 429 и Retry-After; параллельные запросы не могут потратить один остаток несколько раз.

Модели, провайдеры и возможности

Allowlist моделей проверяет основную и все fallback-модели. Allowlist маршрутов пересекается с provider.only из запроса. Политика также может разрешать или запрещать service tiers и дополнительные возможности. Несовместимый запрос отклоняется с 403 до обращения к модели.

ZDR и сбор данных

При обязательном ZDR Ocelotiq устанавливает provider.zdr: true. Запрет сбора данных устанавливает provider.data_collection: "deny", даже если запрос содержит allow. Это ограничивает доступные маршруты, но не превращает сторонний сервис в локальное хранилище и не отменяет его условия обработки данных.

Чувствительные данные

Встроенные фильтры распознают email, телефоны, номера банковских карт с проверкой контрольной суммы, API-ключи и приватные ключи. Для каждого типа задаётся действие: заменить совпадение маркером [REDACTED:тип] или заблокировать запрос. Дополнительные RE2-фильтры работают в режимах redact и block.

Проверяются текст сообщений и content parts, image prompts, инструкции и input Responses API, текстовые multipart-поля, аргументы вызовов инструментов и их результаты. URL и бинарные Base64-данные не разбираются как текст. Редактирование меняет данные, которые получает модель; при блокировке исходное значение не включается в ошибку или аудит.

Prompt injection

Детектор отмечает ограниченный набор признаков подмены инструкций, запроса системного prompt и смены роли. Политика может только записывать эти сигналы в аудит или блокировать совпадения. Детектор не гарантирует обнаружение всех атак: возможны пропуски, ложные срабатывания, обфускация и новые формулировки. Он дополняет разграничение полномочий, проверку tool arguments и явные allowlist, но не заменяет их.

Ошибки и аудит

Нарушение ограничения возвращает 403 с code: "guardrail_blocked"; бюджет — 429 с code: "guardrail_spend_limit". Поле policy_id содержит безопасный идентификатор правила, например gr_model_allowlist или gr_budget_daily. Журнал решений хранит результат, endpoint, идентификаторы применённых политик, фильтров и сигналов, количество проверенных полей и редакций — без исходного защищённого содержимого.

Ошибка Guardrails
{
  "error": {
    "message": "Request blocked by guardrail policy.",
    "type": "policy_error",
    "code": "guardrail_blocked",
    "policy_id": "gr_model_allowlist"
  }
}

Стриминг

Передайте "stream": true в запросе, чтобы получать ответ по частям через Server-Sent Events (SSE).

Формат полностью совместим с OpenAI — каждый чанк приходит как data: {...}, а конец потока обозначается data: [DONE].

Python — стриминг
stream = client.chat.completions.create(
    model="openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Расскажи историю"}],
    stream=True,
)

for chunk in stream:
    if chunk.choices[0].delta.content:
        print(chunk.choices[0].delta.content, end="")
Пример SSE-чанка
data: {"id":"chatcmpl-abc123","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"Привет"}}]}

data: [DONE]

Поиск в интернете

Некоторые модели поддерживают режим онлайн-поиска — модель автоматически ищет актуальную информацию в интернете перед генерацией ответа.

Как включить

Добавьте суффикс :online к названию модели в параметре model.

Обычный режим: openai/gpt-4o-mini

С поиском: openai/gpt-4o-mini:online

Когда использовать

  • Вопросы о текущих событиях, новостях, погоде
  • Запросы, требующие актуальных данных (цены, курсы, статистика)
  • Поиск информации, которая могла появиться после обучения модели
Обратите внимание: при использовании :online стоимость запроса может быть выше, так как модель дополнительно выполняет поиск в интернете.
Python — поиск в интернете
response = client.chat.completions.create(
    model="openai/gpt-4o-mini:online",
    messages=[{"role": "user", "content": "Какие новости сегодня?"}],
)

print(response.choices[0].message.content)
cURL — поиск в интернете
curl https://ai.ocelotiq.ru/v1/chat/completions \
  -H "Authorization: Bearer ocelotiq_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-4o-mini:online",
    "messages": [
      {"role": "user", "content": "Какой курс доллара сейчас?"}
    ]
  }'

Список моделей

GET/v1/models

Возвращает OpenAI-совместимый список доступных моделей. Базовые поля id, object, created и owned_by сохранены, а дополнительные поля описывают совместимость модели.

В каталоге Модели эти данные показаны бейджами. Фильтры позволяют оставить модели с tools, reasoning, структурированным JSON и нужными входными или выходными модальностями.

Входные модальности

text — текст, image — изображения, audio — аудио, file — файлы, video — видео.

Выходные модальности

text — текст, image — генерация изображений, audio — аудио, embeddings — векторы.

Как выбрать модель: сначала проверьте input_modalities и output_modalities, затем наличие нужного имени в supported_parameters (например, tools или structured_outputs). Учитывайте context_length и top_provider.max_completion_tokens. default_parameters показывает настройки провайдера по умолчанию, а reasoning_capabilities — доступность reasoning. Эти метаданные помогают выбрать модель, но сами по себе не добавляют новые media-endpoints и не заменяют документацию конкретного метода.
Пример ответа
{
  "object": "list",
  "data": [
    {
      "id": "openai/gpt-4o-mini",
      "object": "model",
      "created": 1741540000,
      "owned_by": "ocelotiq",
      "context_length": 128000,
      "supported_parameters": ["temperature", "tools", "structured_outputs"],
      "architecture": {
        "input_modalities": ["text", "image"],
        "output_modalities": ["text"]
      },
      "top_provider": { "max_completion_tokens": 16384 },
      "default_parameters": { "temperature": 0.7 },
      "reasoning_capabilities": { "supported": false, "parameters": [] },
      "capabilities": { "chat": true, "streaming": true, "vision": true, "files": false, "reasoning": false }
    }
  ]
}

Генерация изображений

GET/v1/images/models

Возвращает доступные модели с выходной модальностью image. Запрос требует API-ключ. В supported_parameters находятся общие capability модели, а endpoint_capabilities содержит точные значения, поддержку стриминга, разрешённые поля provider.options и персональные цены в копейках для каждого маршрута.

POST/v1/images

Параметры запроса

ПолеТипНазначение
modelstringSlug из GET /v1/images/models; обязательное поле
promptstringОписание результата; обязательное поле
nintegerОт 1 до 10 изображений, если диапазон объявлен моделью
resolutionstring512, 1K, 2K или 4K
sizestringТир разрешения либо WIDTHxHEIGHT, например 2048x2048
aspect_ratiostringauto либо отношение W:H из capability модели
qualitystringauto, low, medium или high
output_formatstringpng, jpeg, webp или svg для совместимой модели
backgroundstringauto, transparent или opaque
output_compressioninteger0–100 для JPEG и WebP; для PNG игнорируется
seedintegerДетерминированный seed, если поддерживается endpoint
input_referencesarrayДо 16 изображений по HTTPS или в Base64 data URL
providerobjectonly, order, ignore, sort, allow_fallbacks и разрешённые provider.options
streambooleanНативный SSE-поток, если supports_streaming равен true

Перед отправкой API выбирает endpoint, который одновременно поддерживает все переданные поля. Отсутствующее имя параметра означает, что этот endpoint его не принимает. Для enum разрешены только перечисленные значения, для range — целые числа между min и max.

Размер, формат и фон

size принимает тир разрешения или точные размеры в пикселях. Точный размер нельзя сочетать с resolution; при заданном aspect_ratio пропорции должны совпадать. Прозрачный фон доступен только с PNG или WebP. output_compression влияет на JPEG и WebP, а для PNG игнорируется. SVG возвращается как Base64-разметка с media_type: "image/svg+xml".

Референсы и маршрутизация

input_references принимает объекты image_url с абсолютным HTTPS URL или data:image/...;base64,.... Поддерживаются PNG, JPEG, WebP и GIF. Поля provider.only, order, ignore, sort и allow_fallbacks ограничивают маршруты; ключи в provider.options[slug] должны присутствовать в allowed_passthrough_parameters соответствующего endpoint.

Обычный ответ

Каждый элемент data содержит b64_json и, когда формат определён, media_type. Декодируйте Base64 и сохраняйте байты с расширением, соответствующим MIME type.

Стриминг

Используйте stream: true только при supports_streaming: true. SSE передаёт превью в image_generation.partial_image. Финальное изображение и usage в image_generation.completed, а затем [DONE], отправляются только после успешного списания. Событие error, разрыв до [DONE] или отсутствие completed event считаются неуспешной генерацией и не списываются.

Лимиты и ошибки

Глобальные пределы: до 10 результатов, до 16 референсов, до 20 MiB на встроенное изображение, до 64 MiB на все Base64-референсы и до 96 MiB на JSON-тело. Меньшие пределы n и input_references берутся из capability endpoint. Некорректное поле, формат, сочетание размера или несовместимая capability возвращают 400; превышение размера — 413; недоступность маршрута или отсутствие безопасной цены до начала ответа — 502. После начала SSE ошибка приходит как type: error либо поток завершается без [DONE].

Биллинг

Завершённая генерация списывается по фактической стоимости из usage.cost. Если ответ не содержит cost, используется синхронизированная цена совместимого image endpoint с учётом количества результатов, референсов, варианта и единицы тарификации. Цены текстовых токенов для этого endpoint не применяются. Незавершённые и отменённые генерации не списываются.

Список моделей
curl https://ai.ocelotiq.ru/v1/images/models \
  -H "Authorization: Bearer ocelotiq_ваш_ключ"
Python — обычный ответ
import base64
import requests

response = requests.post(
    "https://ai.ocelotiq.ru/v1/images",
    headers={"Authorization": "Bearer ocelotiq_ваш_ключ"},
    json={
        "model": "openai/gpt-image-1",
        "prompt": "Предметная фотография керамической чашки",
        "quality": "high",
        "output_format": "png",
        "background": "transparent",
    },
)
response.raise_for_status()

image = base64.b64decode(response.json()["data"][0]["b64_json"])
with open("cup.png", "wb") as file:
    file.write(image)
Ответ JSON
{
  "created": 1748372400,
  "data": [{
    "b64_json": "<BASE64_IMAGE>",
    "media_type": "image/png"
  }],
  "usage": {
    "prompt_tokens": 16,
    "completion_tokens": 272,
    "total_tokens": 288,
    "cost": 0.011
  }
}
cURL — SSE
curl -N https://ai.ocelotiq.ru/v1/images \
  -H "Authorization: Bearer ocelotiq_ваш_ключ" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-image-1",
    "prompt": "Панорама горного озера на рассвете",
    "stream": true
  }'

data: {"type":"image_generation.partial_image","partial_image_index":0,"b64_json":"<BASE64_PREVIEW>"}

data: {"type":"image_generation.completed","b64_json":"<BASE64_IMAGE>","media_type":"image/png","created":1748372400,"usage":{"prompt_tokens":16,"completion_tokens":272,"total_tokens":288,"cost":0.011}}

data: [DONE]
Референс и provider options
{
  "model": "openai/gpt-image-1",
  "prompt": "Перерисуй сцену акварелью",
  "input_references": [{
    "type": "image_url",
    "image_url": {
      "url": "https://cdn.example.com/source.webp"
    }
  }],
  "provider": {
    "only": ["openai"],
    "options": {
      "openai": {"moderation": "auto"}
    }
  }
}

Responses API

POST/v1/responses

Endpoint сохраняет типы элементов output: сообщения, reasoning, вызовы функций, annotations и refusals не объединяются в одну текстовую строку.

Поддерживаемые параметры

ПолеТипНазначение
modelstringПубличный slug модели; обязательное поле
inputstring | object | arrayТекст, message, function_call, function_call_output или reasoning items
instructionsstringСистемная инструкция
streambooleanSSE-поток Responses events
max_output_tokensintegerМаксимальное число выходных токенов
temperature, top_p, frequency_penalty, presence_penalty, top_logprobsnumberПараметры генерации совместимой модели
reasoningobjectУровень effort и формат summary
tools, tool_choicearray | string | objectFunction tools и выбор инструмента
parallel_tool_callsbooleanНесколько вызовов функций в одном ответе
textobjectФормат text, json_object или json_schema; verbosity
service_tierstringauto, default, flex, priority или scale для совместимого маршрута
metadata, userobject | stringМетаданные запроса и идентификатор конечного пользователя
include, max_tool_calls, prompt_cache_key, safety_identifier, truncationразныеПоля маршрутов с нативной поддержкой Responses
store, backgroundbooleanПоддерживается только false

input принимает message с ролями system, developer, user, assistant; content items input_text, output_text, input_image, input_file, refusal; а также function_call и function_call_output. Входной reasoning item требует нативной поддержки Responses.

Стриминг

При stream: true возвращается SSE-поток. Текст приходит в response.output_text.delta, reasoning — в response.reasoning_summary_text.delta, аргументы функций — в response.function_call_arguments.delta. Терминальное событие response.completed содержит итоговый usage.

Инструменты

Function tools работают на всех совместимых маршрутах. Модель возвращает отдельный function_call; результат передаётся как function_call_output с тем же call_id. При parallel_tool_calls: true результат нужен для каждого вызова. Остальные типы tools требуют нативной поддержки Responses и совместимости выбранного провайдера.

Reasoning и структурированный ответ

Reasoning возвращается отдельным item. Число reasoning-токенов сохраняется в usage.output_tokens_details.reasoning_tokens и входит в output_tokens. Для структурированного ответа используйте text.format со значением json_object или json_schema.

Мультимодальный ввод

input_image.image_url принимает абсолютный HTTPS URL или data URL. PDF передаётся через input_file.file_url либо file_data вместе с filename. file_id не поддерживается. Тип, размер и доступность модальности проверяются до отправки запроса.

Формат ответа и usage

Читайте массив output в tool/reasoning workflows. Корневое output_text содержит только склейку текстовых частей. Ответ сохраняет доступные поля провайдера, reasoning details, annotations, refusals и function calls. Биллинг использует фактические input_tokens, output_tokens, cache и reasoning details как для обычного ответа, так и для стрима.

Stateless-ограничения

Ответы и разговоры не сохраняются. Передавайте полную историю в input. Поля previous_response_id, conversation, prompt, store: true и background: true отклоняются с 400.

file_id, неизвестный тип input item или несовместимый параметр также возвращают 400; превышение лимита media payload — 413; отсутствие подходящего маршрута провайдера или читаемой usage/model attribution — 502.

Python
response = client.responses.create(
    model="openai/gpt-4o-mini",
    instructions="Отвечай кратко.",
    input="Объясни DNS в одном предложении.",
)

print(response.output_text)
print(response.usage.input_tokens, response.usage.output_tokens)
Node.js
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://ai.ocelotiq.ru/v1",
  apiKey: process.env.OCELOTIQ_API_KEY,
});

const response = await client.responses.create({
  model: "openai/gpt-4o-mini",
  input: "Объясни DNS в одном предложении.",
});

console.log(response.output_text);
Стриминг — Python
events = client.responses.create(
    model="google/gemini-2.5-flash",
    input="Кратко объясни TLS.",
    reasoning={"effort": "medium"},
    stream=True,
)

for event in events:
    if event.type == "response.output_text.delta":
        print(event.delta, end="")
    elif event.type == "response.completed":
        print(event.response.usage)
Function tool
{
  "model": "openai/gpt-4o-mini",
  "input": "Какая погода в Казани?",
  "tools": [{
    "type": "function",
    "name": "get_weather",
    "description": "Возвращает погоду в городе",
    "parameters": {
      "type": "object",
      "properties": {"city": {"type": "string"}},
      "required": ["city"],
      "additionalProperties": false
    },
    "strict": true
  }],
  "parallel_tool_calls": true
}
Результат функции и полная история
{
  "model": "openai/gpt-4o-mini",
  "input": [
    {
      "type": "message",
      "role": "user",
      "content": [{"type": "input_text", "text": "Какая погода в Казани?"}]
    },
    {
      "type": "function_call",
      "id": "fc_1",
      "call_id": "call_1",
      "name": "get_weather",
      "arguments": "{\"city\":\"Казань\"}"
    },
    {
      "type": "function_call_output",
      "call_id": "call_1",
      "output": "{\"temperature_c\":18}"
    }
  ],
  "tools": [{
    "type": "function",
    "name": "get_weather",
    "parameters": {
      "type": "object",
      "properties": {"city": {"type": "string"}},
      "required": ["city"],
      "additionalProperties": false
    }
  }]
}
Reasoning и JSON Schema — Python
response = client.responses.create(
    model="google/gemini-2.5-flash",
    input="Извлеки название и год: Python появился в 1991 году.",
    reasoning={"effort": "high"},
    text={"format": {
        "type": "json_schema",
        "name": "language",
        "strict": True,
        "schema": {
            "type": "object",
            "properties": {
                "name": {"type": "string"},
                "year": {"type": "integer"},
            },
            "required": ["name", "year"],
            "additionalProperties": False,
        },
    }},
)
Изображение
{
  "model": "google/gemini-2.5-flash",
  "input": [{
    "type": "message",
    "role": "user",
    "content": [
      {"type": "input_text", "text": "Что изображено?"},
      {
        "type": "input_image",
        "image_url": "https://cdn.example.com/photo.webp",
        "detail": "auto"
      }
    ]
  }]
}
Usage
{
  "input_tokens": 43,
  "input_tokens_details": {"cached_tokens": 8},
  "output_tokens": 29,
  "output_tokens_details": {"reasoning_tokens": 17},
  "total_tokens": 72
}

Ошибки

Обычные ошибки возвращаются в формате:

{ "error": "описание ошибки" }
КодОписание
400Невалидный JSON, неизвестная модель или некорректные параметры
401Отсутствует или неверный API-ключ
402Недостаточно средств на балансе
403Email не подтверждён либо запрошенная маршрутизация запрещена политикой
413Тело запроса или декодированные мультимодальные данные превышают лимит
429Исчерпан бюджет Guardrails; срок ожидания указан в Retry-After
500Внутренняя ошибка сервиса
502Маршрут обработки недоступен, вернул нечитаемый ответ или не завершил поток

Биллинг и цены

Баланс и все расчёты ведутся в копейках (1 рубль = 100 копеек).

Как считается стоимость

  • Текстовые модели — цена за 1 000 000 токенов, отдельно для входных (prompt) и выходных (completion) токенов. Актуальные цены для каждой модели показаны на странице Модели.
  • Модели генерации изображений — фактическая стоимость провайдера; при отсутствии usage.cost применяется синхронизированный image-тариф совместимого endpoint.

Пример расчёта

Модель: openai/gpt-4o-mini

Ввод: 1 500 коп. / 1M токенов, Вывод: 6 000 коп. / 1M токенов

Запрос: 5 000 входных + 2 000 выходных токенов

Стоимость: (5000 / 1M × 1500) + (2000 / 1M × 6000) = 7.5 + 12 = 19.5 коп. ≈ 20 коп.

Отслеживание расходов

В личном кабинете доступны детальная помесячная аналитика и логи каждого запроса с разбивкой по модели, токенам и стоимости.

SDK и клиенты

Ocelotiq совместим с любым OpenAI-совместимым SDK или HTTP-клиентом. Достаточно заменить base_url на https://ai.ocelotiq.ru/v1.

Py

Python — openaipip install openai

JS

Node.js — openainpm install openai

LC

LangChainChatOpenAI(openai_api_base="https://ai.ocelotiq.ru/v1", ...)

cU

cURL / HTTPЛюбой HTTP-клиент с JSON-запросами

Лимиты

  • Максимальное количество API-ключей на аккаунт не ограничено.
  • Запросы ограничены вашим балансом — пока есть средства, можно делать запросы.
  • Тело Chat Completions ограничено 96 MiB; отдельные мультимодальные лимиты приведены в разделе «Мультимодальный ввод».
  • Контекстное окно и дополнительные media-ограничения зависят от выбранной модели и маршрута обработки.
  • Ошибка 502 означает, что маршрут недоступен или не вернул корректный завершённый ответ.
Автоматический failover: при ошибке маршрута Ocelotiq автоматически использует следующий доступный вариант.

Остались вопросы? Пишите на admin@ocelotiq.ru