Как устроен API
На этой странице
AI Creator API — прокси между твоим инструментом и провайдером модели. Он проверяет ключ и лимиты, резервирует деньги на балансе, передаёт запрос провайдеру и возвращает его ответ. Тело запроса уходит как есть; меняется только имя модели, если это алиас.
Три протокола#
Мы отвечаем по трём протоколам. Какой нужен, решает инструмент, а не ты:
| Протокол | Запрос | Кто пользуется |
|---|---|---|
| Anthropic Messages | POST /v1/messages | Claude Code, Anthropic SDK |
| OpenAI Responses | POST /v1/responses | Codex CLI, OpenAI SDK |
| OpenAI Chat Completions | POST /v1/chat/completions | Cline, OpenCode, Aider, OpenAI SDK |
Один протокол в другой мы не переводим. Запрос к модели по протоколу, на котором её нет, вернёт 400 model_not_available. Форматы запросов и ответов — как у официальных API Anthropic и OpenAI; все пути и заголовки — в справочнике API.
Адрес для клиентов Anthropic — https://api.aicreator.app, для клиентов OpenAI — https://api.aicreator.app/v1. Для России есть второй адрес того же API — https://api-ru.aicreator.app: ключи, пути и баланс общие.
Имена моделей и алиасы#
В поле model мы принимаем только имена из своего списка — они перечислены в разделе «Модели и цены», а для своего ключа их отдаёт GET /v1/models. Имя пишется буква в букву: другое написание той же модели получит 400 model_not_available.
Четыре коротких имени, которые присылает Claude Code, мы заменяем сами:
| Алиас | Модель |
|---|---|
opus | claude-opus-5-5 |
sonnet | claude-sonnet-5-5 |
haiku | claude-haiku-5-5 |
fable | claude-fable-5-1 |
Запрос с алиасом считается и оплачивается как запрос к модели, в которую он превратился.
Что происходит с запросом#
До отправки провайдеру мы проверяем:
- ключ — иначе 401;
- лимиты ключа и сервиса — иначе 429;
- что модель есть на этом протоколе и разрешена ключу — иначе 400 или 403;
- что баланс вмещает резерв под запрос — иначе 402.
Отказ на этом шаге ничего не стоит и в журнал запросов кабинета не попадает. Дальше запрос уходит провайдеру, ответ возвращается тебе в том виде, в каком пришёл, а с баланса списывается сумма по фактическим токенам. Ответ на запрос, который дошёл до провайдера, несёт заголовок X-Billing-Id — по нему запрос находится в выгрузке статистики. Коды отказов — в разделе «Ошибки и лимиты».
Стриминг#
С "stream": true ответ приходит как SSE. Поток провайдера мы передаём байт в байт: те же события в том же порядке.
- Если модель молчит дольше 15 секунд, мы шлём keepalive:
event: pingв протоколе Anthropic и SSE-комментарий: pingв протоколах OpenAI. - В стриме Chat Completions мы всегда включаем
stream_options.include_usage: последним приходит чанк с пустымchoices: []и статистикой токенов. Свой клиент должен проверять, чтоchoicesне пуст. - Один запрос длится не дольше 30 минут.
Почему длинные ответы нужно стримить#
Запрос без стрима ждёт весь ответ молча: пока модель работает, по соединению ничего не идёт. Перед нашим API стоит Cloudflare, и если ответа нет дольше примерно двух минут, он закрывает соединение с кодом 524, хотя модель ещё работает. Адрес для России идёт через тот же Cloudflare, так что и там правило то же.
На стрим это ограничение не действует: данные или keepalive идут постоянно.Для длинных ответов и долгого thinking включай "stream": true. Claude Code и Codex стримят сами.
Резерв и списание#
- Перед запросом мы резервируем на балансе сумму по оценке. Не хватает баланса — ответ 402
insufficient_balance, и провайдеру запрос не уходит. - После ответа списываем сумму по фактическим токенам из ответа провайдера. Остаток резерва сразу возвращается на баланс; списание не бывает больше резерва.
Резерв заведомо больше цены запроса. Вход оценивается по размеру тела: байты, делённые на 3, плюс 8 192 токенов запаса. Выход — по max_tokens, а без него — по максимуму модели. К сумме добавляется 20%. Поэтому на небольшом балансе задавай max_tokens явно.
Запрос, который отклонён или упал до начала генерации, ничего не стоит: резерв возвращается целиком. Если генерация оборвалась на середине, оплачивается то, что модель успела сгенерировать. В редком случае сбоя на нашей стороне резерв возвращается примерно через 45 минут. Подробности — в разделе «Биллинг и статистика».
Чьи ошибки#
Ошибки бывают двух видов. Наши — когда запрос остановили мы; у них общий JSON-формат с полем error.code. Ошибки провайдера приходят как есть, в формате его протокола, вместе с заголовками retry-after и x-should-retry — инструменты узнают их и повторяют запрос так же, как с официальным API.
Что мы храним#
- О каждом запросе, который дошёл до провайдера, — числа: модель, ключ, протокол, токены входа, выхода и кэша, цену, статус, задержку и время до первого токена. Это и есть журнал запросов в кабинете.
- Тексты промптов и ответов мы не храним и в логи не пишем.
- От ключа хранится только хеш и начало; полный ключ в логи не попадает.
Это описание наших серверов. Чтобы модель ответила, тело запроса уходит её провайдеру как есть.
Свой код#
Официальные SDK работают без правок: поменяй base URL и ключ. Пример на OpenAI SDK:
from openai import OpenAI
client = OpenAI(base_url="https://api.aicreator.app/v1", api_key="sk-aic-…")
reply = client.chat.completions.create(
model="gpt-6-astra",
messages=[{"role": "user", "content": "Hello"}],
)
print(reply.choices[0].message.content)import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://api.aicreator.app/v1", apiKey: process.env.AIC_API_KEY });
const reply = await client.chat.completions.create({
model: "gpt-6-astra",
messages: [{ role: "user", content: "Hello" }],
});
console.log(reply.choices[0].message.content);