Барлық мақалалар
6 мин оқу

tonapi.io және rate-лимиттер: 429 қатесін қалай жою керек

tonapi.io rate-лимиттен асқанда HTTP 429 қайтарады. 429 қатесін қалай жою керек, «228» неге тек мем және TONNode MCP арқылы өз кілтіңізді қалай аласыз.

tonapi429 қатесіrate limitTON APIMCPTONNode

tonapi 429: кешкі сегіз жарым, прод өртеніп жатыр, ал логтарда — қып-қызыл қабырға

TON-дағы ботыңыз жаңа ғана танымал бір топтамаға ілікті, пайдаланушылар ағылып келді, ал қосымша кенеттен бос баланстарды қайтара бастады. Логтарды ашасыз — сонда жүздеген жол:

HTTP 429 Too Many Requests

Таныс жағдай ма? Сіз баланстар мен транзакциялар тарихы үшін tonapi.io-ға барасыз, он пайдаланушыда бәрі мүлтіксіз жұмыс істеді, ал мыңында анонимді қатынау төбеге тіреліп қалды. Бұл — классика: трафик аз кезде жария API тегін әрі шексіз болып көрінеді. Жүктеме өсе бастасымен ол бөтелке мойнына айналады да, сіз tonapi 429-ды тобымен ала бастайсыз. Бұл — кодыңыздың багы да, «нода құлады» дегені де емес: бұл — жария API-дің rate limit-і, әрі ол болжамды түрде емделеді.

429 неге пайда болатынын, әйгілі «228»-дің бұған неге қатысы жоқ екенін, қандай фикстер шынымен көмектесетінін, сондай-ақ TON-ды оқу үшін ортақ анонимді пулдан TONNode MCP-сервері арқылы жеке лимитке қалай көшуге болатынын талдап көрейік.

tonapi.io неге 429 Too Many Requests қайтарады

tonapi.io — TON деректеріне арналған жария HTTP-API. Кез келген жария сервистегідей, онда да tonapi rate limit бар — бір клиент бүкіл сыйымдылықты жеп қоймауы үшін қойылған сұрау жиілігінің шектеуі.

Кілтсіз жүргенде сіз ортақ анонимді пулды планетадағы қалған барлық анониммен бөлісесіз. Іс жүзінде бұл — шамамен секундына ~1 сұрау лимиті. Бір скрипт үшін бұған шыдауға болады. Бірақ әр әмиян үшін алдымен балансты, содан кейін жетон-балансты, сосын тарихты сұрайтын параллель воркер қосылған сәтте — сіз секундтық лимиттен лезде асып кетесіз. Әсіресе бірден көп мекенжайды индекстеу керек болатын суық старт кезінде ауыр тиеді.

Сервер былай жауап береді:

HTTP/1.1 429 Too Many Requests
Retry-After: 1

Мынаны түсіну маңызды: 429 — спецификациядағы стандартты HTTP коды, tonapi-дің меншікті коды емес. Жиілік асып кеткенде оны кім болса да қайтарады — GitHub, Stripe, Cloudflare, кез келген rate-limited сервис. toncenter-де де, RPC-провайдерлердің көпшілігінде де дәл сол механизм. Демек, ол да стандартты тәсілдермен емделеді — солар туралы төменде.

«228 қатесі» — API коды емес, комьюнити мемі (нақты код — 429)

Мәселені орыстілді форумдарда гуглдаған болсаңыз, сізге «228 қатесі» міндетті түрде кездескен. Бәрін бірден нақтылап алайық, өйткені бұл жаңадан бастағандарды шынымен шатастырады.

«228» — tonapi-дің де, toncenter-дің де ресми қате коды емес. Бұл — TON-комьюнитиде әлдеқашан орныққан әрі чаттар мен әзілдерде қалқып шығатын мем-сан. Лимиттен асқанда сізге ешқандай 228 HTTP-статусы келмейді — HTTP-де ондай статус-код тіпті жоқ.

