Қысқаша
Бір API кілт минутына 600 оқу (GET) және 200 жазу (POST, PATCH, DELETE) сұрауын жібере алады. Шектен асса API 429 күйін және request_rate_limited кодын қайтарады, Retry-After тақырыбында қанша секунд күту керегін айтады. Әр жауапта X-RateLimit-Remaining тақырыбы сол минутта қанша сұрау қалғанын көрсетеді.
Бірақ 429 жауабының бәрі жиілікке байланысты емес. tariff_daily_burst пен tariff_limit_reached те сол HTTP кодымен келеді, ал олар — тариф лимиті: бірнеше секунд күткеннен өтпейді. Сондықтан кодыңыз 429-ды көргенде бірден қайталамай, алдымен error өрісін оқуы керек.
Нақты шектер
| Не | Шек | Есептегіш |
|---|---|---|
| GET (оқу) | минутына 600 | әр API кілтке бөлек |
| POST, PATCH, DELETE (жазу) | минутына 200 | әр API кілтке бөлек |
| Төлем бетінің ашық сұраулары | минутына 120 | IP мекенжай бойынша |
Терезе — тұрақты бір минут: минут біткенде есептегіш нөлден басталады. Екі API кілт жасасаңыз, әрқайсысының есептегіші бөлек жүреді — бұл әр жобаға бөлек кілт беруге ыңғайлы, бірақ шектен өту үшін кілт көбейтудің қажеті жоқ: қалыпты дүкен бұл шекке ешқашан жетпейді.
X-RateLimit-Remaining тақырыбы әр сәтті жауапта келеді. Мониторингіңізде сол санды жазып қойсаңыз, шекке жақындап қалғаныңызды алдын ала көресіз.
429-дың үш түрі
| Код | Қайдан келеді | Не болды | Не істеу керек |
|---|---|---|---|
request_rate_limited | API (/api/v1/*) | Кілттің минуттық жиілігі асып кетті | Retry-After көрсеткен секундты күтіп қайталаңыз |
rate_limited | Кабинетке кіру коды | Кодты 60 секунд ішінде қайта сұрадыңыз немесе тәуліктік код лимиті бітті | Бір минут күтіңіз. Жауапта retryAfterSeconds өрісі болады |
too_many_attempts | Кодты енгізу | Қате код тым көп рет енгізілді | Жаңа код сұраңыз, ескісін теруді тоқтатыңыз |
rate_limited пен too_many_attempts — кабинетке кіру процесіне қатысты, сіздің серверлік интеграцияңызда әдетте кездеспейді. Егер кездессе, демек кодыңыз кіру эндпоинттерін шақырып тұр.
Жиілік пен лимитті ажырату
Бұл екеуін шатастыру — ең жиі кездесетін қате. Лимит бітсе, қанша күтсеңіз де сол минутта өтпейді.
| Код | Түрі | Қашан өтеді | Қайталауға бола ма |
|---|---|---|---|
request_rate_limited | Жиілік | Бірнеше секундтан кейін | Иә, Retry-After бойынша |
tariff_daily_burst | Тәуліктік қорғаныс | Тәулік ауысқанда | Жоқ. Алдымен кодыңызды тексеріңіз — бұл әдетте циклге түскен интеграция |
tariff_limit_reached | Айлық тариф лимиті | Жаңа ай басталғанда немесе тарифті көтергенде | Жоқ. Кабинет → Тариф |
Соқыр қайталау мына жағдайда қауіпті: tariff_daily_burst келгенде цикл тоқтамай, сағаттар бойы сұрау жіберіп тұрады. Толығырақ: Тарифтер және лимиттер.
Retry-After тақырыбы
request_rate_limited жауабында Retry-After тақырыбы секундпен келеді — бұл ағымдағы минуттық терезенің аяқталуына қалған уақыт. Оны оқып, дәл сонша күту ең дұрыс тактика: ертерек қайталасаңыз тағы 429 аласыз.
Тақырып жоқ болса (мысалы прокси кесіп тастаса), 1 секундтан бастап екі есе өсіретін бэкоффқа көшіңіз.
Кодта қалай өңдеу керек
Ережесі қарапайым: error кодын оқыңыз, соған қарай шешім қабылдаңыз.
const RETRYABLE = new Set(['request_rate_limited', 'rate_limited']);
async function callWithRetry(fn, { maxAttempts = 5 } = {}) {
const delays = [1000, 2000, 4000, 8000]; // 1, 2, 4, 8 секунд
for (let attempt = 0; attempt < maxAttempts; attempt++) {
try {
return await fn();
} catch (err) {
// Тариф лимиті — күту көмектеспейді, бірден тоқтаймыз
if (err.code === 'tariff_limit_reached' || err.code === 'tariff_daily_burst') throw err;
if (!RETRYABLE.has(err.code) && !(err.status >= 500)) throw err;
if (attempt === maxAttempts - 1) throw err;
const retryAfter = Number(err.retryAfterSeconds || 0) * 1000;
const wait = retryAfter || delays[Math.min(attempt, delays.length - 1)];
await new Promise((r) => setTimeout(r, wait + Math.random() * 300));
}
}
}
Соңындағы кездейсоқ қосымша (Math.random()) — джиттер. Бірнеше процесс қатар жұмыс істесе, олар дәл бір сәтте оянып, тағы 429 алмау үшін керек.
Счёт жасауды қайталағанда әрқашан сол Idempotency-Key мәнін жіберіңіз — әйтпесе бірінші сұрау шын мәнінде өтіп кетіп, қайталауыңыз екінші счёт жасауы мүмкін. Толығы: Идемпоттылық.
Жиілікке мүлдем жетпеу
| Сценарий | Дұрыс тәсіл |
|---|---|
| Көп счётты бір уақытта шығару | POST /api/v1/invoices/bulk — бір сұрауда 100 счёт: Топтап счёт жасау |
| Төлемді күту | Webhook негізгі арна болсын, сұрауды тек алғашқы 30 секундта қосыңыз: Webhook пен күйді сұрау |
| Барлық счётты үнемі тексеру | GET /invoices тізімін сүзгімен алыңыз, әрқайсысын жеке сұрамаңыз |
| Есеп жасау | Тәулігіне бір рет экспорт, әр беттеу үшін бөлек сұрау емес |
Ең жиі кездесетін себеп — циклде GET /invoices/{id} шақыратын, бірақ тоқтау шарты жоқ код. Әр сұрау циклінде шығу шартын жазып қойыңыз.
Жиі қойылатын сұрақтар
429 алдым, бірақ Retry-After жоқ. Демек бұл request_rate_limited емес, тариф коды. error өрісін қараңыз.
Шектеу счёт санына әсер ете ме? Жоқ. Жиілік — бұл минутына сұрау саны, ал тарифтегі сан — айына жасалған счёт саны. Екеуі бөлек есептеледі.
Шекті көтеруге бола ма? Стандартты шектер қалыпты жүктемеге жеткілікті. Нақты сценарийіңіз оған сыймаса, қолдауға жазыңыз.
Sandbox-та шектер басқа ма? Жиілік шектері бірдей. Ал тариф лимиттері sandbox счёттарына қолданылмайды.
Бірнеше сервер бір кілтпен жұмыс істеп жатыр. Есептегіш кілт бойынша ортақ, сондықтан шек барлық серверге бірге қолданылады. Жүктемені бөлу керек болса, әр сервиске бөлек кілт беріңіз.