Як прибрати помилку 429 «Too Many Requests» на toncenter
Помилка 429 «Too Many Requests» на toncenter: чому вона б’є по ШІ-агентах, швидкий фікс бекофом і справжнє рішення — власний ключ із гарантованим throughput.
Токен-агент на TON падає в найневдаліший момент: користувач просить «покажи мій баланс і останні угоди», агент чесно йде в toncenter — а у відповідь прилітає не JSON з даними, а сухе HTTP 429 Too Many Requests. Агент за один тік спробував зібрати баланс гаманця, стан акаунта, історію транзакцій і смикнути пару get-методів — і публічний toncenter зачинив двері вже на другому запиті. Користувач бачить «щось пішло не так», а ви — стіну червоних логів з одним і тим самим статусом. Це не баг вашого коду. Це публічний rate limit toncenter, у який упирається будь-який агент, щойно починає працювати активніше за один запит на секунду.
Розберімо, звідки береться toncenter 429, чому саме ШІ-агенти ловлять Too Many Requests на TON найчастіше, як швидко збити частоту помилок бекофом — і як прибрати стелю зовсім, перейшовши на власний ключ із гарантованою пропускною здатністю.
Що означає 429 «Too Many Requests» на toncenter
Код 429 — це стандартна HTTP-відповідь «занадто багато запитів». Сервер не зламався і не відхилив ваші дані: він просто каже, що ви перевищили дозволену частоту звернень і вас пригальмовують (rate limiting). У toncenter (v2) тіло відповіді при цьому має приблизно такий вигляд:
{ "ok": false, "error": "Rate limit exceeded", "code": 429 }
Ключове: "ok": false і "code": 429 — це HTTP-статус, продубльований у тілі, а не внутрішній код помилки контракту. І зверніть увагу: поля result з даними акаунта тут узагалі немає — текст ліміту лежить у полі error. Тож якщо ваш код одразу тягне дані з result, він отримає undefined і, найімовірніше, впаде десь далі по стеку з невиразною помилкою парсингу — хоча справжня причина лежить в error. Правило просте: коли ok: false, спершу перевіряйте code і читайте error, а не розбирайте неіснуючий result.
Окремо про фольклор: у TON-ком’юніті гуляє «помилка 228». Це не код API, а мем — жоден сервер вам 228 не поверне. Реальний код ліміту — саме 429, і шукати в документації треба саме його. 429 — тимчасова помилка: той самий виклик пройде, якщо зробити його повільніше або з валідним ключем.
Чому без ключа toncenter дає ~1 запит/с
Публічний toncenter без API-ключа обмежує вас приблизно одним запитом на секунду. Це не баг і не жадібність — це захист спільного безкоштовного ресурсу, яким користуються тисячі людей одночасно. Кілька нюансів, на яких спотикаються навіть досвідчені розробники:
- Спільний пул — це про анонімний трафік. Без ключа ви ділите єдиний публічний ліміт приблизно в 1 rps з усіма безіменними запитами з усього світу. У годину пік реально доступна вам частота може виявитися навіть нижчою.
- Платний ключ піднімає стелю — але тільки якщо він справді переданий у запиті. Класична пастка: ключ є, а заголовок
X-API-Keyзагубився під час рефакторингу HTTP-клієнта, і ви знову сидите на публічному ліміті, годинами не розуміючи, чому платний тариф «не працює».
Один запит на секунду — це нормально для ручного дебагу в браузері чи скрипта, який раз на хвилину перевіряє баланс. Для будь-якої автоматизації, а тим паче для агента, це вбивчо мало.
Чому ШІ-агенти ловлять 429 найчастіше: берст-патерн
І ось тут починається найцікавіше. Звичайний застосунок шле запити більш-менш рівномірно. ШІ-агент працює інакше — берстами (burst, сплеск). Він живе тіками: на одному кроці міркування йому треба зібрати контекст, і він смикає десятки викликів поспіль, майже одночасно.
Уявіть один крок: «користувач просить перевірити, чи прийшов платіж». Щоб відповісти, агент за частки секунди смикає поспіль:
get_masterchain_info— дізнатися поточну голову блокчейна;get_balance— баланс гаманця;get_account_state— статус і прапорці акаунта;get_transactions— останні транзакції;run_get_method— прочитати get-метод контракту;get_jetton_balance— а заразом і баланс USDT.
Шість викликів за один тік. Ліміт — один на секунду. Перший пройде, а решта повернуть 429, і агент або застрягне, або почне галюцинувати на неповних даних. Причому це не «кривий агент» — це нормальна архітектура автономного міркування: збери контекст, потім думай. Ба більше, впіймавши помилки, агент часто намагається «полагодити» їх повторними викликами — і добиває вже вичерпану квоту. Публічний ліміт просто не розрахований на такий профіль навантаження.
Схожа історія і з публічними лайтсерверами з глобального конфігу TON — під навантаженням вони відповідають not ready або відвалюються по ADNL-таймауту. Про це окремо: чому лайтсервер відповідає «not ready» і що робити. І в tonapi.io та сама хвороба 429 — розбір тут.
Швидкий фікс: ретраї з експоненційним бекофом і Retry-After
Перше, що варто зробити просто зараз, — перестати бити в стіну на повній швидкості. Якщо 429 усе ж прилетів, не гатіть у сервер повторно одразу: це лише подовжує бан. Це паліатив — він знижує частоту 429, але не піднімає стелю. Правильний паліатив складається з чотирьох частин.
1. Експоненційний бекоф із джитером. Перед кожною наступною спробою чекайте довше, ніж перед попередньою, плюс випадкова добавка, щоб паралельні воркери не синхронізувалися і не били в одну й ту саму секунду.
async function fetchWithBackoff(url, opts = {}, maxRetries = 5) {
for (let attempt = 0; attempt < maxRetries; attempt++) {
const res = await fetch(url, opts);
if (res.status !== 429) return res;
// Пріоритет — Retry-After від сервера, інакше експонента з джитером
const retryAfter = res.headers.get("Retry-After");
const baseMs = retryAfter
? Number(retryAfter) * 1000
: Math.min(1000 * 2 ** attempt, 16000);
const jitter = Math.random() * 300;
await new Promise((r) => setTimeout(r, baseMs + jitter));
}
throw new Error("toncenter: 429 не відпустив після ретраїв");
}
2. Зважайте на заголовок Retry-After, якщо він прийшов. toncenter на 429 його зазвичай не надсилає, тому основну ставку робіть на власну формулу бекофу. Але якщо сервер усе ж указав, скільки чекати, — чекайте рівно стільки, а не вгадуйте (у коді вище саме це й робить гілка if (retryAfter)).
3. Обмежте конкурентність. Поставте перед toncenter чергу або семафор, який випускає не більше ~1 запиту на секунду. Тоді берст агента розтягнеться в часі: той самий список із шести викликів виконається послідовно, за ~6 секунд, але без жодного 429.
4. Кешуйте повторювані читання. get_masterchain_info у межах одного кроку можна запросити один раз і перевикористати. Метадані жетона (decimals, символ) не змінюються — читайте їх один раз. Баланс, який ви читали 300 мс тому, навряд чи змінився.
Це працює і робить агента ввічливішим, але визнаймо чесно: бекоф не піднімає стелю. Ви все ще замкнені в 1 rps, просто тепер чемно стоїте в черзі замість того, щоб падати. Користувач чекає секунди там, де міг би чекати мілісекунди. Для агента, якому важлива швидкість відгуку, це лікування симптому, а не хвороби. Інші обхідні шляхи публічних API — у добірці альтернатив toncenter на 2026.
Справжнє рішення: власний ключ і TON через MCP
Корінь проблеми в тому, що ви ділите вузький публічний канал із тисячами анонімних запитів. Єдиний спосіб прибрати 429 по-справжньому — отримати власну гарантовану пропускну здатність замість спільної квоти. Тоді берст агента з шести викликів проходить цілком, а не впирається в стіну на п’ятому, і агент може збирати контекст на повній швидкості. Ретраї з бекофом залишаються як страховка від мережевих збоїв, але перестають бути основним механізмом виживання.
І є шлях, який на додачу прибирає вовтузіння з HTTP-статусами взагалі. Якщо дані з TON потрібні саме ШІ-агенту, логічніше віддавати їх не сирою REST-відповіддю, яку треба парсити й обробляти на 429, а як готові інструменти через MCP.
MCP (Model Context Protocol) — стандарт, за яким ШІ-агенти (Claude, Cursor, ChatGPT/Codex, будь-який MCP-клієнт) викликають зовнішні інструменти. Замість того щоб учити агента правильно формувати HTTP-запит до toncenter, ловити 429, читати Retry-After і парсити JSON, ви даєте йому типізовані інструменти, а всю чорну роботу з мережею бере на себе сервер.
TONNode — це hosted MCP-сервер для TON, рівно 16 інструментів. Ті шість читань, якими агент зазвичай і пробиває ліміт toncenter, тут — готові виклики:
get_masterchain_info— голова мастерчейна;get_balance— баланс GRAM;get_account_state— статус, прапорці, остання транзакція;get_transactions— історія транзакцій;run_get_method— будь-який read-only get-метод контракту;get_jetton_balance— баланс жетона або USDT (адреса жетон-гаманця обчислюється он-чейн).
(До речі, GRAM — це перейменований у червні 2026 року Toncoin. Мережа й далі називається TON, змінилася лише назва монети.)
Під капотом пакет @tonnode/mcp працює за нативним протоколом TON — ADNL, без HTTP-прошарків. Тобто ви не просто міняєте один REST-ендпоінт на інший: агент спілкується з мережею напряму, а ви перестаєте вручну розгрібати HTTP-семантику лімітів. Пакет open source (MIT), лежить на npm і GitHub (tonnode/mcp).
Різниця на практиці: агенту більше не треба знати, що таке 429, Retry-After чи ADNL-таймаут. Він каже «дай баланс і останні транзакції цієї адреси» — і отримує структуровану відповідь. Той самий берст із шести викликів іде на сервер, у якого є пропускна здатність під вашим ключем, а не на спільний публічний ліміт.
Як підключити і з чого почати безкоштовно
Є два шляхи, і почати можна взагалі без реєстрації.
Безкоштовно й локально
Повний набір інструментів читання через публічний конфіг — просто додайте в налаштування вашого MCP-клієнта:
{
"mcpServers": {
"ton": {
"command": "npx",
"args": ["-y", "@tonnode/mcp"]
}
}
}
Жодних ключів, npx сам підтягне пакет. Цього досить, щоб спробувати й переконатися, що агент читає TON без жодного 429. Детальний розбір — у гайді про безкоштовний MCP для TON.
Hosted-ендпоінт із власним ключем
Коли потрібна гарантована пропускна здатність під реальне навантаження, підключаєте hosted-ендпоінт із власним ключем:
{
"mcpServers": {
"ton": {
"type": "http",
"url": "https://mcp.tonnode.io/mcp",
"headers": { "Authorization": "Bearer tn_live_…" }
}
}
}
Далі просто розмовляєте з агентом людською мовою — він сам обере потрібний інструмент:
«Перевір адресу
EQC…: візьми баланс черезget_balance, статус акаунта черезget_account_stateі останні 10 транзакцій черезget_transactions. Потім черезget_jetton_balanceподивися баланс USDT.»
Агент викличе потрібні інструменти в потрібному порядку — а не гатитиме наосліп у rate limit.
Тарифи
На всіх тарифах доступні всі 16 інструментів — платите ви лише за пропускну здатність:
| Тариф | Ціна | Пропускна здатність |
|---|---|---|
| Hobby | безкоштовно назавжди | 60 запитів/хв |
| Pro | $29/міс | 300 запитів/хв |
| Scale | $199/міс | 1200 запитів/хв |
Навіть безкоштовний Hobby на 60 запитів/хв — це зовсім інший режим, ніж публічний toncenter з його ~1 rps: ті самі ~60 запитів на хвилину, але вже гарантовано ваші, а не спільні з натовпом анонімів. Берст агента з десятка викликів проходить цілком, без жодного 429. Ключ Hobby видається одразу після входу, без картки.
Оплатити платні тарифи можна в GRAM або USDT у мережі TON через TonConnect, або в BTC/ETH/SOL та інших через рахунок xRocket у Telegram.
Кілька чесних застережень, щоб не було завищених очікувань: TONNode зараз закриває завдання читання й побудови транзакцій, але не пропонує як готові продукти pay-per-request, REST-API v2, вебхуки, SSE-стрими чи письмовий SLA з відсотками аптайму. Архівна нода з глибокою історією ще синхронізується — це пункт роадмапу, а не сьогоднішня гарантія. Усе, що описано вище, працює вже зараз.
Практичний план переходу
- Заберіть безкоштовний ключ Hobby (60 запитів/хв, без картки): tonnode.io/dashboard?plan=hobby.
- Пропишіть hosted-конфіг вище у свій MCP-клієнт.
- Замініть ручні виклики toncenter на інструменти
get_balance,get_account_state,get_transactions,run_get_method,get_jetton_balance. - Щойно агент упреться в 60 запитів/хв під навантаженням — переходьте на Pro за $29/міс (300 запитів/хв): tonnode.io/pricing.
Підсумок
429 «Too Many Requests»на toncenter — це означає, що ви вперлися в публічний ліміт ~1 rps, а не збій у вашому коді. (І це точно не «228» — такого коду не існує.)- ШІ-агенти ловлять його найчастіше через берст-патерн: десятки викликів за один тік міркування.
- Ретраї з експоненційним бекофом,
Retry-After, семафор і кеш знижують частоту 429, але стелю не рухають — і то ціною швидкості. - Справжній вихід — власний ключ із гарантованою пропускною здатністю. А якщо дані потрібні саме агенту, TONNode віддає ті самі читання TON як MCP-інструменти, і питання «як обробити 429» просто зникає з вашого коду.
Почніть безкоштовно: отримати ключ Hobby — 60 запитів/хв, без картки. Якщо в агента реальне навантаження і берсти щільні — одразу беріть Pro за $29/міс, 300 запитів/хв.
Дайте вашому агенту доступ до TON
16 MCP-інструментів: читання, некастодіальні свопи, кросчейн і гаманці. Безкоштовний тариф — 60 зап/хв, картка не потрібна.