Логтарда және жауап тақырыптарында көретін нақты код — дәл 429. Чатта біреу «тонапиден 228 жеп алдым» деп жазса, шын мәнінде ол 429 алған (немесе кәдімгі таймаут), ал «228»-ді сөз айналымы ретінде қолданып отыр. Логтарыңыздан «228»-ді емес, 429-ды іздеңіз — нағыз себепті солай табасыз. Мұны бір жол кодпен тексеруге болады:

curl -s -o /dev/null -w "%{http_code}\n" https://tonapi.io/v2/blockchain/masterchain-head
# жүктеме кезінде кілтсіз мынаны көресіз: 429

Жылдам фикстер: ретрайлар, бэкофф, кэш және өз кілтіңіз

429 — стандартты жағдай болғандықтан, оның да емдеу жолдарының стандартты жинағы бар. Қарапайымнан бастап негізгісіне қарай жүреміз.

1. Retry-After-ды құрметтейтін экспоненциалды бэкофф

Алғашқы бас тартудан кейін-ақ эндпоинтті тығыз циклде сабалай бермеңіз — жағдайды тек ушықтырасыз. 429 кезінде сервер жиі Retry-After тақырыбын қайтарады — қанша секунд күту керегін. Оны құрметтеңіз, ал ол болмаса — үзілісті экспоненциалды түрде өсіріңіз.

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 = Number(res.headers.get('retry-after'));
    const waitMs = Number.isFinite(retryAfter) && retryAfter > 0
      ? retryAfter * 1000
      : Math.min(1000 * 2 ** attempt, 30_000); // 1s, 2s, 4s… шегі 30s

    await new Promise(r => setTimeout(r, waitMs));
  }
  throw new Error('429 кетпеді: ретрайлар саны асып кетті');
}

2. Бір мезгілдегі сұраулар санын шектеңіз

429 көбіне жалпы көлемнен емес, сіздің Promise.all арқылы 50 сұрауды «желпуішпен» жіберуіңізден келеді. Параллелизм лимиті (1–4) бар семафор қойыңыз — сонда секірістер секундтық лимитті теспей тегістеледі.

3. Өзгермейтін деректерді кэштеңіз

Жетонның метадеректері (атауы, символы, decimals), мекенжай конвертациясының нәтижесі, ескі транзакциялар — бұлар өзгермейтін деректер. Оларды ақылға қонымды TTL-мен локал кэшке салыңыз да, API-ден қайта сұрамаңыз. Тек жетондардың decimals кэшінің өзі ғана жүгінулердің байқарлықтай үлесін алып тастайды.

4. Басты фикс — аноним орнына өз кілтіңіз

Алғашқы үш тармақ — ауырсынуды басатын дәрі. Нағыз емдеу — анонимді пулдан өз кілтіңізге көшу. Жеке кілт лимитіңізді анонимдегі ~1 req/s-пен салыстырғанда ондаған есе көтереді; сіз бүкіл интернетпен бәсекелесуді қоясыз да, 429 күнделікті жұмыстан жай ғана кетеді. Көрші провайдер бойынша жеке жағдай toncenter-дегі 429 фиксінде талданған — логикасы бірдей.

tonapi лимиттері бәрібір жетпегенде не істеу керек

Айталық, сіз бәрін дұрыс істедіңіз: бэкофф, кэш, кезек. Бірақ қосымша өсіп келеді, әрі кілтпен де сіз не тарифке, не «нода үстіндегі HTTP-қабат» моделінің өзіне тірелесіз. Мұнда әдетте екі жол қарастырылады.

«Өз лайтсерверлерің» жолы. «TON-ның глобал конфигінен жария лайтсерверді алып, тікелей ADNL арқылы жүре беру» деген азғырық пайда болады. Адал ескертпе: бұл — күміс оқ емес. Глобал конфигтегі жария лайтсерверлер де ортақ әрі лимитті — жүктеме кезінде олар үнемі not ready деп жауап береді немесе ADNL-таймаутпен үзіледі, әрі терең транзакция тарихын сақтамайды. Тағы бір жиі кездесетін ауыртпалық — дәл сол not ready, оның талдауы «liteserver not ready»-ді қалай жөндеу керек деген жазбада. Яғни жай ғана «жария конфигке көшу» лимит мәселесін шешпейді, кейде тіпті ушықтырады.

