Перейти к содержанию

Brand Partner API

Небольшой, предсказуемый REST API для создания заказов mintbot, опроса их статуса и получения событий жизненного цикла. JSON на входе, JSON на выходе. Авторизация bearer-token. Идемпотентные записи. Подписанные webhooks.

Панель доступа к API Перейти к webhooks


Кратко

Base URL https://mint.mintbot.ai/api/v1
Auth `Authorization: Bearer ***
Идемпотентность Idempotency-Key: <uuid> при каждом POST
Content type application/json
Rate limit 120 req / 60 s на партнёра
Webhooks Подписываются HMAC-SHA256, повторяются до 7 раз

Аутентификация

Каждый запрос передаёт партнёрский API-ключ в заголовке Authorization. Создайте или ротируйте ключ в панели.

Authorization: Bearer mo_liv...xxxx
Content-Type: application/json

У ротации нет льготного окна

Ротация ключа атомарно отзывает предыдущий. Заранее подготовьте замену значения в своей конфигурации, прежде чем нажимать Rotate.

Идемпотентность

Каждый POST требует заголовок Idempotency-Key. Подойдёт любой UUID для каждого отдельного запроса.

  • Мы кэшируем ответ на 24 часа. Повтор с тем же ключом возвращает исходный ответ с Idempotent-Replay: true.
  • Повторное использование того же ключа с другим телом возвращает 409 idempotency_key_mismatch.

Заказы

Создать заказ

POST /orders

Создаёт заказ и возвращает URL Stripe Checkout. После подтверждения оплаты mintbot разворачивает агента, а событие дохода с долей партнёра записывается автоматически.

Запрос

{
  "tier": "s1",
  "duration_months": 1,
  "credit_usd": 10,
  "language": "en",
  "external_id": "your-side-id",
  "success_url": "https://your.app/thanks?id={ORDER_ID}",
  "cancel_url":  "https://your.app/cart",
  "webhook_url": "https://your.app/mintbot-webhook"
}
tier
Один из trial, s1, s2, s4.
duration_months
Срок жизни сервера в календарных месяцах. Должно быть 1, 3 или 12.
credit_usd
Необязательно. Предоплаченный чат-кредит, включённый в заказ.
language
Необязательно. Влияет на локаль Stripe Checkout и язык приветственного email.
external_id
Необязательно. Возвращается в каждом webhook и ответе заказа — используйте его, чтобы связывать заказы mintbot со строками в собственной системе.
success_url · cancel_url
URL возврата Stripe Checkout. {ORDER_ID} подставляется на стороне сервера.
webhook_url
Необязательно. Переопределение URL webhook уровня партнёра для конкретного заказа.

Ответ — 201 Created

{
  "id": 42,
  "tier": "s1",
  "duration_months": 1,
  "credit_usd": 10,
  "amount_cents": 1200,
  "currency": "usd",
  "status": "awaiting_payment",
  "checkout_url": "https://checkout.stripe.com/c/pay/cs_test_…",
  "panel_url": null,
  "expires_at": null,
  "language": "en",
  "external_id": "your-side-id",
  "created_at": "2026-05-16 09:58:00",
  "paid_at": null
}

Пример

curl -X POST https://mint.mintbot.ai/api/v1/orders \
  -H "Authorization: Bearer *** \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{
    "tier": "s1",
    "duration_months": 1,
    "credit_usd": 10,
    "success_url": "https://your.app/thanks?id={ORDER_ID}",
    "cancel_url":  "https://your.app/cart"
  }'
import os, uuid, requests

r = requests.post(
    "https://mint.mintbot.ai/api/v1/orders",
    headers={
        "Authorization": f"Bearer {os.environ['MINTBOT_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "tier": "s1",
        "duration_months": 1,
        "credit_usd": 10,
        "success_url": "https://your.app/thanks?id={ORDER_ID}",
        "cancel_url":  "https://your.app/cart",
    },
    timeout=10,
)
r.raise_for_status()
order = r.json()
redirect_to = order["checkout_url"]

Получить заказ

GET /orders/{id}

Получает один заказ по его mintbot id. Возвращает ту же структуру, что и POST /orders.

curl https://mint.mintbot.ai/api/v1/orders/42 \
  -H "Authorization: Bearer ***

Список заказов

GET /orders

Список с курсорной пагинацией, сначала самые новые.

Query parameters

status
Необязательно. Фильтр по awaiting_payment, completed, deployed, deploy_failed или expired.
cursor
Необязательно. Передайте next_cursor с предыдущей страницы, чтобы продолжить.

Ответ

{
  "items": [ /* OrderResponse … */ ],
  "next_cursor": "37"
}

next_cursor равен null, когда страниц больше нет.


Продлить заказ

POST /orders/{id}/renew

Продлевает существующего агента ещё на duration_months. Только инфраструктура — новый чат-кредит не включается. Возвращает новый id заказа и свежий URL Stripe Checkout.

Запрос

{
  "duration_months": 1,
  "external_id": "your-side-id",
  "success_url": "https://your.app/thanks?id={ORDER_ID}",
  "cancel_url":  "https://your.app/account"
}

Доход

Прочитать доход

GET /revenue

Итоги плюс последние 200 событий ledger.

Query parameters

include_paid
Необязательно, по умолчанию true. Установите false, чтобы видеть только ещё не выплаченные события.

Ответ

{
  "currency": "usd",
  "gross_cents": 12000,
  "partner_cut_cents": 2000,
  "mintbot_cut_cents": 10000,
  "unpaid_cents": 800,
  "events": [
    {
      "id": 7,
      "order_id": 42,
      "kind": "order_paid",
      "gross_cents": 1200,
      "partner_cut_cents": 200,
      "mintbot_cut_cents": 1000,
      "currency": "usd",
      "created_at": "2026-05-16 09:58:00",
      "payout_id": null,
      "payout_at": null
    }
  ]
}

Профиль партнёра

Получить профиль

GET /partner

Возвращает ваш профиль партнёра и невыплаченный баланс — удобно, чтобы показывать заработок внутри собственной админ-панели без самостоятельного хранения этих данных.

Ответ

{
  "id": 12,
  "email": "you@kliendifirma.com",
  "pricing_currency": "usd",
  "balance_unpaid_cents": 800,
  "webhook_url": "https://your.app/mintbot-webhook",
  "api_key_prefix": "mo_live_a12b"
}

Настройки

Получить настройки

GET /settings

Возвращает всю вашу несекретную конфигурацию партнёра одним ответом — выбранные режимы, apex-домен, DNS-провайдера, провайдера бота, репозиторий кастомизации, шаблон субдомена (с готовой меткой-превью), тарифы по уровням, метаданные API-ключа, метаданные webhook и тот же статус готовности / по секциям, который управляет баннером дашборда MintOffice.

Предназначен для интеграционных агентов, которым нужно узнать, как настроен партнёр, не парся дашборд и не опрашивая оператора. Типичный вызывающий — кодинг-агент, устанавливающий вашу white-label-сборку на свежем сервере: он может прочитать этот endpoint, ветвиться по readiness.status и сообщить оператору, какие именно секции ещё требуют внимания.

Секреты никогда не возвращаются

Всё, что партнёр указал как учётные данные — токен Telegram-бота, API-ключ Zone.ee, секрет подписи webhook, сам plaintext API-ключа — отображается только как булево *_set. Секрет webhook дополнительно показывает тот же 8-символьный display-префикс, который уже отображается в дашборде, так что вызывающий может подтвердить, какой секрет настроен, ни разу не увидев его значение.

Ответ

{
  "id": 12,
  "email": "you@kliendifirma.com",
  "status": "live",
  "created_at": "2026-05-12 14:22:01",
  "onboarded_at": "2026-05-12 14:48:33",
  "activated_at": "2026-05-13 09:10:05",
  "last_login_at": "2026-05-20 00:51:18",
  "preferred_language": "en",
  "pricing_currency": "usd",
  "balance_unpaid_cents": 800,

  "domain": {
    "mode": "byo",
    "client_apex_domain": "agent99.cc",
    "dns_provider": "zone.ee",
    "zone_ee_username": "you@kliendifirma.com",
    "zone_ee_api_key_set": true,
    "subdomain_prefix": "agent",
    "subdomain_numbering": "natural",
    "subdomain_pad_width": 3,
    "subdomain_label_preview": "agent1"
  },

  "bot": {
    "mode": "own",
    "provider": "telegram",
    "telegram_bot_username": "agent99cc_bot",
    "telegram_bot_token_set": true
  },

  "template": {
    "mode": "default",
    "repo_url": null
  },

  "api": {
    "key_prefix": "mo_live_a12b",
    "key_created_at": "2026-05-13 09:11:42",
    "webhook_url": "https://your.app/mintbot-webhook",
    "webhook_secret_set": true,
    "webhook_secret_prefix": "ab12cd34"
  },

  "pricing": {
    "mode": "default",
    "currency": "usd",
    "tiers": {
      "trial": { "price_cents": 0,    "partner_cut_cents": 0,   "updated_at": null },
      "s1":    { "price_cents": 1200, "partner_cut_cents": 200, "updated_at": "2026-05-13 09:05:00" },
      "s2":    { "price_cents": 2400, "partner_cut_cents": 400, "updated_at": "2026-05-13 09:05:00" },
      "s4":    { "price_cents": 4800, "partner_cut_cents": 800, "updated_at": "2026-05-13 09:05:00" }
    }
  },

  "readiness": {
    "ready": true,
    "missing_fields": [],
    "dns_blocker": null,
    "status": "live"
  },

  "section_status": {
    "domain":   { "status": "ready", "mode": "byo",     "issue": null, "dns_blocker": null },
    "bot":      { "status": "ready", "mode": "own",     "issue": null, "dns_blocker": null },
    "template": { "status": "ready", "mode": "default", "issue": null, "dns_blocker": null },
    "api":      { "status": "ready", "mode": "live",    "issue": null, "dns_blocker": null },
    "all_ready": true
  }
}

Справочник полей

status
Жизненный цикл партнёра. Один из onboarding, live, paused. Brand Partner API отклоняет записи, пока статус onboarding.
domain.mode
byo (вы приносите собственный apex-домен) или hosted (mintbot предоставляет субдомен *.mintbot.ai). При hosted поля DNS-провайдера намеренно пусты, независимо от того, что партнёр вводил ранее.
domain.subdomain_label_preview
Готовая метка, которую получил бы первый клиентский агент (agent1, 1, 001, …) при текущих subdomain_prefix, subdomain_numbering и subdomain_pad_width. Используйте её для превью «вот что увидят ваши клиенты», не переписывая правила нумерации.
bot.mode
own (Telegram-бот, предоставленный партнёром), borrow (использование бота mintbot во время тестирования) или web (только панель, без Telegram).
template.mode
default (нет репозитория кастомизации агента — агент работает на чистой небрендированной базе) или custom (agent customization repo партнёра по адресу repo_url). При custom собственный VPS агента клонирует этот репозиторий после стандартного деплоя и запускает его install.sh / update.sh, чтобы наложить вашу персону, тему панели и любой дополнительный инструментарий поверх базы — central никогда не выполняет репозиторий сам. Укажите в repo_url ваш GitHub HTTPS agent customization repo, когда хотите кастомный брендинг.
api.webhook_secret_prefix
Первые 8 символов секрета подписи webhook, присутствует только когда секрет настроен. Позволяет вызывающему различать, какой секрет установлен, не видя полного значения. Дашборд показывает тот же префикс.
readiness.missing_fields
Список имён полей дашборда, ещё обязательных перед Go Live. Пуст, когда ready равно true. Достаточно стабилен, чтобы строить на нём UI «чего ещё не хватает» в вашей собственной админке.
readiness.dns_blocker
Содержит короткую строку-причину, когда проверка DNS не проходит (например, nameservers_not_pointing, glue_record_missing). Иначе null.
section_status.*.issue
Человекочитаемая подсказка по секции, когда эта секция блокирует Go Live. Отражает посекционные статус-метки дашборда.

Пример

curl https://mint.mintbot.ai/api/v1/settings \
  -H "Authorization: Bearer $MINTBOT_API_KEY"
import os, requests

r = requests.get(
    "https://mint.mintbot.ai/api/v1/settings",
    headers={"Authorization": f"Bearer {os.environ['MINTBOT_API_KEY']}"},
    timeout=10,
)
r.raise_for_status()
settings = r.json()

if not settings["readiness"]["ready"]:
    print("Still missing:", settings["readiness"]["missing_fields"])

Каталог

Список пакетов для продажи для вашей витрины — публичные пакеты (trial / starter / pro), соединённые с вашими итоговыми ценами в вашей валюте ценообразования. Рендерите карточки тарифов из него, а не зашивайте слаги уровней и цены жёстко: снятые пакеты исчезают сами, а изменение цены или валюты, сделанное вами в дашборде, доходит до вашей витрины в пределах окна кэша — без редеплоя.

Это тот endpoint, который не даёт витрине рекламировать вчерашние пакеты. Референсный портал вызывает его при каждом рендере лендинга / /buy / /extend (с кэшированием и липким fallback).

Тексты для отображения остаются вашими

display_name / description / featured — это канонические метаданные пакетов mintbot. Если вы хотите переименовать пакет или переписать его описание под свой бренд, переопределите это в собственной витрине (в референсном портале для этого есть карта PLAN_OVERRIDES) — каталог является источником истины о том, какие пакеты существуют и сколько они стоят, а не о ваших маркетинговых текстах.

Получить каталог

GET /api/v1/catalog

Без параметров. Только bearer-авторизация — нет гейта активации, поэтому витрина может рендерить каталог ещё до того, как ваш партнёрский аккаунт переведён в live.

Ответ

{
  "currency": "usd",
  "packages": [
    {
      "tier": "trial",
      "display_name": "Trial",
      "description": "One day to kick the tires.",
      "featured": false,
      "default_credit_usd": 5,
      "durations": [
        { "months": 1, "label": "24 hours", "price_cents": 0 }
      ],
      "subscription": { "available": false, "price_cents": null }
    },
    {
      "tier": "starter",
      "display_name": "Starter",
      "description": "A month of assistant time.",
      "featured": true,
      "default_credit_usd": 10,
      "durations": [
        { "months": 1,  "label": "1 month",   "price_cents": 1500 },
        { "months": 3,  "label": "3 months",  "price_cents": 4500 },
        { "months": 12, "label": "12 months", "price_cents": 18000 }
      ],
      "subscription": { "available": true, "price_cents": 1500 }
    }
  ]
}
Поле Значение
currency Ваша валюта ценообразования. Каждое price_cents ниже выражено в ней.
packages[] По одной записи на публичный пакет, в порядке предложения/отображения.
tier Слаг, который вы передаёте в POST /orders / POST /subscriptions.
display_name / description / featured Канонические тексты для отображения (переопределите в своей витрине, если хотите).
default_credit_usd Подсказка о входящем в пакет LLM-кредите (информационно).
durations[] Сроки, на которые можно купить этот пакет. months — значение, которое вы отправляете как duration_months; price_cents — сумма, которую спишет заказ. Месячные пакеты предлагают 1 / 3 / 12 месяцев; trial предлагает единственный 24-часовой срок.
subscription available равно true для пакетов, которые можно купить как ежемесячное автопродление через POST /subscriptions; price_cents — ежемесячная сумма. trial никогда не доступен по подписке.

Цены совпадают с тем, что вам спишут

Каждое price_cents вычисляется тем же резолвером цен, что использует endpoint заказов, поэтому цена на карточке всегда равна итоговой сумме Stripe Checkout для этого (tier, duration_months).

Пример

curl -s https://mint.mintbot.ai/api/v1/catalog \
  -H "Authorization: Bearer $MINTBOT_API_KEY" | jq
import os, requests

r = requests.get(
    "https://mint.mintbot.ai/api/v1/catalog",
    headers={"Authorization": f"Bearer {os.environ['MINTBOT_API_KEY']}"},
    timeout=10,
)
r.raise_for_status()
catalog = r.json()

for pkg in catalog["packages"]:
    month1 = next(d for d in pkg["durations"] if d["months"] == 1)
    print(pkg["display_name"], month1["price_cents"], catalog["currency"])

DNS-записи

Интеграциям бренд-партнёров часто нужно создавать DNS-записи на apex-домене партнёра — направляя @, www или субдомены отдельных клиентов на нужный сервер. MintOffice предоставляет vendor-blind прокси, чтобы вы могли делать это ни разу не имея дела с API-ключом вышестоящего провайдера в собственной инфраструктуре. Учётные данные, сохранённые вами при онбординге (сегодня: zone.ee; cloudflare и route53 запланированы под той же формой), остаются зашифрованными в MintOffice; ваш вызов приходит с Bearer mo_live_…, а мы делаем вышестоящий вызов от вашего имени.

Область — это собственный настроенный apex партнёра (domain.client_apex_domain из GET /settings). Вы не можете трогать запись в зоне, которой не владеете.

Сегодня прокси поддерживает операции, которые использует сам deploy pipeline — A-записи (upsert / список / удаление по id). Поддержка CNAME / TXT / MX появится в той же форме, когда абстракция нижележащего провайдера их получит.

Idempotency-Key здесь не требуется

В отличие от endpoint'ов создания заказов, DNS-upsert'ы естественно идемпотентны на уровне провайдера (повтор с тем же (subdomain, ip) — это no-op, а устаревшие дубликаты вычищаются при каждом вызове). Вам не нужно отправлять заголовок Idempotency-Key — повторы всегда сходятся к одной A-записи на FQDN.

Создать или обновить A-запись (upsert)

POST /dns/records

Идемпотентно направляет <subdomain>.<your-apex> на IPv4-адрес. Передайте "" (или "@") для самого apex.

Запрос

{
  "subdomain": "www",
  "ip": "203.0.113.10"
}

subdomain принимает:

  • "" или "@" — сам apex (example.com).
  • Одна DNS-метка — "www", "api" — для <label>.<apex>.
  • Точечные подметки — "api.eu" — для вложенных субдоменов (api.eu.example.com).

ip должен быть IPv4-адресом в точечной записи. Каждая метка — [a-z0-9_-], 1–63 символа, без - в начале/конце.

Ответ — 200

{
  "apex": "example.com",
  "provider": "zone_ee",
  "fqdn": "www.example.com",
  "records": [
    { "id": "9182734", "name": "www.example.com", "destination": "203.0.113.10" }
  ]
}

Список records после записи всегда отражает текущее представление FQDN у вышестоящего провайдера после вычистки дубликатов — поэтому успешный ответ ровно с одной записью — это сигнал happy-path, что ничего устаревшего не осталось.

Список записей

GET /dns/records

Возвращает все A-записи на настроенном apex. Добавьте ?name=<label-or-fqdn>, чтобы отфильтровать до одного FQDN — значением может быть голая метка ("www"), точечный субдомен ("api.eu") или полный FQDN ("www.example.com").

Ответ — 200

{
  "apex": "example.com",
  "provider": "zone_ee",
  "items": [
    { "id": "9182734", "name": "example.com",     "destination": "203.0.113.10" },
    { "id": "9182735", "name": "www.example.com", "destination": "203.0.113.10" }
  ]
}

Удалить запись

DELETE /dns/records/{record_id}

record_id — это идентификатор вендора, возвращаемый GET /dns/records (zone.ee выдаёт целочисленные id, приводимые к строке на границе API). Удаление записи, которой уже нет, считается успехом — endpoint идемпотентен на стороне клиента.

Ответ — 200

{ "deleted": true, "id": "9182734" }

Ошибки

HTTP error.code Причина
401 unauthenticated / invalid_api_key Отсутствует / некорректный Bearer-токен.
422 validation_error Некорректный субдомен или назначение не в формате IPv4.
422 dns_not_configured У партнёра нет client_apex_domain либо отсутствуют учётные данные настроенного провайдера. Исправьте в Настройки → Домен.
422 dns_provider_unsupported DNS-провайдер партнёра ещё не подключён к прокси MintOffice (например, заглушка cloudflare). Пока переключитесь на zone_ee.
502 dns_provider_error Вышестоящий провайдер вернул 4xx/5xx или сбой транспорта. В message ошибки передаётся статус вышестоящего ответа и короткая выдержка из его тела с вырезанными секретами. Повтор безопасен.

Пример

# Point apex + www at your server's IP.
curl https://mint.mintbot.ai/api/v1/dns/records \
  -H "Authorization: Bearer $MINTBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"subdomain": "",    "ip": "203.0.113.10"}'

curl https://mint.mintbot.ai/api/v1/dns/records \
  -H "Authorization: Bearer $MINTBOT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"subdomain": "www", "ip": "203.0.113.10"}'

# Verify.
curl "https://mint.mintbot.ai/api/v1/dns/records" \
  -H "Authorization: Bearer $MINTBOT_API_KEY"
import os, requests

URL = "https://mint.mintbot.ai/api/v1/dns/records"
H = {"Authorization": f"Bearer {os.environ['MINTBOT_API_KEY']}"}

for sub in ("", "www"):
    r = requests.post(URL, headers=H, json={"subdomain": sub, "ip": "203.0.113.10"})
    r.raise_for_status()
    print(sub or "@", r.json()["records"])

Webhooks

Когда с заказом что-то происходит, мы отправляем POST с подписанным JSON-событием на настроенный вами URL webhook.

Типы событий

Event Когда срабатывает
order.created Создана сессия Stripe Checkout, ожидается оплата.
order.paid Stripe подтвердил оплату. Событие дохода записано.
order.cancelled Заказ истёк по времени или был явно отменён.
agent.provisioning_started Для этого заказа запущен deploy pipeline.
agent.ready Deploy завершился успешно. Payload содержит panel_url и expires_at.
agent.failed Deploy pipeline завершился ошибкой. Проверьте поле error, чтобы увидеть сломавшийся шаг.
agent.expired TTL агента истёк. Партнёр может продлить через POST /orders/{id}/renew.

Доставка и повторы

  • До 7 попыток по экспоненциальному расписанию: 0s, 30s, 2m, 10m, 1h, 6h, 24h.
  • После последней попытки доставка помечается как exhausted и повторы прекращаются.
  • Ответьте статусом 2xx в течение 10 секунд, чтобы подтвердить получение.

Заголовки запроса

Content-Type: application/json
User-Agent: mintbot-webhook/1.0
X-Mintbot-Signature: t=<unix_ts>,v1=<hex_hmac_sha256>
X-Mintbot-Event-Id: evt_42_order.paid_1747371234567
X-Mintbot-Event-Type: order.paid

Пример payload — order.paid

{
  "id": 42,
  "tier": "s1",
  "duration_months": 1,
  "credit_usd": 10,
  "amount_cents": 1200,
  "currency": "usd",
  "status": "completed",
  "external_id": "your-side-id",
  "paid_at": "2026-05-16 10:02:14"
}

Проверка подписи

Подпись — это HMAC-SHA256(secret, "{timestamp}.{raw_body}"). Всегда проверяйте сырое тело запроса — повторная сериализация разобранного JSON сломает сравнение.

import hmac, hashlib, time

def verify(secret: str, body: bytes, header: str, tolerance: int = 300) -> bool:
    try:
        ts_part, v1_part = header.split(",", 1)
        ts  = int(ts_part.split("=", 1)[1])
        sig = v1_part.split("=", 1)[1]
    except Exception:
        return False
    if abs(int(time.time()) - ts) > tolerance:
        return False
    expected = hmac.new(
        secret.encode(),
        f"{ts}.".encode() + body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, sig)
const crypto = require("crypto");

function verify(secret, rawBody, header, toleranceSec = 300) {
  const [tsPart, v1Part] = header.split(",");
  const ts  = Number(tsPart.split("=")[1]);
  const sig = v1Part.split("=")[1];
  if (Math.abs(Date.now() / 1000 - ts) > toleranceSec) return false;
  const expected = crypto
    .createHmac("sha256", secret)
    .update(`${ts}.`)
    .update(rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(
    Buffer.from(expected, "hex"),
    Buffer.from(sig, "hex"),
  );
}

Идемпотентные получатели

Используйте X-Mintbot-Event-Id как ключ дедупликации — повторы используют тот же id, поэтому строковый INSERT … ON CONFLICT DO NOTHING по этому столбцу делает ваш обработчик безопасным.


Ошибки

Каждый ответ с ошибкой содержит стабильный code, по которому можно ветвиться программно. Поле message — человекочитаемая подсказка, оно может меняться между релизами. request_id повторяет заголовок ответа X-Request-Id — указывайте его в обращениях в поддержку.

{
  "error": {
    "code": "invalid_api_key",
    "message": "API key is unknown or revoked.",
    "request_id": "f0c2d6c4-…"
  }
}
Code Значение
unauthenticated Отсутствует или некорректно сформирован заголовок Authorization.
invalid_api_key API key неизвестен или был выведен из обращения ротацией.
rate_limited Превышен лимит на партнёра или на IP — см. Retry-After.
missing_idempotency_key Запрос POST без Idempotency-Key.
idempotency_key_mismatch Тот же ключ повторно использован с другим телом запроса.
validation_error Тело запроса не прошло проверку схемы.
not_found Ресурс не существует или не принадлежит вашему партнёру.
payment_gateway_error Stripe отклонил создание сессии Checkout.

Rate limits

  • 120 requests / 60 s rolling window на партнёра. Burst и steady-state используют один и тот же bucket.
  • 60 requests / 60 s — отдельный bucket на IP для неаутентифицированных запросов и запросов с неудачной аутентификацией, чтобы brute-force bearer не расходовал партнёрскую квоту.
  • Лишние запросы возвращают 429 rate_limited с заголовком Retry-After (секунды ожидания).

Нужна помощь?

Эта документация написана для партнёров, которые реально пользуются API. Если чего-то не хватает, что-то непонятно или устарело, скажите об этом своему агенту mintbot — он передаст обратную связь, и мы обновим страницу.