Документация
Быстрый старт
- 1. Зарегистрируйтесь
- 2. Пополните баланс и создайте API-ключ в кабинете.
- 3. Подставьте ключ в сниппет ниже и выполните запрос.
curl https://apimira.com/v1/chat/completions \
-H "Authorization: Bearer am-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-5.4-mini",
"messages": [
{
"role": "user",
"content": "Привет!"
}
]
}'Выберите модель — её ID подставится в код сам, вместе с нужным эндпоинтом. Подсветкой отмечено единственное место, куда идёт ваш ключ: создайте его в кабинете, в разделе «API-ключи», и замените им заглушку.
| Base URL / Endpoint | https://apimira.com/v1 |
|---|---|
| API-ключ | am-ВАШ_КЛЮЧ |
| Model ID | openai/gpt-5.4-mini |
base_url — это адрес выше с суффиксом /v1. Модель задаётся параметром model.
Model ID берётся из каталога целиком, вместе с префиксом до «/»: например google/gemini-3.7-flash или anthropic/claude-sonnet-4.6.
Подключение программ
Любая программа с OpenAI-совместимым API подключается тремя значениями (Claude Code и Anthropic SDK — исключение, у них свой протокол; смотрите карточку ниже):
| Base URL / Endpoint | https://apimira.com/v1 |
|---|---|
| API-ключ | am-ВАШ_КЛЮЧ |
| Model ID | openai/gpt-5.4-mini |
Если поле называется просто «Base URL» — путь /chat/completions программа добавит сама, дописывать его не нужно. И следите, чтобы в адресе не получилось /v1/v1.
Быстрая проверка ключа без программы — выполните запрос из блока «Быстрый старт» выше.
Что шлюз принимает, а что отвергает
Строгий JSON-режим (response_format), снятый с производства формат functions и параметры аудио-вывода (audio, modalities) шлюз отклоняет ошибкой unsupported_parameter. Картинки на вход работают у моделей с пометкой «Видит картинки»: картинка передаётся частью content типа image_url со ссылкой data:image/png;base64,… Внешние ссылки шлюз не скачивает, модель без этой способности отвечает ошибкой unsupported_capability, а звук на вход не поддерживается вовсе. Ни один из этих случаев не проходит молча: вы не платите за ответ, полученный не по тем правилам. Вызов функций работает: до 128 инструментов в запросе, вызовы приходят и обычным ответом, и потоком. Обычная переписка и потоковая выдача работают на всех моделях каталога.
Редакторы кода: Cursor, Cline, Roo Code, Kilo Code
В настройках провайдера выберите «OpenAI Compatible» и заполните три поля выше. Агентные режимы, где расширение само читает и правит файлы, работают: шлюз поддерживает вызов функций. У Cursor адрес задаётся в Settings → Models, поле «Override OpenAI Base URL», ключ — там же; свой ключ действует в чате и агенте, а Tab и подсказки прямо в коде остаются на моделях Cursor. Если список моделей не подгрузился, впишите Model ID вручную.
SillyTavern
API Connections → Chat Completion → Source: Custom (OpenAI-compatible). В Custom Endpoint укажите Base URL, ниже — ключ и Model ID. Если чат работает, а проверка статуса нет — включите Bypass API status check.
n8n
Создайте OpenAI-креденшл, в поле Base URL укажите наш адрес с /v1 и вставьте ключ. В AI-узле выберите модель по полному Model ID. Узел AI Agent тоже работает: он опирается на вызов функций, а шлюз его поддерживает.
Janitor AI
В настройках прокси укажите Proxy URL (Base URL с /v1), API Key и Model. Путь /chat/completions Janitor добавляет сам. Сначала сохраните конфигурацию прокси, затем настройки персонажа.
OpenCode
Откройте ~/.config/opencode/opencode.json, добавьте провайдера конфигом ниже, запустите opencode и выберите модель командой /models.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"ApiMira": {
"npm": "@ai-sdk/openai-compatible",
"name": "ApiMira",
"options": {
"baseURL": "https://apimira.com/v1",
"apiKey": "am-ВАШ_КЛЮЧ"
},
"models": {
"openai/gpt-5.4-mini": { "name": "GPT-5.4 Mini" },
"anthropic/claude-sonnet-4.6": { "name": "Claude Sonnet 4.6" }
}
}
}
}Claude Code и Anthropic SDK
Подключаются по нативному эндпоинту Anthropic — POST /v1/messages, max_tokens обязателен. Ключ шлюз принимает и в заголовке Authorization: Bearer, и в x-api-key. Адрес шлюза указывайте без /v1 — Claude Code сам дописывает путь, а лишний /v1 даст 404. count_tokens отвечает оценкой числа токенов, а не точным значением, а поле cache_control шлюз принимает, но игнорирует: разметка кэша вручную не поддерживается. При этом кэш работает автоматически у моделей, для которых на странице «Модели» указана ставка кэш-входа: если начало запроса совпадает с предыдущим, эти токены считаются по льготной ставке, а их число приезжает в usage.cache_read_input_tokens. Подробная инструкция с переменными окружения — в разделе «Инструменты».
Чат — генерация ответа
POST /v1/chat/completions
Генерация ответа модели. Поддерживает stream=true (SSE). Формат запроса и ответа — как у OpenAI.
Стриминг: передайте "stream": true. Чанки приходят в формате data: {...} и завершаются data: [DONE].
Поддержано: текстовый чат (включая вызовы инструментов через tools и tool_choice), картинки на вход у моделей с такой способностью, генерация и редактирование изображений, генерация видео. В чате response_format, functions, audio и modalities по-прежнему отвечают 400 — параметр не игнорируется молча.
Параметры запроса
Тело POST /v1/chat/completions. Обязательны только model и messages — всё остальное можно не передавать, у каждого поля есть разумное значение по умолчанию.
| Поле | Тип | Что делает |
|---|---|---|
| modelобязательно | string | ID модели из каталога — целиком, вместе с префиксом до «/». |
| messagesобязательно | array | Переписка списком: у каждого сообщения role (system, user, assistant, tool) и content. Модель не помнит прошлые запросы — всю нужную историю присылайте здесь. |
| stream | boolean | true — ответ идёт потоком по мере генерации. Куски приходят строками data: {…}, конец потока — data: [DONE]. |
| temperature | 0 … 2 | Разброс ответов: ниже — предсказуемее и суше, выше — свободнее и разнообразнее. |
| top_p | 0 … 1 | Другой способ управлять разбросом. Меняйте что-то одно — либо temperature, либо top_p. |
| max_tokens | ≥ 1 (max 32 000) | Потолок длины ответа; больше 32 000 шлюз урезает до 32 000. Влияет на размер брони — см. «Цены и списания». |
| max_completion_tokens | ≥ 1 (max 32 000) | То же самое под новым именем OpenAI. Если пришли оба, действует max_completion_tokens. |
| stop | string | string[] | До четырёх строк, на которых генерация обрывается. Сама строка в ответ не попадает. |
| stream_options | object | {"include_usage": true} добавит счётчик токенов в последний кусок потока. |
| tools | array (≤ 128) | Описания функций, которые модель может вызвать. Вызовы приходят в choices[].message.tool_calls. |
| tool_choice | string | object | none — не вызывать, auto — на усмотрение модели, required — вызвать обязательно, объект — вызвать конкретную функцию. |
| user | string | Ваш собственный идентификатор конечного пользователя. Передаётся как есть и на цену не влияет. |
Эти параметры шлюз отклоняет
functions, response_format, audio, modalities — ответ 400 с кодом unsupported_parameter. Отказ намеренный: молча проигнорировать параметр и выставить счёт за ответ, полученный не по вашим правилам, хуже честной ошибки.
Что приходит в ответе
Формат совпадает с OpenAI, поэтому официальные SDK разбирают его без переделок.
| Поле | Тип | Что делает |
|---|---|---|
| id | string | Идентификатор запроса. Его стоит приложить к обращению в поддержку. |
| model | string | ID модели, которая ответила. |
| choices[].message.content | string | null | Текст ответа. null, если модель вместо текста вызвала инструмент. |
| choices[].message.tool_calls | array | Вызовы функций, если модель их сделала. |
| choices[].finish_reason | string | Почему генерация закончилась: stop — модель договорила, length — упёрлась в max_tokens, tool_calls — зовёт инструмент. |
| usage.prompt_tokens | number | Входные токены — по ним считается первая половина счёта. |
| usage.prompt_tokens_details.cached_tokens | number | Сколько входных токенов пришло из кэша — они уже входят в prompt_tokens; у моделей со ставкой кэш-входа посчитаны по льготной ставке. |
| usage.completion_tokens | number | Выходные токены — вторая половина счёта. |
| usage.total_tokens | number | Сумма входных и выходных. |
Картинки на вход
Модель, которая умеет смотреть на картинки, принимает их прямо в переписке: скриншот ошибки, фото чека, макет. Отдельного эндпоинта не нужно — картинка едет частью сообщения рядом с текстом, тем же POST /v1/chat/completions. То же самое работает на /v1/messages и /v1/responses.
Как передать картинку
В сообщении роли user поле content становится массивом частей: текст — часть типа text, картинка — часть типа image_url, у которой url это строка вида data:image/png;base64,… — тип картинки и её байты в base64. Порядок частей сохраняется: модель видит их в том порядке, в котором вы прислали. Поле detail (auto, low, high) передаётся модели как есть. Сообщение может состоять из одних картинок, без текста.
{
"role": "user",
"content": [
{ "type": "text", "text": "Что написано на этом скриншоте?" },
{
"type": "image_url",
"image_url": { "url": "data:image/png;base64,iVBORw0KGgo…", "detail": "auto" }
}
]
}Внешние ссылки шлюз не скачивает: картинка по http или https возвращает 400 invalid_request с подсказкой. Кодируйте файл в base64 сами — это одна строка в любом языке.
curl https://apimira.com/v1/chat/completions \
-H "Authorization: Bearer am-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"model": "anthropic/claude-sonnet-5",
"messages": [{ "role": "user", "content": [
{ "type": "text", "text": "Что написано на этом скриншоте?" },
{ "type": "image_url", "image_url": { "url": "data:image/png;base64,'"$(base64 -w0 shot.png)"'" } }
]}]
}'Пределы
- — Форматы: PNG, JPEG, WebP. Тип проверяется по первым байтам файла, а не по названию: «png» с чем-то другим внутри возвращает 400 у нас, не доходя до модели.
- — Одна картинка — до 5 МБ двоичных данных; в base64 тот же файл занимает примерно на треть больше.
- — До 50 картинок на запрос — считаются все картинки переписки, а не только последнего сообщения.
- — Тело запроса с картинками — до 24 МБ. Этот предел главнее числа картинок: 50 штук пройдут только мелкими.
- — Тело больше 2 МБ читается только по действующему ключу с положительным балансом, и на загрузку даётся 30 с — дальше 408 request_timeout с заголовком Retry-After. Число одновременных крупных загрузок ограничено: следующая получает 429 с Retry-After, повторите её через указанное время.
- — Больше 20 картинок в одном запросе часть моделей принимает только мелкими — до 2000 px по большей стороне.
Какие модели видят картинки
Способность проверена живой пробой, а не обещанием: сегодня картинки принимают 38 моделей каталога. У них же стоит пометка «Видит картинки» на странице «Модели», а GET /v1/account/pricing отдаёт их в поле capabilities. Модель без этой способности отвечает 400 unsupported_capability и денег не берёт.
openai/gpt-6-astra · openai/gpt-5.6-sol · openai/gpt-5.6-terra · openai/gpt-5.6-luna · openai/gpt-5.5 · openai/gpt-5.4-mini · openai/gpt-5.3-codex · anthropic/claude-fable-5.1 · anthropic/claude-fable-5 · anthropic/claude-fable-5-compressed-context · anthropic/claude-opus-5 · anthropic/claude-opus-4.8 · anthropic/claude-opus-4.7 · anthropic/claude-opus-4.6 · anthropic/claude-opus-4.5 · anthropic/claude-sonnet-4.6 · anthropic/claude-sonnet-4.5 · anthropic/claude-haiku-4.5 · google/gemini-3.7-flash · google/gemini-3.6-flash · google/gemini-3.1-pro-preview · google/gemini-3.1-flash-lite · google/gemini-3-flash-preview · google/gemini-2.5-pro · x-ai/grok-4.6 · x-ai/grok-4.5 · x-ai/grok-4.3 · x-ai/grok-build-0.1 · z-ai/glm-5.3 · z-ai/glm-5.3-flash · z-ai/glm-5.1 · moonshotai/kimi-k3 · moonshotai/kimi-k2.7-code · moonshotai/kimi-k2.5 · qwen/qwen3.8-max · xiaomi/mimo-v2.5-pro · xiaomi/mimo-v2.5 · minimax/minimax-m3
Сколько стоит картинка
Картинка тарифицируется входными токенами модели. Сколько их — решает модель: обычно около 1 089 токенов за кадр 1024×1024, у отдельных моделей в разы больше. Списывается ровно то, что модель вернула в usage.prompt_tokens, — та же формула, что у текста. Под запрос резервируется оценка с запасом, лишнее возвращается на баланс (см. «Цены и списания»). Оценка того же порядка приходит в ответе POST /v1/messages/count_tokens.
Картинки от агентов
Картинка из результата инструмента — агент прочитал файл-картинку или сделал скриншот — тоже доходит до модели. В протоколе OpenAI результат инструмента несёт только текст, поэтому шлюз передаёт такие картинки отдельным пользовательским ходом сразу после серии результатов; порядок переписки при этом сохраняется. Настраивать ничего не нужно.
На /v1/responses картинка — часть input_image; значение detail: original приравнивается к high. На /v1/messages это блок image с source типа base64; source типа url шлюз не скачивает, как и в чате. Блоки document и file по-прежнему отвечают 400: файлы на вход мы пока не принимаем.
Отказы
400 invalid_request — не тот формат, байты не совпали с типом, превышен размер или число картинок, картинка в сообщении system, developer или assistant. 400 unsupported_capability — модель не принимает картинки. 400 context_length_exceeded — картинки вместе с текстом не влезают в контекст модели. 408 request_timeout — тело не пришло целиком за отведённое время. 413 payload_too_large — тело больше предела. Ни один из этих отказов не тарифицируется.
Приватность
Байты картинок нигде не сохраняются: они живут в памяти на время запроса и уходят модели. В статистике остаётся только их число — поле images_in в GET /v1/account/usage.
Генерация изображений
POST /v1/images/generations
POST /v1/images/generations — синхронно, тело и ответ совместимы с OpenAI Images. Списывается фиксированная цена за изображение, умноженная на количество (n).
curl https://apimira.com/v1/images/generations \
-H "Authorization: Bearer am-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"model": "openai/gpt-image-2",
"prompt": "a red cat wearing glasses",
"n": 1
}'Модель должна быть типа «изображение» (см. GET /v1/models). Ответ — массив data, в каждом элементе b64_json: кадр в base64. Ссылку мы не отдаём, даже если её дала модель, — кадр приезжает байтами. У потокенной модели в ответе есть usage: ровно те числа, по которым списано. Заголовок x-request-id в ответе — идентификатор записи списания, по нему запрос находится в GET /v1/account/usage.
Редактирование изображений
POST /v1/images/edits
POST /v1/images/edits меняет готовую картинку по текстовому описанию: заменить фон, дорисовать деталь, повторить стиль. Тело — multipart/form-data, как в OpenAI Images API: файл (или несколько) плюс prompt. Ответ — кадр в base64.
curl https://apimira.com/v1/images/edits \
-H "Authorization: Bearer am-ВАШ_КЛЮЧ" \
-F model=openai/gpt-image-2 \
-F prompt="Замени фон на светлый градиент" \
-F image=@cat.pngОтвет:
{
"created": 1757700000,
"data": [{ "b64_json": "iVBORw0KGgo…" }],
"usage": { "input_tokens": 116, "output_tokens": 1650, "total_tokens": 1766 }
}Формат кадра выбирает модель: одна отдаёт PNG, другая JPEG. Мы его не обещаем и не переделываем — читайте data[0].b64_json как байты картинки, а тип при необходимости определяйте по первым байтам.
Поле usage приходит не всегда: у модели с ценой за кадр его нет вовсе — платится кадр, а не токены. Разбивка input_tokens_details и output_tokens_details появляется только тогда, когда её дала модель: проверяйте наличие поля, а не рассчитывайте на него.
Поля запроса
| Поле | Тип | Что делает |
|---|---|---|
| modelобязательно | string | Модель типа «изображение» с поддержкой редактирования. Чат-модель отвечает 404 model_not_found, картиночная без этой способности — 400 unsupported_capability. |
| promptобязательно | string (≤ 4000) | Что сделать с картинкой. |
| imageобязательно | file × 1 … 4 | Файл: PNG, JPEG или WebP по первым байтам, до 5 МБ каждый. Одна картинка — поле image, несколько — image[] (так их шлёт SDK OpenAI), до 4 файлов в запросе. |
| n | 1 … 4 | Сколько кадров вернуть, по умолчанию один. Живой пробой проверен один кадр за запрос — на большем числе поведение моделей мы пока не мерили. |
| size | 1024x1024 | Только 1024x1024 или поле не задано — тогда размер выбирает модель. Другие значения возвращают 400: цена кадра зависит от размера. |
| response_format | b64_json | Только b64_json, это же значение по умолчанию. url возвращает 400 unsupported_parameter: хранилища у нас нет, и ссылку мы отдать не можем. |
Отвечаем 400 с именем поля
mask, output_format, output_compression, partial_images, stream со значением true, background: transparent, input_fidelity: high. Все они меняют байты результата или его цену у модели — проглотить их молча значило бы отдать не то, что заказано. Маска в этой версии не поддерживается ни у одной модели: присылайте картинку целиком.
Принимаем и модели не пересылаем
quality, user, background со значением opaque или auto, input_fidelity со значением low. Запрос с ними работает, но результат и цена остаются такими, как без них.
Цены и списания
Цена — как у генерации той же моделью, отдельного тарифа за правку нет. У потокенной модели считаются вход и выход по её ставкам, и usage в ответе показывает ровно те числа, по которым списано. У модели с ценой за кадр списывается цена кадра, умноженная на число кадров. Под запрос резервируется оценка с запасом, лишнее возвращается; сбой модели не стоит ничего.
Заголовок Content-Length обязателен: загрузка без него (chunked) возвращает 400 invalid_request. Если клиент шлёт файл потоком, прочитайте его в память или укажите размер сами.
В ответе есть заголовок x-request-id — идентификатор записи списания. По нему запрос находится в GET /v1/account/usage (поле id) и в кабинете; SDK OpenAI кладёт его в request_id.
Какие модели редактируют
Сегодня редактирование включено у 2 моделей каталога. У них стоит пометка «Редактирование» на странице «Модели», а GET /v1/account/pricing отдаёт способность image_edit в поле capabilities.
openai/gpt-image-2 · google/gemini-3.1-flash-image-preview
Генерация видео
POST /v1/videos/generations
Видео генерируется асинхронно: запрос создаёт задачу и сразу возвращает её id. Параметр seconds обязателен — это длительность ролика, от неё считается цена.
curl https://apimira.com/v1/videos/generations \
-H "Authorization: Bearer am-ВАШ_КЛЮЧ" \
-H "Content-Type: application/json" \
-d '{
"model": "alibaba/wan-2.6",
"prompt": "a paper boat drifting on a calm pond",
"seconds": 5
}'
# {"id": "9b2f…", "status": "processing", "created": 1755648000}GET /v1/jobs/{id}
Готовность опрашивайте раз в 5–10 секунд. status: processing — ещё идёт, succeeded — готово (в ответе url ролика), failed — не вышло (поле error). Генерация занимает от 30 секунд до 3 минут. Ссылка ведёт в хранилище поставщика — скачайте файл сразу после получения.
curl https://apimira.com/v1/jobs/JOB_ID \
-H "Authorization: Bearer am-ВАШ_КЛЮЧ"
# {"id": "9b2f…", "status": "succeeded", "url": "https://…/clip.mp4"}Списание = цена за секунду × seconds. Деньги резервируются при создании задачи и списываются только когда ролик готов; если генерация не удалась — резерв возвращается полностью.
Модели и длительности
| Модель | Секунды (seconds) | Разрешение | Звук |
|---|---|---|---|
| alibaba/wan-2.6 | 2–10 | 720p | есть |
| bytedance/seedance-2.0-fast | 4–15 | 720p | нет |
| bytedance/seedance-2.0 | 4–15 | 720p | нет |
| google/veo-3.1-fast | 4–8 | 1080p | нет |
| google/veo-3.1 | 4–8 | 1080p | нет |
Модель должна быть типа «видео» (см. GET /v1/models). Цены за секунду — на странице моделей.
Эндпоинты
POST /v1/chat/completions
Генерация ответа модели. Поддерживает stream=true (SSE). Формат запроса и ответа — как у OpenAI.
GET /v1/models
Список доступных моделей в формате OpenAI. Отключённые модели не возвращаются.
POST /v1/images/generations
Синхронная генерация изображений (OpenAI Images-совместимо). Кадр приходит в base64.
POST /v1/images/edits
Редактирование готовой картинки по описанию: multipart/form-data на входе, кадр в base64 на выходе.
POST /v1/videos/generations
Создание задачи генерации видео. Тариф посекундный, параметр seconds обязателен; ответ — задача со status processing.
GET /v1/jobs/{id}
Статус задачи генерации. processing — ещё идёт, succeeded — готово (в ответе url ролика), failed — не вышло (деньги не списаны).
POST /v1/messages
Родной протокол Anthropic — совместим с Claude Code и Anthropic SDK без переделок. Авторизация как у родных клиентов: заголовок x-api-key (Bearer тоже принимается). Стриминг (SSE) и вызовы инструментов поддержаны; max_tokens обязателен.
POST /v1/messages/count_tokens
Оценка числа входных токенов без обращения к модели — не точное число и не расходует баланс.
POST /v1/responses
Формат OpenAI Responses API — совместим с Codex CLI и SDK OpenAI без переделок. Stateless: историю шлёт клиент, previous_response_id не поддерживается, ответы по id не хранятся (GET и DELETE — 404). Инструменты function и стрим (SSE) поддержаны.
GET /v1/account/{balance,pricing,usage,analytics}
Read-only API аккаунта: баланс, розничные цены, детализация и аналитика ключа. Подробности — в разделе «Account API».
Цены и списания
Как это устроено
- — Баланс пополняется заранее — счетов в конце месяца и подписок нет.
- — За каждый запрос списывается его собственная стоимость: она зависит от модели и от количества токенов.
- — Баланс уменьшается сразу после ответа. Когда денег не хватает, запрос отвечает ошибкой 402 — в минус аккаунт не уходит.
Как считается стоимость
У каждой модели своя цена, указанная за 1 миллион токенов, — отдельно за вход (ваш запрос) и отдельно за выход (ответ модели). Выход почти всегда дороже входа. Актуальные цены всех моделей — в каталоге «Модели и цены».
вход = токены_входа / 1 000 000 × цена_входа выход = токены_выхода / 1 000 000 × цена_выхода ────────────────────────────────────────────────── итого = вход + выход
Каждая половина округляется вверх до одной миллионной доллара. Количество токенов берётся из ответа модели — то самое поле usage, которое вы видите в своём коде.
Пример расчёта
модель: openai/gpt-5.4-mini цена входа: $0.12 за 1M токенов цена выхода: $0.64 за 1M токенов запрос: 1 200 токенов входа, 800 токенов выхода вход 1 200 / 1 000 000 × $0.12 = $0.000144 выход 800 / 1 000 000 × $0.64 = $0.000512 ──────────────────────────────────────────────── списано: = $0.000656
Цены в примере не выдуманы — они подставляются из живого каталога, так же как в счёт.
Скидка за кэш
Если в начале запроса идёт тот же текст, что и в предыдущем — системный промпт, инструкции, длинный контекст, — модель берёт его из кэша, и мы считаем эти токены по льготной ставке. Включать ничего не нужно: кэш срабатывает сам, когда одинаковый префикс приходит подряд и он достаточно длинный (примерно от тысячи токенов). Первый запрос, который кладёт текст в кэш, не дорожает: он стоит ровно столько же, сколько без кэша.
вход = (токены_входа − токены_кэша) / 1 000 000 × цена_входа
+ токены_кэша / 1 000 000 × цена_кэш-входаСколько токенов пришло из кэша, видно в ответе: usage.prompt_tokens_details.cached_tokens, на эндпоинте /v1/messages — usage.cache_read_input_tokens. Те же числа лежат в кабинете, в GET /v1/account/usage и в выгрузке CSV. Ставка кэш-входа указана на странице «Модели» и в GET /v1/account/pricing. Скидка есть не у всех моделей: там, где ставка не указана, кэш считается по обычной цене входа.
Бронь на время запроса
Пока модель отвечает, никто не знает, каким длинным окажется ответ. Поэтому перед обращением к модели на балансе временно резервируется худший случай:
бронь = токены_входа / 1 000 000 × цена_входа
+ max_tokens / 1 000 000 × цена_выходаЕсли на бронь не хватает, запрос отклоняется сразу, ещё до обращения к модели. Когда ответ получен, списывается фактическая стоимость, а остаток брони возвращается на баланс в тот же момент.
тот же запрос, max_tokens: 4 000 забронировано: $0.002704 списано по факту: $0.000656 вернулось: $0.002048
Ставьте max_tokens близко к ожидаемой длине ответа: чем он больше, тем крупнее бронь и тем меньше баланса остаётся на параллельные запросы. Если max_tokens не задан, бронь считается по потолку в 32 000 токенов.
Когда денег не берут
Ошибка на стороне модели (502, 504) — списания нет, бронь возвращается целиком. Отклонённый запрос — неверный ключ, нехватка баланса, неподдерживаемый параметр, слишком большое тело — тоже бесплатен: до модели он не дошёл. Оценка токенов через /v1/messages/count_tokens бесплатна всегда.
Где смотреть расходы
В кабинете. На странице ключа — журнал запросов с моделью, токенами и стоимостью каждого, выгрузка в CSV и график по дням. В разделе «Расход» — сводка за период и разбивка по моделям. Тексты запросов и ответов мы не сохраняем: в статистике только эти счётчики.
Account API — баланс, цены и статистика ключа
Read-only API вашего аккаунта: баланс, розничные цены и usage ключа из собственного бэкенда — без захода в кабинет. Раздел кабинета «Управление аккаунтом» собирает базовый URL и готовые сниппеты.
Авторизация — тем же ключом, что и запросы к моделям: заголовок Authorization: Bearer. Разрешён только GET; ключ должен быть активен (пауза и отзыв дают 401). Не передавайте ключ в URL и не используйте в браузерном коде. Статистика считается в разрезе ключа, которым сделан запрос; баланс и цены общие для аккаунта.
GET /v1/account/balance60/мин
Текущий баланс аккаунта в долларах (активные резервы уже вычтены).
GET /v1/account/pricing30/мин
Розничные цены моделей из GET /v1/models: за 1M токенов (вход, кэш-вход, выход) или за единицу генерации (у видео — за секунду). Поле capabilities называет способности модели машиночитаемо: vision — принимает картинки на вход, image_edit — редактирует изображения. Себестоимость и маржа не выдаются.
GET /v1/account/usage20/мин
Построчная детализация запросов ключа: модель, операция, статус, токены (отдельно — сколько из них пришло из кэша), число картинок во входе (images_in), списание, задержка и снапшоты цен на момент запроса. Новые сверху.
GET /v1/account/analytics10/мин
Агрегаты ключа за период: totals, разрез по моделям и дням (UTC), ошибки шлюза по кодам.
Параметры query
Все параметры необязательны. Значение за границами — 400 invalid_request с именем параметра в param.
| Поле | Тип | По умолчанию | Что делает |
|---|---|---|---|
| daysusage · analytics | 1 … 90 | 30 | Окно выборки в днях, от текущего момента назад. |
| limitusage | 1 … 100 | 50 | Размер страницы детализации. |
| pageusage | 0 … 200 | 0 | Номер страницы, с нуля. has_more в ответе говорит, есть ли следующая. |
Примеры
curl https://apimira.com/v1/account/balance \
-H "Authorization: Bearer am-ВАШ_КЛЮЧ"
# {"object": "account.balance", "balance_usd": 4.981234, "currency": "USD"}curl "https://apimira.com/v1/account/usage?days=7&limit=25" \ -H "Authorization: Bearer am-ВАШ_КЛЮЧ"
Ответ:
{
"object": "list",
"days": 7,
"limit": 25,
"page": 0,
"has_more": false,
"data": [
{
"id": "9b2f…",
"created_at": "2026-08-21T09:58:12.000Z",
"model": "openai/gpt-5.4-mini",
"operation": "chat",
"status": "success",
"tokens_in": 1200,
"cached_tokens_in": 0,
"images_in": 0,
"tokens_out": 800,
"cost_usd": 0.000656,
"price_input_usd_per_1m_tokens": 0.12,
"price_cached_input_usd_per_1m_tokens": 0.0168,
"price_output_usd_per_1m_tokens": 0.64,
"price_generation_usd": null,
"latency_ms": 812
}
]
}Ответ /v1/account/analytics — один объект с полями:
totals · models[] · daily[] · errors.by_code[]
Приватность
В детализации — только метаданные. Тела промптов и ответов не сохраняются вообще, поэтому не могут быть выданы ни по API, ни как-либо ещё. IP и данные клиента тоже не выдаются.
Ошибки
Конверт ошибок общий для всего шлюза (см. раздел «Ошибки»). Здесь встречаются:
401 invalid_api_key · 400 invalid_request · 429 rate_limited
Лимиты и ограничения
Лимиты защищают и вас, и шлюз: случайный цикл в коде не должен выжигать баланс за минуту.
| Ограничение | Значение |
|---|---|
| Частота запросов на один ключ | 60 подряд, дальше 10 в секунду |
| Размер тела запроса: чат и /v1/messages | 2 МБ |
| Размер тела запроса с картинками: чат, /v1/messages, /v1/responses, правка изображений | 24 МБ |
| Размер тела запроса: изображения, видео, музыка | 256 КБ |
| Длина запроса — все сообщения и схемы инструментов вместе | 400 000 символов |
| Максимум токенов в ответе (max_tokens) | 32 000 токенов |
| Инструментов в одном запросе | 128 |
| Стоп-последовательностей | 4 |
| Лимит расходов на ключ: день, неделя, месяц | задаёте сами |
| Расписание ключа: часы и дни, когда он работает | задаёте сами |
Превышение частоты — это 429 rate_limited: подождите и повторите, ключ не блокируется и не штрафуется. Тело больше 2 МБ читается только по действующему ключу с положительным балансом: на загрузку даётся 30 с, а число одновременных крупных загрузок ограничено — лишняя получает 429 с заголовком Retry-After. Лимит расходов и расписание вы задаёте сами в кабинете на странице ключа. Перебор неверных ключей с одного адреса дополнительно замедляется.
Коды ошибок
Все ошибки приходят в одном формате — таком же, как у OpenAI, поэтому SDK разбирают их сами:
{
"error": {
"message": "The model `openai/gpt-9` does not exist or is disabled.",
"type": "invalid_request_error",
"code": "model_not_found",
"param": "model"
}
}Опирайтесь на code: он машиночитаемый и не меняется. Текст message написан для человека и со временем может стать другим. Поле param указывает на конкретное поле запроса, если ошибка в нём.
| HTTP | code | Когда возникает | Что делать |
|---|---|---|---|
| 400 | invalid_request | Тело запроса не разобралось: не тот JSON, нет обязательного поля или значение вне допустимых границ. | Сверьтесь с разделом «Параметры запроса»: в поле param указано, что именно не подошло. |
| 400 | unsupported_parameter | В запросе параметр, который шлюз пока не поддерживает. | Уберите параметр из запроса — список несовместимых в разделе «Параметры запроса». |
| 400 | unsupported_capability | Модель не умеет то, что просит запрос: картинку на вход или редактирование изображения. | Возьмите модель с нужной пометкой на странице «Модели» или по полю capabilities в GET /v1/account/pricing. Запрос не тарифицирован. |
| 400 | context_length_exceeded | Запрос не влезает в контекст модели — переписка, картинки и схемы инструментов вместе. | Сократите переписку или число картинок либо возьмите модель с большим контекстом — он указан на странице «Модели». |
| 401 | invalid_api_key | Ключ неверен, отозван или не передан. | Проверьте, что ключ скопирован целиком, вместе с префиксом am-, и не отозван в кабинете. |
| 402 | insufficient_balance | Баланс закончился — пополните в кабинете. | Пополните баланс. Уменьшить max_tokens тоже помогает — бронь станет меньше. |
| 403 | key_schedule_blocked | Ключ вне разрешённого расписания. Настройте расписание в кабинете (/app/keys). | Измените расписание ключа в кабинете или возьмите другой ключ. |
| 404 | model_not_found | Модель не существует или отключена. См. GET /v1/models. | Возьмите ID из GET /v1/models целиком, вместе с префиксом до «/». |
| 404 | job_not_found | Задачи генерации с таким id нет. | Проверьте id из ответа на создание задачи. |
| 404 | not_found | По этому адресу ничего нет. Ответы /v1/responses не хранятся — получить или удалить их по id нельзя. | Проверьте адрес. Историю диалога держите на клиенте и шлите полный input каждым запросом. |
| 408 | request_timeout | Тело запроса не пришло целиком за отведённое время. | Повторите запрос: через сколько, говорит заголовок Retry-After. На медленном канале уменьшите размер картинок. |
| 413 | payload_too_large | Тело запроса слишком большое. | Сократите переписку или разбейте её на несколько запросов. |
| 429 | rate_limited | Слишком много запросов с этого ключа — подождите и повторите. Частота выравнивается автоматически. | Подождите и повторите. Помогает пауза, растущая с каждой попыткой. |
| 429 | spend_limit_exceeded | Достигнут лимит расходов ключа. Поднимите или снимите его в кабинете (/app/keys). | Поднимите или снимите лимит в кабинете, на странице ключа. |
| 500 | internal_error | Сбой на нашей стороне. | Повторите запрос. Если повторяется — напишите в поддержку и приложите id из ответа. |
| 502 | provider_not_configured | У модели нет рабочего маршрута к поставщику. | Выберите другую модель и сообщите нам: такой ошибки быть не должно. |
| 502 | upstream_error | Ошибка провайдера модели. Списания за такой запрос нет. | Повторите запрос или попробуйте другую модель. Деньги за него не списаны. |
| 504 | upstream_timeout | Поставщик модели не ответил вовремя. | Повторите запрос. Для длинных ответов включайте stream — поток не упирается в таймаут. |
Ни одна ошибка из таблицы не тарифицируется. Если запрос не дошёл до модели или модель ответила ошибкой, деньги не списываются, а бронь возвращается на баланс целиком.
Частые вопросы
Как сменить модель?
Измените значение параметра model. Остальной код не трогаете — запрос уйдёт к нужному провайдеру.
Работает ли официальный OpenAI SDK?
Да. Укажите base_url на наш адрес с /v1 и наш ключ — остальной код остаётся прежним.
Как считается стоимость?
По токенам входа и выхода, по цене модели на момент запроса. Разбор с формулой и примерами — в разделе «Цены и списания».
Есть ли лимиты запросов?
Да. Частотный лимит на каждый ключ и настраиваемые вами лимиты расходов в деньгах. Все числа — в разделе «Лимиты».