«Провайдерді/интерфейсті ауыстыру» жолы. Мәселе нақты tonapi.io-да емес, сіздің ортақ ресурста отырғаныңызда. HTTP-API баламаларына шолу 2026 жылғы tonapi баламаларында жиналған. Ал егер сіз ЖИ-агент құрып жатсаңыз, REST-ті қолмен орап әуре болмай, TON-ды MCP арқылы құралдар жинағы ретінде қосқан жөн — сонда блокчейнді оқу ретрай жасауды талап ететін шикі HTTP-сұрау емес, құрал шақыруына айналады.

TONNode MCP: ортақ анонимді пулдың орнына жеке лимит

TONNode (сайты — tonnode.io) — бұл TON үшін hosted MCP-сервер. MCP (Model Context Protocol) — ЖИ-агенттер (Claude, Cursor, ChatGPT/Codex және кез келген MCP-клиент) сыртқы құралдарды шақыратын стандарт. Агентке https://tonapi.io/v2/... мекенжайына сұрау жасауды және 429-ды өңдеуді үйретудің орнына, сіз оған TON-ды оқуға арналған аты бар құралдардың жинағын бересіз.

Түйінді тұс: @tonnode/mcp пакеті TON-ның нативті ADNL-протоколы бойынша, HTTP-қабаттарсыз жұмыс істейді. Ол — open source (MIT), npm мен GitHub-та (tonnode/mcp) жатыр. Бұл — tonapi үстіндегі тағы бір REST-враппер емес, желімен тікелей сөйлесу.

Сіз tonapi-ге не үшін барсаңыз, сол типтік сұраулардың бәрі оқу құралдарымен бірме-бір жабылады:

  • get_balance — мекенжайдағы GRAM балансы.
  • get_jetton_balance — USDT немесе кез келген жетонның балансы; жетон-әмиян он-чейн есептеледі, оның мекенжайын өзіңіз шығарудың қажеті жоқ. Мұның бірнеше сұраудан тұратын байламды қалай алмастыратыны — TON-дағы USDT балансы бір шақырумен деген жазбада.
  • get_account_state — аккаунт статусы, флагтар, соңғы транзакция.
  • get_transactions — транзакциялар тарихы.
  • run_get_method — контрактінің кез келген read-only get-әдісі.
  • get_masterchain_info — мастерчейннің басы (ағымдағы блок).
  • get_jetton_info — жетонның метадеректері: атауы, символы, эмиссиясы және decimals (USDT-де — 6, жетондардың көпшілігінде — 9; онсыз raw-бірліктерді дұрыс қайта есептей алмайсыз).
  • parse_address — EQ/UQ/raw мекенжайларын офлайн конвертациялау және тексеру, желіге мүлдем жүгінбей.

Нейминг туралы шағын ескертпе: GRAM — 2026 жылдың маусымында атауы өзгертілген Toncoin. Желі бұрынғысынша TON деп аталады, тек монетаның аты ғана өзгерді. get_balance баланстары — GRAM-мен.

Агент қолмен жазылған HTTP арқылы емес, құралдар арқылы орындайтын промпт мысалы:

Мына мекенжай бойынша GRAM балансы мен USDT балансын тексер
UQBvW8Z5huBkMJYdnfAEM5JqTNkuWX3diqYENkWsIL0XF_wm
және осы әмиянның соңғы 5 транзакциясын көрсет.

Агент get_balance-ты, содан кейін get_jetton_balance-ты (жетон-әмиянды он-чейн есептеп), сосын get_transactions-ты өзі шақырады — сіз жазған бірде-бір HTTP-сұраусыз, Retry-After-сыз және кодыңыздағы қолмен жасалған бэкоффсыз.

Бір минутта қалай қосу керек: әзірлеу үшін локал немесе прод үшін hosted-кілт

