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.modebyo(вы приносите собственный apex-домен) илиhosted(mintbot предоставляет субдомен*.mintbot.ai). Приhostedполя DNS-провайдера намеренно пусты, независимо от того, что партнёр вводил ранее.domain.subdomain_label_preview- Готовая метка, которую получил бы первый клиентский агент (
agent1,1,001, …) при текущихsubdomain_prefix,subdomain_numberingиsubdomain_pad_width. Используйте её для превью «вот что увидят ваши клиенты», не переписывая правила нумерации. bot.modeown(Telegram-бот, предоставленный партнёром),borrow(использование бота mintbot во время тестирования) илиweb(только панель, без Telegram).template.modedefault(нет репозитория кастомизации агента — агент работает на чистой небрендированной базе) или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 — он передаст обратную связь, и мы обновим страницу.