airakurs api — единая точка входа ко всем текстовым моделям каталога. один адрес, один ключ и один формат запроса: модель указывается прямо в запросе, поэтому при переходе с одной модели на другую не нужно ни подключать вторую библиотеку, ни переписывать код под чужой формат.
формат запросов — openai. он работает и с моделями anthropic, google и xai: запрос приводится к нужному виду по пути, а ответ возвращается таким, какой ожидает клиент openai. один и тот же код обращается к любой текстовой модели.
адрес
базовый адрес один:
https://api.airakurs.ru/v1
запросы к текстовым моделям идут на https://api.airakurs.ru/v1/chat/completions. тело запроса передаётся в json, ключ — заголовком Authorization.
запрос
обязательных полей два: model с идентификатором модели и messages со списком сообщений. у каждого сообщения есть роль (user — сообщение от пользователя, assistant — ответ модели, system — инструкция для модели) и содержимое.
curl "https://api.airakurs.ru/v1/chat/completions" \
-H "Content-Type: application/json" \
-H "Authorization: Bearer <КЛЮЧ>" \
-d '{
"model": "anthropic/claude-sonnet-4.5",
"messages": [
{"role": "system", "content": "Отвечай коротко."},
{"role": "user", "content": "Назови столицу Австралии."}
]
}'
в примере — формат openai и модель anthropic. это и есть смысл единого api: формат запроса не зависит от того, кто создал модель. чтобы обратиться к другой модели, меняется только значение model; адрес, заголовки и структура запроса остаются теми же.
ответ
ответ приходит в json. текст модели лежит в первом элементе массива choices, в поле message.content:
{
"id": "chatcmpl-6b9cf7a4-427d-404a-9c90-031b2ff36bc3",
"object": "chat.completion",
"model": "anthropic/claude-sonnet-4.5",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Канберра."
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 18,
"completion_tokens": 4,
"total_tokens": 22
}
}
рядом с choices приходит объект usage с числом израсходованных токенов — по нему считается стоимость запроса — и служебные поля: идентификатор ответа, время создания и название модели.
поле finish_reason показывает, почему модель остановилась: stop — ответ завершён, length — упёрлась в ограничение на длину ответа.
что доступно сейчас
| задача | эндпоинт | статус |
|---|---|---|
| список моделей | GET /v1/models | доступен |
| генерация текста | POST /v1/chat/completions | доступен |
| openai responses | POST /v1/responses | доступен |
| anthropic messages | POST /v1/messages | доступен |
| google gemini | POST /v1beta/models/{model}:generateContent | доступен |
| эмбеддинги | POST /v1/embeddings | позже |
| изображения | POST /v1/images/generations | позже |
| речь | POST /v1/audio/speech | позже |
| видео | POST /v1/videos | позже |
в первой версии шлюза — только текст. картинки, видео и озвучка остаются в студии, пока не откроются в api.
другие форматы запросов
формат openai — не единственный: тот же ключ работает с форматами anthropic messages, openai responses и google gemini.
что дальше
- быстрый старт — первый запрос с примерами на python и node.js.
- модели — как устроены идентификаторы.
частые вопросы
нужно ли менять адрес при переходе на модель другого вендора?
нет. адрес, заголовки и структура запроса не меняются — достаточно поставить другое значение в поле model. идентификатор при этом лучше писать целиком, вместе с вендором.
только текстовые модели или что-то ещё?
сейчас через шлюз доступна генерация текста. эмбеддинги, изображения, речь и видео появятся позже на том же адресе и с тем же ключом.
сколько сообщений можно передать в одном запросе?
столько, сколько вмещает контекст модели. модель не помнит предыдущие запросы, поэтому историю диалога нужно передавать в поле messages целиком при каждом обращении.
обязательно ли передавать системное сообщение?
нет, поле messages может содержать только сообщение пользователя. системное сообщение задаёт модели общие указания и полезно, когда нужен определённый стиль или формат ответа.