Екі тәсіл бар, әрі екеуі де адал. Оларды шатастырмау маңызды: кілтсіз локал npx әзірлеуге ыңғайлы, бірақ ол TON-ның жария конфигінде жұмыс істейді; жүктеме кезіндегі 429 ауыртпалығын алып тастайтын жеке лимитті дәл hosted-кілт береді.

A нұсқасы — локал, тегін, кілтсіз (әзірлеу үшін)

Оқу құралдарының толық жинағы npx арқылы бір-ақ командамен көтеріледі — тіркелудің де, картаның да қажеті жоқ. MCP-клиенттің конфигіне қосыңыз:

{
  "mcpServers": {
    "ton": {
      "command": "npx",
      "args": ["-y", "@tonnode/mcp"]
    }
  }
}

Локал әзірлеу мен тексеру үшін мінсіз старт: оқудың толық жинағы, нөлдік конфигурация, капот астында open source. Бірақ адал ескертпе: бұл режим TON-ның жария конфигі арқылы жүреді, яғни кез келген жария лайтсервермен бірдей ортақ шектеулерге ұшырайды (not ready, жүктеме кезіндегі ADNL-таймауттар). Прод-трафик үшін бұл — жеке лимиттің баламасы емес; ол үшін B нұсқасына барыңыз.

B нұсқасы — өз кілтіңіз бар hosted-эндпоинт (прод үшін)

Кепілді өткізу қабілеті және прод жүктемесі кезінде жеке лимит керек болғанда, өзіңіздің Bearer-кілтіңіз бар hosted-эндпоинтті қосасыз:

{
  "mcpServers": {
    "ton": {
      "type": "http",
      "url": "https://mcp.tonnode.io/mcp",
      "headers": { "Authorization": "Bearer tn_live_…" }
    }
  }
}

Тарифтер

Барлық тарифте TONNode-тың 16 құралының бәрі қолжетімді — сіз тек өткізу қабілеті үшін төлейсіз:

  • Hobby — мәңгі тегін, минутына 60 сұрау. Кілт кірген бойда, картасыз беріледі.
  • Pro — айына $29, минутына 300 сұрау.
  • Scale — айына $199, минутына 1200 сұрау.

Анонимді tonapi-мен айырмашылық айқын: онда сіз ~1 req/s-ті бүкіл интернетпен бөлісесіз, ал мұнда сізде жеке төбе бар — тегін Hobby hosted-кілтінде-ақ бұл тек өзіңізге арналған минутына 60 сұрау, бэкоффпен әуре болмай және кездейсоқ 429-сыз. Бұл — кілтсіз локал npx-пен бірдей тегін жол емес: Hobby hosted-кілтінде ортақ жария пул емес, өз лимитіңіз болады.

Қорытынды

tonapi.io-дан келген 429 — баг та, аңызға айналған «228» да емес, адал сигнал: сіз ортақ анонимді пулда отырсыз және оның төбесіне тірелдіңіз. Бэкоффпен жасалған ретрайлар, Retry-After-ды құрметтеу, бір мезгілдегі сұраулар санын шектеу және кэш өткір ауырсынуды басады. Бірақ мәселе шын мәнінде тек өз сыйымдылығыңыз пайда болғанда ғана кетеді — ал ЖИ-агенттерге сүйеніп құрып жатсаңыз, мұны MCP арқылы істеген тіпті ыңғайлы: онда TON-ды оқу HTTP-қабат арқылы емес, нативті протокол бойынша жүреді.

Тегін Hobby hosted-кілтін алыңыз (60 req/min, картасыз) және 429 қатесін ұмытыңызtonnode.io/dashboard?plan=hobby

Прод-жүктемеге қор керек болса — Pro мен Scale тарифтерін салыстырыңыз: tonnode.io/pricing.

Агентіңізге TON-ға қолжетімділік беріңіз

16 MCP-құрал: оқу, кастодиалды емес сваптар, кроссчейн және әмияндар. Тегін тариф — 60 сұрау/мин, карта керек емес.