PayBot ограничивает частоту запросов: базовый лимит API — 20 запросов в минуту на ключ. При превышении приходит 429 с кодом rate_limit_exceeded. Читайте заголовки X-RateLimit-Limit, X-RateLimit-Remaining и X-RateLimit-Reset, чтобы притормаживать заранее, а на 429 — повторять запрос с экспоненциальным backoff, ориентируясь на X-RateLimit-Reset.
Лимиты не действуют для тарифа enterprise и для ключей в тестовом режиме (kp_test_...) — там частота не ограничивается.
Какие лимиты действуют
| Лимит | Значение |
|---|---|
| API (общий) | 20 запросов/мин на ключ |
Аутентификация (/auth/*) | 10 запросов/мин |
| Checkout — данные ссылки | 60/мин на токен+IP |
| Checkout — статус (поллинг) | 120/мин (не чаще ~1 раза в 500 мс) |
| Checkout — обновление QR | 10/мин (только при истёкшем qr_expires_at) |
| Checkout — email плательщика | 20/мин |
| Платежи в месяц | trial 30 / starter 200 / professional 1500 / enterprise 999999 |
Помимо частотного лимита есть месячный лимит числа платежей по тарифу. Его превышение — это не rate_limit_exceeded, а отдельный код plan_limit_exceeded (тоже 429), который стоит показывать как апселл, а не как ошибку. О различии кодов — в разделе коды ошибок.
Заголовки ответа
На каждый ответ API проставляет три заголовка (они проброшены в CORS-expose, поэтому доступны из браузера).
| Заголовок | Значение |
|---|---|
X-RateLimit-Limit | сколько запросов в окне разрешено |
X-RateLimit-Remaining | сколько запросов осталось в текущем окне |
X-RateLimit-Reset | когда окно сбросится (используйте для backoff) |
Читайте X-RateLimit-Remaining после каждого ответа: если он близок к нулю, притормозите отправку заранее, не доводя до 429.
Что делать при ошибке 429
429 означает, что вы превысили лимит. Не ретрайте немедленно в цикле — это только продлевает блокировку. Подождите до момента из X-RateLimit-Reset и повторяйте с экспоненциальным backoff (задержка удваивается с каждой попыткой) плюс небольшой случайный джиттер, чтобы параллельные клиенты не били синхронно.
import time
import random
import requests
def request_with_backoff(method: str, url: str, max_retries: int = 5, **kwargs):
delay = 1.0
for attempt in range(max_retries):
resp = requests.request(method, url, **kwargs)
if resp.status_code != 429:
return resp
reset = resp.headers.get("X-RateLimit-Reset")
try:
wait = max(float(reset) - time.time(), 0) if reset else delay
except ValueError:
wait = delay
time.sleep(wait + random.uniform(0, 0.5)) # джиттер против синхронных ретраев
delay *= 2
return resp
resp = request_with_backoff(
"GET",
"https://api.paybot.kz/v2/payments",
headers={"X-API-Key": "kp_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"},
)Для идемпотентных POST (создание QR, счёта, возврата) повторяйте запрос с тем же Idempotency-Key, чтобы ретрай после 429 не создал дубликат операции — см. идемпотентность.
Исключения из лимитов
Частотный лимит не применяется в двух случаях:
- •Тариф
enterprise— запросы не ограничиваются по частоте. - •Тестовый режим ключа (
kp_test_...) — обходятся и rate-limit, и проверка живости сессии Kaspi, работает sandbox.
Это удобно для нагрузочной отладки: гоняйте интеграцию на тестовом ключе без риска упереться в лимит, а на боевом закладывайте backoff. Подробнее про тестовый режим — в разделе тестирование.
FAQ
Как понять, что я близок к лимиту, до 429?
Смотрите X-RateLimit-Remaining в каждом ответе. Когда остаток мал, замедлите отправку сами — это надёжнее, чем ловить 429 и откатываться.
Чем rate_limit_exceeded отличается от plan_limit_exceeded?
rate_limit_exceeded — вы шлёте слишком часто (частотный лимит, ~20/мин), лечится backoff. plan_limit_exceeded — исчерпан месячный лимит платежей по тарифу, backoff не поможет: нужен апгрейд плана, поэтому показывайте апселл.
Poll-ить статус checkout можно как часто?
До 120 запросов в минуту на токен, то есть не чаще примерно раза в 500 мс. QR обновляйте (refresh-qr) только по факту истечения qr_expires_at — там лимит жёстче, 10/мин.
Считается ли в лимит платежей неоплаченный QR?
Месячный лимит тарифа считает оплаченные платежи. Частотный же лимит (20/мин) считает сами HTTP-запросы независимо от исхода.
Смежные разделы
- •Коды ошибок — как обрабатывать
429и различать коды лимитов. - •Тестирование — тестовый режим без ограничений частоты.