Быстрый старт
- Зарегистрируйтесь и пополните баланс в разделе «Баланс».
- Создайте ключ в разделе «Ключи». Ключ показывается один раз — сохраните его.
- Укажите в инструменте base URL
https://aemapi.tech/v1и ключ.
curl https://aemapi.tech/v1/chat/completions \
-H "Authorization: Bearer $AEM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "deepseek-v4-pro", "messages": [{"role": "user", "content": "Привет!"}]}'Список доступных вашему ключу моделей: GET https://aemapi.tech/v1/models. Цены — на главной и в кабинете.
Аутентификация
Передайте ключ одним из способов — шлюз принимает все три:
| Заголовок | Где используется |
|---|---|
Authorization: Bearer sk-sig-… | OpenAI SDK, Codex, Cursor, curl |
x-api-key: sk-sig-… | Anthropic SDK, Claude Code |
api-key: sk-sig-… | клиенты в стиле Azure OpenAI |
Не вставляйте ключ в код и в публичные репозитории. Используйте переменную окружения и отдельный ключ с дневным лимитом для каждого устройства или сервиса.
Codex CLI
Добавьте провайдера в ~/.codex/config.toml. Codex работает через Responses API — выберите модель с поддержкой Responses.
model = "gpt-6.1-sol" model_provider = "aemapi" [model_providers.aemapi] name = "AEM API" base_url = "https://aemapi.tech/v1" env_key = "AEM_API_KEY" wire_api = "responses"
export AEM_API_KEY="sk-sig-…" codex
Стриминг, вызовы инструментов, reasoning и previous_response_id поддерживаются. Запросы одной сессии идут в тот же канал поставщика, поэтому кеш промпта работает и повторный контекст тарифицируется по цене кеша.
Claude Code
Claude Code обращается к Anthropic Messages API. Укажите адрес без /v1 — клиент добавит его сам.
export ANTHROPIC_BASE_URL="https://aemapi.tech" export ANTHROPIC_AUTH_TOKEN="sk-sig-…" export ANTHROPIC_MODEL="claude-sonnet-4-5" claude
Доступны только модели с отметкой Messages в каталоге. Запись в кеш у Anthropic стоит на 25% дороже обычного входа, чтение из кеша — дешевле; всё это учитывается при списании.
Cursor, Cline, Roo Code, Continue
Cursor
Settings → Models → включите OpenAI API Key, вставьте ключ, включите Override OpenAI Base URL и укажите https://aemapi.tech/v1. Добавьте имя модели вручную, например glm-5.3.
Cline и Roo Code
API Provider: OpenAI Compatible. Base URL — https://aemapi.tech/v1, API Key — ваш ключ, Model ID — id модели из каталога.
Continue
{
"models": [{
"title": "AEM API — GLM",
"provider": "openai",
"model": "glm-5.3",
"apiBase": "https://aemapi.tech/v1",
"apiKey": "sk-sig-…"
}]
}OpenAI SDK
Python
from openai import OpenAI
import os
client = OpenAI(base_url="https://aemapi.tech/v1", api_key=os.environ["AEM_API_KEY"], max_retries=0)
resp = client.chat.completions.create(
model="deepseek-v4-pro",
messages=[{"role": "user", "content": "Объясни, что делает этот SQL"}],
)
print(resp.choices[0].message.content)
print(resp.usage) # фактические токены, по ним и списываемNode.js
import OpenAI from "openai";
const client = new OpenAI({ baseURL: "https://aemapi.tech/v1", apiKey: process.env.AEM_API_KEY, maxRetries: 0 });
const stream = await client.responses.create({
model: "gpt-6.1-sol",
input: "Сгенерируй миграцию для таблицы orders",
stream: true,
});
for await (const event of stream) {
if (event.type === "response.output_text.delta") process.stdout.write(event.delta);
}Эндпоинты
| Метод | Путь | Описание |
|---|---|---|
POST | /v1/chat/completions | OpenAI Chat Completions, со стримингом и tools |
POST | /v1/responses | OpenAI Responses API — для Codex и агентов |
GET | /v1/responses/{id} | Получить сохранённый ответ (только свой) |
POST | /v1/messages | Anthropic Messages — для Claude Code |
GET | /v1/models | Модели, доступные ключу |
Каждый ответ содержит заголовок x-request-id. Укажите его, если пишете в поддержку, — так мы найдём запрос в журнале.
Как считается стоимость
Цены указаны в рублях за 1 млн токенов. Стоимость запроса считается по usage, который вернул поставщик модели:
стоимость = (вход − кеш) × цена_входа
+ кеш × цена_кеша
+ запись_в_кеш × цена_входа × 1,25 // только Anthropic
+ выход × цена_выхода // включая токены рассуждений- До запроса резервируется полный верхний расход: консервативный вход и ограниченный выход. После корректного итогового usage списывается факт в пределах резерва, остаток освобождается.
- Если итоговый usage отсутствует или некорректен, резерв сохраняется для сверки с поставщиком. Оценочного списания нет.
- Подтверждённый отказ до генерации освобождает резерв. Неоднозначный 5xx/сетевой сбой сохраняет средства до проверки; второй платный запрос автоматически не запускается.
- При отключении клиента шлюз дочитывает ответ поставщика до итогового usage или таймаута. Расход может продолжить расти до указанного выходного лимита.
Поддерживаются встроенный текст и локальные function/custom tools. Изображения, аудио, background, платные серверные инструменты и premium tiers отклоняются до резервирования. Размер входа проверяется консервативно по UTF-8 байтам; непрозрачный контекст и previous_response_id требуют резерва полного контекста модели.
Лимиты
| Лимит | По умолчанию | Где меняется |
|---|---|---|
| Запросов в минуту на ключ | 120 | Настройки ключа |
| Одновременных запросов на аккаунт | 8 | По запросу в поддержку |
| Расход ключа в день / всего | без лимита | Настройки ключа |
| Разрешённые модели ключа | все | Настройки ключа |
| Размер запроса | 1 МБ | — |
Дневной лимит обнуляется в 00:00 по Москве.
Ошибки
Ошибки возвращаются в формате OpenAI ({"error": {"message", "type", "code"}}), а для /v1/messages — в формате Anthropic.
| HTTP | code | Что делать |
|---|---|---|
| 401 | invalid_api_key, key_disabled | Проверьте ключ и его статус в кабинете |
| 402 | insufficient_quota | Пополните баланс |
| 403 | model_not_allowed | Модель не разрешена ключу — измените список моделей |
| 404 | model_not_found | Проверьте id модели: GET /v1/models |
| 423 | billing_requires_review | Резерв на сверке. Сохраните x-request-id и проверьте кабинет; автоматический повтор запрещён. |
| 429 | rate_limited, concurrency_limited | Повторите после retry-after секунд |
| 429 | key_daily_limit_exceeded, key_limit_exceeded | Лимит расхода ключа исчерпан |
| 502 | upstream_unavailable | Все каналы модели недоступны — повторите позже, смотрите статус |
| 503 | model_unavailable | Модель временно отключена |
Стриминг и надёжность
- Стрим передаётся без буферизации: байты поставщика уходят клиенту сразу.
- Для Chat Completions шлюз сам добавляет
stream_options.include_usage, чтобы получить точный расход. Последний чанк с полемusageвы тоже получите. - Переключение разрешено только для подтверждённых отказов 401/403/404/429 до генерации. При неоднозначной ошибке или оборванном потоке резерв остаётся на сверке. Ошибка SSE не означает, что генерация была бесплатной.
- Шлюз сохраняет только метаданные. У Responses store по умолчанию false; store:true запрашивает хранение у поставщика. Доступ к сохранённым ответам ограничен владельцем и ключом.