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

Подключение к Chat Completions, параметры запросов и учёт расходов.

Адрес и ключ

API совместим с OpenAI Chat Completions: подходят OpenAI SDK и любые программы, в которых можно указать адрес OpenAI-совместимого API.

Base URL
https://artaill.ru/api/gateway/v1
Авторизация
Authorization: Bearer … с API-ключом

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

Пути указаны относительно Base URL.

POST /chat/completions
Ответ модели целиком (JSON) или потоком (SSE).
GET /models
Модели, доступные ключу; GET /models/{id} — одна модель.

Цены — на странице моделей. Каталог в JSON с ролями сообщений и параметрами каждой модели — /api/gateway/catalog, ключ для него не нужен.

Замена ключа и месячный бюджет

Потерянный ключ восстановить нельзя: создайте новый и отзовите прежний. Отозванный ключ не принимает новые запросы; уже принятые завершаются и оплачиваются.

Месячный бюджет ограничивает расходы ключа за календарный месяц по UTC, включая текущие резервы. Пустое поле — без ограничения, 0 запрещает расход.

Первый запрос

Выберите модель, разрешённую вашему ключу.

Загружаем примеры…

Текст ответа — в choices[0].message.content, число токенов — в usage. Стоимость запроса видна в журнале запросов.

Основные поля JSON-ответа
{
  "choices": [{
    "index": 0,
    "message": {"role": "assistant", "content": "Привет! Чем помочь?"},
    "finish_reason": "stop"
  }],
  "usage": {
    "prompt_tokens": 12,
    "completion_tokens": 8,
    "total_tokens": 20
  }
}

finish_reason: "length" — ответ достиг предела вывода, "content_filter" — сработала фильтрация. В обоих случаях текст или JSON могут быть оборваны.

Справочники SDK: Python и JavaScript / TypeScript.

Параметры

Историю диалога хранит и передаёт ваше приложение. Artaill не сохраняет тексты запросов и ответов; правила обработки у поставщика модели могут отличаться — подробнее в политике конфиденциальности.

model
Обязательный. ID модели из каталога.
messages
Обязательный. Массив сообщений с role и content; допустимые роли зависят от модели.
max_tokens или max_completion_tokens
Предел вывода в токенах, от 1 до максимума модели; укажите только один из двух. По умолчанию — значение из каталога.
stream
true — ответ потоком SSE, по умолчанию false. Чтобы получить usage в потоке, добавьте stream_options: {"include_usage": true}.

У моделей с рассуждениями в предел вывода могут входить токены рассуждений: при слишком маленьком пределе ответ может остаться без текста. Вход вместе с пределом вывода должен помещаться в контекст модели.

Неизвестный или не поддерживаемый моделью параметр отклоняется с ошибкой 400 до вызова модели; такой запрос не оплачивается.

Дополнительные параметры

Модели поддерживают разные наборы параметров; список для каждой — в JSON-каталоге. Если параметр не указан, действует настройка провайдера.

temperature, top_p
Числа от 0 до 2 и от 0 до 1 соответственно.
presence_penalty, frequency_penalty
Числа от −2 до 2.
stop
Строка или массив из 1–4 строк остановки.
reasoning_effort
Строка из списка уровней рассуждений модели.
seed, logit_bias
Целое число; объект с ID токенов и смещениями от −100 до 100.
logprobs, top_logprobs
logprobs: true включает вероятности токенов. top_logprobs — целое число от 0 до 20, только вместе с ним.
n
Только 1.
store
Только false.

Изображения, JSON, функции

Изображения принимают не все модели — это видно в каталоге. Поддержку response_format и tools показывает JSON-каталог.

Изображения на входе

Сообщение пользователя может быть массивом частей с текстом и изображениями. Изображение передаётся ссылкой HTTPS, доступной провайдеру, или data URL вида data:image/png;base64,….

