Документация AICP
Всё для подключения вашего продукта: от первого запроса до учёта результата.
НАЧАЛО РАБОТЫ
Первый запрос
Подключите AICP к серверу вашего приложения: один адрес API, ключ проекта и имя модели.
- Создайте проект и ключ
В кабинете → API-ключи создайте ключ и сохраните секрет. Он показывается один раз. Новый проект начинает с нулевого баланса; бюджет выделяет владелец платформы.
- Настройте приложение
Храните ключ в секретах сервера или переменной окружения
AICP_API_KEY. В настройках интеграции укажите значения ниже.
| Настройка | Значение |
|---|---|
| Base URL | https://api.tower24.tech/v1 |
| Модель | aicp-chat |
| API key | Ваш ключ проекта AICP, не ключ OpenAI |
Готовая интеграция должна позволять задать Base URL и передать Idempotency-Key. Одного поля «ключ OpenAI» недостаточно. Полная совместимость со всеми методами и параметрами OpenAI не заявлена.
3. Отправьте запрос с сервера
Пример ниже выполняет платный запрос в пределах выделенного бюджета. Здесь он не запускается автоматически.
# AICP_API_KEY уже задан в защищённом окружении сервера.
# Сохраните ID до отправки; не меняйте его при повторе этой операции.
REQUEST_ID="$(uuidgen)"
curl --max-time 40 https://api.tower24.tech/v1/chat/completions -H "Authorization: Bearer $AICP_API_KEY" -H "Content-Type: application/json" -H "Idempotency-Key: $REQUEST_ID" --data-binary '{
"model": "aicp-chat",
"messages": [{"role": "user", "content": "Напиши короткое приветствие для клиента CRM."}],
"max_tokens": 512
}' Текст результата находится в choices[0].message.content. Сохраните id, статус учёта и стоимость из aicp. Если запрос завершился ошибкой или потерялся ответ, сначала прочитайте правила повторов.
НАЧАЛО РАБОТЫ
Авторизация
Все семь методов /v1/ требуют активный ключ проекта в заголовке:
Authorization: Bearer <AICP_API_KEY>Ключ определяет проект и доступ к его данным. Его создают в кабинете; пароль кабинета и ключ провайдера для этих запросов не подходят. Секрет нельзя помещать в URL, браузерный JavaScript или публичный репозиторий. Запросы выполняет backend вашего продукта; произвольные браузерные cross-origin запросы не поддерживаются.
В проекте может быть до пяти активных ключей. Ключ действует 90 дней; срок и отзыв видны в кабинете. Отозванный или истёкший ключ возвращает 401 unauthorized. Отзыв не удаляет историю и не отменяет уже начатое исполнение.
СПРАВОЧНИК API
Генерация текста
POST/v1/chat/completions
Один нестриминговый ответ модели. Обязательные заголовки: Authorization, Content-Type: application/json, Idempotency-Key.
| Поле | Контракт |
|---|---|
model · обязательно | Строка aicp-chat. |
messages · обязательно | Массив из 1–16 сообщений. Только поля role и content. Роли: system, user, assistant. Content — строка из 1–12 000 символов. |
max_tokens · обязательно | Целое число 1–2048; включает рассуждение и видимый ответ. Это верхняя граница, не обещанный объём текста. |
stream | Только false; можно не передавать. |
response_format | Необязательный строгий JSON Schema. Без него — текст. |
Другие поля отклоняются. В частности, temperature, tools, reasoning_effort, вложения и клиентские настройки провайдера не принимаются.
{
"model": "aicp-chat",
"messages": [
{
"role": "user",
"content": "Напиши короткое приветствие для клиента CRM."
}
],
"max_tokens": 512
}Успешный ответ · HTTP 200
Иллюстрация структуры; значения ID, токенов и стоимости в реальном ответе зависят от запроса.
{
"id": "request-id",
"object": "chat.completion",
"created": 1793690000,
"model": "aicp-chat",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Здравствуйте! Чем можем помочь?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 10,
"completion_tokens": 4,
"total_tokens": 14
},
"aicp": {
"executionOutcome": "RESULT_EVIDENCE_SAVED",
"accounting": "COMMITTED",
"customerDelivery": "UNCONFIRMED",
"receiptDigest": "sha256-digest",
"providerCost": {
"minor": "11",
"currency": "USD",
"scale": 6
},
"customerCharge": {
"minor": "14",
"currency": "USD",
"scale": 6
},
"margin": {
"minor": "3",
"currency": "USD",
"scale": 6
},
"markupBps": "2500",
"route": {
"policy": "fixed-safe-v1",
"provider": "openai",
"model": "gpt-5-mini-2025-08-07",
"optimizer": "DISABLED_PENDING_EVALUATION"
},
"evaluator": { "status": "NOT_RUN" },
"synthetic": false
}
}customerDelivery: UNCONFIRMED не отменяет COMMITTED: сервер не считает отправку HTTP доказательством, что приложение сохранило ответ. Ошибка 502 также может содержать уже подтверждённый расход — см. ошибки.
СПРАВОЧНИК API
Структурированный JSON
POST/v1/chat/completions
Используйте тот же метод и заголовки. Добавьте response_format; результат остаётся JSON-строкой в choices[0].message.content. Разберите её через JSON.parse после проверки HTTP-статуса.
{
"model": "aicp-chat",
"messages": [
{
"role": "user",
"content": "Клиент хочет узнать цену. Определи намерение: pricing, support или other."
}
],
"max_tokens": 512,
"response_format": {
"type": "json_schema",
"json_schema": {
"name": "crm_intent",
"strict": true,
"schema": {
"type": "object",
"properties": {
"intent": {
"type": "string",
"enum": [
"pricing",
"support",
"other"
]
}
},
"required": [
"intent"
],
"additionalProperties": false
}
}
}
}Поддерживаемая схема
type: json_schema, обязательныеname,strict: true,schema. Name: 1–64 латинских буквы, цифры,_или-. Необязательное описание — до 256 символов.- Корень схемы — object. У каждого object:
additionalProperties: false, все properties перечислены в required. - Типы: object, array, string, number, integer, boolean, null. Nullable-форма:
["string", "null"]и аналогично для других типов. - Ключевые слова: type, description, properties, required, additionalProperties, items, enum, minItems, maxItems, minimum, maximum. Ограничения должны соответствовать типу; enum содержит 1–64 скалярных значения.
- Весь объект json_schema — до 4096 UTF-8 байт, до 64 узлов, глубина до 6 (корень — 1). Служебные имена свойств
__proto__,constructor,prototypeзапрещены.
$ref, anyOf, регулярные выражения и режим json_object не поддерживаются. Невалидный результат модели не превращается в успешный JSON; проверяйте error и фактический учёт.
СПРАВОЧНИК API
Доступные модели
GET/v1/models
curl --max-time 40 "https://api.tower24.tech/v1/models" \
-H "Authorization: Bearer $AICP_API_KEY"{
"object": "list",
"data": [
{
"id": "aicp-chat",
"object": "model",
"owned_by": "openai",
"nonProduction": false
}
]
}Клиент использует стабильный alias aicp-chat, а не имя upstream-модели. Текущий безопасный маршрут закреплён за OpenAI gpt-5-mini-2025-08-07. Каталог всех доступных AICP моделей управляется владельцем платформы и не означает, что умный выбор уже включён: до появления измеримой проверки качества действует fixed-safe-v1. Этот метод сообщает клиентскую конфигурацию; он не выполняет inference и не подтверждает работоспособность провайдера.
СПРАВОЧНИК API
Проект и баланс
GET/v1/workspace
curl --max-time 40 "https://api.tower24.tech/v1/workspace" \
-H "Authorization: Bearer $AICP_API_KEY"| Поле ответа | Значение |
|---|---|
workspace | Профиль проекта: id, name и применённые policy/quota/pricing/budget настройки. |
wallet | currency, scale, unit, balanceMinor, reservedMinor, availableMinor. Денежные значения Minor — десятичные строки. |
quota | Действующие ограничения проекта. |
keys | Метаданные ключей: id, label, prefix, status. Секретов нет. |
route | model, provider, deployment, cell. |
nonProduction | false на текущем публичном Gateway. |
Доступный баланс равен остатку за вычетом резервов. До исполнения сервер резервирует верхнюю оценку стоимости; достаточный баланс нужен даже при ожидаемом коротком ответе. После подтверждённого учёта списывается фактическая стоимость.
СПРАВОЧНИК API
Расходы и история
GET/v1/usage
curl --max-time 40 "https://api.tower24.tech/v1/usage" \
-H "Authorization: Bearer $AICP_API_KEY"| Поле ответа | Значение |
|---|---|
data[] | Подтверждённые расходы: requestId, status=COMMITTED, inputTokens, outputTokens, providerCost, customerCharge, margin, markupBps, route, evaluator, pricing, receiptDigest, createdAt. |
requests[] | Все запросы проекта: id, status, customerDelivery, errorCode, createdAt. |
ledger[] | Записи учёта: id, requestId, kind, currency, amountMinor, createdAt. |
nonProduction | Режим среды. |
Метод возвращает историю вашего проекта без параметров пагинации. providerCost — стоимость провайдера, customerCharge — расход клиента, margin — их точная разница по зафиксированной для запроса наценке. Формат денег: {"minor":"11","currency":"USD","scale":6} означает $0.000011. Храните значения точно, без округления до центов.
Стоимость рассчитывает AICP. Продукту-потребителю не нужно повторно вычислять или списывать её по своему тарифу. Отсутствие записи в data ещё не доказывает отсутствие исполнения: проверьте requests и возможный резерв.
СПРАВОЧНИК API
Статус запроса
GET/v1/requests/{id}
id берётся из ответа генерации или error.requestId. В URL передавайте его как один закодированный сегмент. Чужой или неизвестный ID возвращает 404.
curl --max-time 40 "https://api.tower24.tech/v1/requests/REQUEST_ID" \
-H "Authorization: Bearer $AICP_API_KEY"| Поле ответа | Значение |
|---|---|
id, status, accounting | Идентификатор, состояние запроса, COMMITTED или NOT_COMMITTED. |
executionOutcome, containment, customerDelivery | Состояние исполнения, ограничение дальнейших действий и доставка. |
inputBound, outputBound, reserve | Принятые границы и исходный резерв. reserve — денежный объект; это не текущий остаток удержания. |
model, deployment, pricing, route, evaluation | Зафиксированные модель, цена, решение маршрутизации и состояние оценки качества. |
receiptAvailable, receiptDigest | Наличие сохранённого подтверждения результата и его хеш. |
errorCode, createdAt, updatedAt, events[] | Диагностика и события {kind, createdAt}. |
Метод возвращает статус и доказательства учёта, не текст генерации. Сохранённый ответ COMMITTED получают повтором исходного POST с тем же телом и Idempotency-Key.
СПРАВОЧНИК API
Завершение учёта
POST/v1/requests/{id}/reconcile
Применяется к SETTLEMENT_PENDING, когда результат уже сохранён, но учёт не завершён. Авторизация — ключ того же проекта, Content-Type — application/json, тело — {}. Idempotency-Key здесь не требуется.
curl --max-time 40 -X POST https://api.tower24.tech/v1/requests/REQUEST_ID/reconcile -H "Authorization: Bearer $AICP_API_KEY" -H "Content-Type: application/json" --data '{}' HTTP 200: {"request": {…}, "executorInvoked": false, "nonProduction": false}. Поля request описаны выше. Повтор уже COMMITTED не списывает второй раз. Для UNKNOWN без сохранённого подтверждения — 409 receipt_required; этот метод не снимает неопределённость и не запускает модель заново.
СПРАВОЧНИК API
Отзыв текущего ключа
POST/v1/keys/current/revoke
Отзывает именно ключ, переданный в Authorization. Content-Type — application/json; тело — {}. Idempotency-Key не требуется. Для управления другими ключами используйте кабинет.
# Выполняйте только если хотите отозвать используемый ключ.
curl --max-time 40 -X POST https://api.tower24.tech/v1/keys/current/revoke -H "Authorization: Bearer $AICP_API_KEY" -H "Content-Type: application/json" --data '{}' HTTP 200: {"status":"REVOKED","credentialId":"…","nonProduction":false}. Последующие запросы с этим ключом, включая повтор отзыва, получат 401. История сохраняется; уже начатые запросы этим действием не отменяются.
ПРАВИЛА И ОШИБКИ
Повторы и неопределённый результат
Idempotency-Key обязателен для генерации. Используйте 1–128 символов из A–Z a–z 0–9 . _ : -. Для новой операции — новый ID; для повтора той же операции — прежний ID и прежнее тело. Сохраните их до отправки.
| Состояние | Действие клиента |
|---|---|
COMMITTED | Повтор исходного POST с прежним ID возвращает сохранённый ответ, включая сохранённый HTTP 502. Нового исполнения и списания нет. |
SETTLEMENT_PENDING | Прочитайте статус; выполните reconcile без нового inference. После COMMITTED повтор исходного POST возвращает результат. |
UNKNOWN | Сохраните состояние неопределённости и requestId, обратитесь к владельцу платформы. Резерв удержан; нельзя запускать ту же бизнес-операцию с новым ID или через fallback. |
IN_FLIGHT | Прочитайте статус позже. Повтор не запускает второе исполнение. |
FAILED_PRE_EFFECT | Доказано, что исполнение не началось; резерв освобождён. Этот ID не переисполняется. Новая операция возможна после устранения причины. |
То же значение ключа с другим нормализованным телом даёт 409 idempotency_conflict. Все состояния, кроме COMMITTED, не возвращают успешный replay. Автоматические SDK retries и fallback следует отключить; интеграция должна обрабатывать эти состояния явно.
Если ответ потерян и requestId неизвестен, сохраните исходные Idempotency-Key и тело. Чтения GET по Idempotency-Key сейчас нет. Повтор с прежним ключом защищён от второго исполнения; новый ключ такой защиты для исходной операции не даёт. HTTP-таймаут не доказывает отсутствие расходов.
ПРАВИЛА И ОШИБКИ
Ограничения
Текущий публичный Gateway поддерживает текст и строгий JSON. Streaming, tools, embeddings, изображения, аудио, batch и Responses API пока отсутствуют.
| Ограничение | Текущее значение |
|---|---|
| Тело chat/completions | До 32 768 UTF-8 байт целиком. |
| Оценка входа | До 30 720: UTF8(JSON(messages)) + 2048 + UTF8(JSON(normalized response_format)), если формат задан. Это консервативная оценка допуска, не измеренные токены. |
| Сообщения / ответ | 1–16 сообщений, до 12 000 символов каждое; max_tokens 1–2048. |
| Частота / параллелизм | По умолчанию 10 RPM, 32 768 TPM, один активный или удержанный запрос на проект. TPM проверяется по входной оценке и заданному максимуму ответа. |
| Бюджеты | По умолчанию $1/сутки и $5/месяц, дополнительно ограниченные доступным балансом; периоды UTC. Действующие параметры — в /v1/workspace. |
| Таймауты | Провайдер 25 с, приложение 28 с, внешний сервер 35 с. В примере клиент ждёт 40 с. Это не обещание времени ответа. |
Контекст не обрезается незаметно: превышение отклоняется. После UNKNOWN удержанный запрос может занять единственный слот проекта; немедленные повторы не решают эту ситуацию.
ПРАВИЛА И ОШИБКИ
Ошибки API
Проверяйте HTTP-статус и error.code. Текст message может меняться и сейчас может быть на английском. В ответе может присутствовать error.requestId.
{
"error": {
"code": "outcome_unknown",
"message": "Execution outcome is unknown; the hold is retained and this key cannot trigger a retry",
"requestId": "request-id"
}
}| HTTP / code | Значение и действие |
|---|---|
| 400 · invalid_request / invalid_response_format | Проверьте поля, типы и допустимую схему. Дополнительные поля не принимаются. |
| 400 · idempotency_required | Добавьте корректный Idempotency-Key в запрос генерации. |
| 401 · unauthorized | Ключ отсутствует, истёк или отозван. Проверьте заголовок и ключ в кабинете. |
| 402 · insufficient_balance / budget_limit | Недостаточно доступного бюджета для резерва или превышен периодный лимит. |
| 403 · host_denied / origin_denied | Используйте точный HTTPS API-адрес и серверную интеграцию. |
| 404 · not_found | ID запроса не существует или принадлежит другому проекту. |
| 409 · idempotency_conflict | Этот ключ уже связан с другим телом. Не заменяйте ID, пока не установлено состояние исходной операции. |
| 409 · request_not_replayable / settlement_pending | Существующий запрос не завершён. Следуйте правилам повторов, без нового inference. |
| 409 · receipt_required / invalid_usage_evidence / accounting_invariant | Завершение учёта невозможно по текущим доказательствам. Сохраните requestId и обратитесь к владельцу платформы. |
| 413 · request_failed | Слишком большое тело. Внешний сервер также может вернуть 413 без JSON; проверяйте Content-Type. |
| 422 · token_limit | Превышена консервативная граница входа или выхода. Уменьшите запрос. |
| 429 · rate_limit / concurrency_limit | Превышена частота/TPM или занят слот. Для удержанного UNKNOWN ожидание само по себе не освобождает резерв. |
| 502 · provider_refusal / provider_incomplete / provider_invalid_output | Провайдер завершил оплачиваемое исполнение, но пригодного результата нет. Ответ может быть COMMITTED, содержать usage/aicp и не содержать choices. Сохраните стоимость; не запускайте автоматическую повторную генерацию. |
| 503 · outcome_unknown | Исход не подтверждён; резерв сохраняется. Новый ID/fallback для той же операции запрещён. |
| 503 · settlement_pending | Результат сохранён; требуется только завершение учёта через reconcile. |
| 503 · execution_not_started | Отсутствие исполнения доказано, резерв освобождён. |
| 500 · request_failed и ошибки транспорта | Сохраните исходные параметры и ID. Нельзя заключать «расхода нет» только по HTTP-ошибке или разрыву соединения. |
При обращении к владельцу платформы передайте время, requestId (если известен), HTTP-статус и error.code. API-ключ и содержимое переписки в сообщение не включайте.