Por qué tu bot recibe 403 de Cloudflare (y cómo endurecer un cliente ccxt)
Si automatizas un exchange con ccxt , tarde o temprano lo verás en los logs: rachas cortas de 403 Forbidden que pegan a fetch_balance , a los OHLCV o al saldo de earn, y que desaparecen solas a los pocos minutos. No es que tu API key esté mal. Es el WAF (Cloudflare) que muchos exchanges ponen delante de su REST, challengueando a algo que "parece un bot". Y tu bot es un bot — pero uno legítimo ,…
When automating an exchange with ccxt, you will eventually encounter short bursts of 403 Forbidden errors in the logs, affecting calls to fetch_balance, OHLCV data, or earn balance, only to disappear after a few minutes. This is not due to a malfunctioning API key; it is the WAF (Cloudflare) put in front of the exchange's REST API, challenging suspected bot activity.
Your bot is legitimate and operates your own account against the official API; the issue lies in the client's HTTP reputation. Two layers can mitigate this false positive issue, rather than evading any access controls.
First, reduce the frequency with which the WAF challenges your client by hardening it. A default ccxt client announces itself as such; adjusting a user-agent resembling a browser, adding an Accept-Language header, and using a relaxed timeout will make Cloudflare challenge your client less often. The harden function from the ccxt_resilience library takes an already-built ccxt client, returns the same object (chainable), and never alters its construction. If any attribute-setting fails, the attributes remain unchanged.
Second, retry only what is transient. It is tempting to wrap everything in a try/except block that retries, but this is a trap. Retrying authentication or fund-related errors only wastes time, ends in the same failure, and hides logic bugs behind delays. The key is to retry only transitory issues like 403/Cloudflare, 429, and timeouts, using exponential backoff with jitter, and re-raising real errors at the moment.
Authentication errors are immediately re-raised without retrying, and if all attempts fail, the last exception is re-raised so your fail-safe handler (e.g., returning the last cached value) can handle it.
Explicitly classify which exceptions are transient, so you can inspect and replace the behavior if needed. The is_transient_error function from ccxt_resilience can identify a 403 Forbidden Cloudflare error but not an invalid API key. It also classifies exceptions by type (like DDoSProtection, RequestTimeout) with ccxt installed; without it, it relies on the exception message.
This makes ccxt a soft dependency—it works with or without ccxt installed. If your case involves another API, with_retry accepts your own retry predicate. Install the library via pip install ccxt-resilience. The code, tests, and details are available in the repo: github.com/isazajuancarlos/ccxt-resilience. This is lightweight infrastructure without state, so use it selectively.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.