{
  "messages": [{
    "role": "user",
    "content": [
      {"type": "text", "text": "Что изображено на фото?"},
      {"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}}
    ]
  }]
}

До 8 изображений в запросе. В base64 принимаются PNG, JPEG, WebP и GIF, суммарно до 10 MiB до кодирования. В image_url можно задать detail: "auto", "low" или "high".

Ответ по JSON Schema

Добавьте в запрос response_format со схемой и опишите в сообщении, какие данные нужны. Например, краткий пересказ:

{
  "response_format": {
    "type": "json_schema",
    "json_schema": {
      "name": "summary",
      "strict": true,
      "schema": {
        "type": "object",
        "properties": {"summary": {"type": "string"}},
        "required": ["summary"],
        "additionalProperties": false
      }
    }
  }
}

JSON приходит строкой в message.content. Перед разбором проверьте finish_reason и отказ в message.refusal. Какие конструкции схемы поддерживаются, зависит от модели. Для JSON без схемы укажите {"type": "json_object"} и явно попросите JSON в сообщении.

Вызов функций

Опишите функции в tools. Например, получение статуса заказа:

{
  "tools": [{
    "type": "function",
    "function": {
      "name": "get_order_status",
      "description": "Узнать статус заказа по номеру",
      "parameters": {
        "type": "object",
        "properties": {"order_id": {"type": "string"}},
        "required": ["order_id"],
        "additionalProperties": false
      }
    }
  }],
  "tool_choice": "auto"
}

При finish_reason: "tool_calls" вызовы приходят в message.tool_calls; функции выполняет ваш код. В следующий запрос добавьте полученное сообщение assistant целиком и результат каждого вызова с его ID:

{"role": "tool", "tool_call_id": "ID из tool_calls", "content": "{\"status\":\"shipped\"}"}

tool_choice принимает "auto", "none", "required" или {"type":"function","function":{"name":"get_order_status"}}. parallel_tool_calls: false запрещает несколько вызовов в одном ответе. Эти параметры тоже должны поддерживаться моделью. Каждый запрос в цепочке вызовов оплачивается отдельно.

Потоковый ответ

Пример — в первом запросе, вариант «Поток · SSE».

Успешный поток заканчивается строкой data: [DONE]. С include_usage перед ней приходит отдельное событие с choices: [] и usage — уже после finish_reason, поэтому читайте поток до конца. Если провайдер не сообщил полный отчёт о токенах, usage равен null.

Ошибка после начала потока приходит событием data: {"error": {...}}, затем соединение закрывается без [DONE]. HTTP-статус к этому моменту уже 200, поэтому успешное завершение определяет только [DONE].

Если читаете SSE без SDK

Текст приходит в choices[0].delta.content, фрагменты вызовов функций — в delta.tool_calls: собирайте их по index и разбирайте function.arguments как JSON, когда вызов завершён. Строки, начинающиеся с :, — комментарии.

Ограничения

Одновременные запросы
До 2 выполняющихся запросов на аккаунт, включая ответы в чате Artaill. Очереди нет: запрос сверх лимита получает 429.
Частота
До 60 запросов в минуту на ключ и 120 на аккаунт, считая все запросы с ключом.
Размер запроса
JSON — до 16 MiB; текст, включая описания функций и схемы, — до 1 MiB; до 512 сообщений. Контекст и предел вывода у каждой модели свои.

429 также возможен при общей нагрузке на сервис. Заголовок Retry-After, если он есть, указывает, через сколько секунд повторить запрос.

Ошибки

Ошибка до начала ответа приходит с HTTP-статусом и JSON-объектом error с полями code, type, message и param. Обрабатывайте ошибки по code: текст message может меняться.

400 / 413
Неверный или неподдерживаемый параметр, слишком большой запрос. Без исправления повтор не поможет.
401
Ключ неверен, отозван или истёк.
402
insufficient_balance — не хватает средств на балансе; key_budget_exceeded — бюджета ключа; key_reservation_exceeded — резерв больше предела ключа на один запрос. Резерв считается по входу и пределу вывода, их уменьшение его снижает.
403
model_not_allowed — модель не разрешена ключу; cross_origin_denied — запрос из браузера с другого сайта.
404
Модель или запрос не найдены.
409
request_already_accepted — запрос с этим Idempotency-Key уже принят. Ответ содержит его ID и ссылку на состояние.
429
Превышена частота или число одновременных запросов. Повторите позже, с учётом Retry-After.
5xx
Ошибка или тайм-аут модели, временная недоступность сервиса. Запрос мог дойти до модели и быть оплачен: перед повтором проверьте его состояние. accounting_pending — расчёт ещё не завершён.

Повторы и расходы

Ответ на принятый запрос содержит заголовок X-Request-ID. По этому ID состояние и стоимость запроса видны в журнале и через GET /api/gateway/requests/{id} с тем же API-ключом. Текст ответа там не хранится.

Работа модели оплачивается и при ошибке или обрыве соединения. Без заголовка Idempotency-Key каждый POST — новый вызов модели, поэтому повторы SDK в примерах отключены. После сбоя сначала проверьте состояние запроса.

Idempotency-Key защищает от повторного выполнения: передайте уникальное значение для каждой операции, от 1 до 128 печатных ASCII-символов без пробелов. Значение действует 24 часа с момента принятия запроса, даже если тот завершился ошибкой. Повтор с тем же значением и API-ключом модель не вызывает: сервис вернёт 409 с request_id и status_url в JSON и заголовком Location. Тело запроса не сравнивается, прежний ответ не возвращается.

Расчёт стоимости

Цены указаны за миллион токенов, оплачивается фактическое число токенов. Цена за запрос, если она есть, добавляется к стоимости токенов. Чтение и запись кэша оплачиваются по своим тарифам, когда модель сообщает эти данные.

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

Предел резерва и месячный бюджет проверяются при принятии запроса и не ограничивают итоговую цену: она может превысить резерв. Если модель не сообщила полный отчёт о токенах, стоимость считается по оценке.

В метаданных запроса price_rub — полная цена, charged_rub — списано с баланса, held_rub — ещё удерживается. Пока accounting: "pending", нулевое списание не значит, что запрос бесплатный — дождитесь расчёта. Цена по оценке помечена estimated, основание — в basis.