YOUR EXIT IP IS ONE SIGNAL. BOT MANAGEMENT READS THE WHOLE REQUEST.

2026-11-12 · proxies / bot management · ~14 min read · provenance tagged inline
TL;DR for agents. ESTABLISHED: Cloudflare documents a bot score built from request features (headers, session characteristics, browser signals), TLS fingerprints, heuristics that include header order, JavaScript detections and a clearance cookie tied to the visitor and device, and the site owner writes the rules that act on it, including rules on IP, ASN and country. ESTABLISHED: a forward proxy replaces the source address and the TCP connection and forwards everything above them untouched, so a new exit cannot repair a request whose TLS, HTTP or browser layer was what got scored. OURS: our public stock endpoint returns counts per country and IP class, a held session is the -sid- username token, and we publish no per-IP reputation score and no pass rate; jump to what to do.

WHAT WAS REPORTED

REPORTED: customer reports to Proxies.sx support during 2026. They are self-reported and came without a shared reproduction; we have not measured them. Treat them as directional.

REPORTED: Customers running public data collection tell us that some requests through mobile and residential exits are challenged or refused on sites behind Cloudflare, and that taking a new IP often changes nothing. The reports rarely carry the three facts that would locate the cause: which response came back (a Challenge Page, a numbered error or a rate limit), which client software made the request, and whether cookies were kept between requests. Without those a report cannot say which layer was scored, so it cannot say that the address was the reason.

WHAT DECIDES THE OUTCOME

ESTABLISHED: every statement in this section comes from Cloudflare's developer documentation, the JA4+ repository, an RFC or a vendor white paper, linked at the end of each paragraph and read on 12 November 2026. None of it depends on the reports above.

Cloudflare scores, the site owner decides

ESTABLISHED: Cloudflare describes the bot score as a score from 1 to 99 that indicates how likely that request came from a bot: 1 is automated, 2 through 29 likely automated, 30 through 99 likely human, and 0 means the request was not scored. Site owners use it to block, challenge, or allow requests based on their score in their own rules. The threshold belongs to each site, so there is no single bar called passing Cloudflare: one site can serve a request that another challenges. Cloudflare: Bot scores.

ESTABLISHED: Several engines feed the score. Heuristics match requests against a growing database of malicious fingerprints and give deterministic matches a score of 1; a request with a missing or empty User-Agent is scored 1 at this stage. The machine learning engine, which Cloudflare says accounts for the majority of all bot detections, takes request features, including headers, session characteristics, and browser signals. JavaScript Detections run a script in the page to identify headless browsers and other malicious fingerprints. Cloudflare tells site owners that bot scores can shift as the model learns. Cloudflare: Bot detection engines · How Cloudflare generates bot scores.

The address: IP, ASN and country

ESTABLISHED: The address is an explicit input to site rules. IP Access rules allowlist, block, and challenge traffic based on the visitor's IP address, Autonomous System Number (ASN), or country, the rules language exposes the client's AS number as ip.src.asnum, and Enterprise sites can match Managed IP Lists that Cloudflare maintains for known open HTTP and SOCKS proxy endpoints, anonymizers and VPN servers. On the scoring side, the release note for machine learning model v8 reads Improved detection of residential proxies. Increased weight on network level traffic characteristics. Cloudflare does not publish how an individual address is weighted. IP Access rules · ip.src.asnum · Managed Lists · Machine Learning models.

ESTABLISHED: Reputation by address is coarse wherever addresses are shared. RFC 6269 describes it for carrier-grade NAT: when a server puts an address in a penalty box or demands a CAPTCHA, the other subscribers behind that address are caught by it. Where a site enables it, Cloudflare's rate limiting sets a cookie, _cfuvid, used to distinguish individual users who share the same IP address, and states that visitors who do not provide it are likely to be grouped together. The operational inference is that on a shared address a client that discards cookies is counted with everyone else behind it. RFC 6269 §13.1 · Cloudflare cookies.

TLS: JA3 and JA4 describe the client

ESTABLISHED: JA3 and JA4 identify TLS clients based on how they initiate connections, and the fingerprint acts as a stable identifier across different destination IPs, ports, and certificates. JA4 is computed from the ClientHello: transport, TLS version, whether SNI is present, the number of cipher suites and extensions, the first ALPN value, then a hash of the sorted cipher list and a hash of the sorted extension list with the signature algorithms. Sorting is what separates it from JA3, and Cloudflare notes that it reduces the number of unique fingerprints for modern browsers. Cloudflare: JA3/JA4 fingerprint · JA4 specification · RFC 8446 §4.1.2.

ESTABLISHED: Cloudflare aggregates traffic per fingerprint across its network. Its Signals Intelligence fields report, for each JA4 over the last hour, the share of requests originating from browser-based user agents (browser_ratio_1h), how many distinct user agents and client IPs use it (uas_rank_1h, ips_rank_1h), its request volume, and the share already flagged by heuristics (heuristic_ratio_1h). The operational inference is that a fingerprint is judged together with the rest of the traffic that shares it: the ClientHello of an HTTP library is one Cloudflare mostly sees from non-browsers, whatever User-Agent a single request carries. Cloudflare: Signals Intelligence.

HTTP: header order is a documented check

ESTABLISHED: RFC 9110 states that the order in which field lines with differing field names are received in a section is not significant. Each implementation is therefore free to pick its own order, and the order identifies the implementation. Cloudflare gives exactly this as its example of a heuristic: a detection ID can identify when a client sends headers in a different order than what its claimed browser would use. JA4H, the HTTP member of the JA4+ suite, hashes the header names in the order they were sent, together with the method, version, cookie and referer presence, header count and language. RFC 9110 §5.3 · Cloudflare: Detection IDs · JA4H reference implementation.

ESTABLISHED: HTTP/2 exposes more implementation choices. RFC 9113 says settings are not negotiated; they describe characteristics of the sending peer, and Akamai's 2017 white paper found a consistent variation between client implementations in the SETTINGS, WINDOW_UPDATE and PRIORITY frames and in the order of request pseudo-header fields, enough to fingerprint them passively. Cloudflare's Bot Management documentation names no HTTP/2 fingerprint field. What it publishes is h2h3_ratio_1h, the share of a JA4's requests made over HTTP/2 or HTTP/3, and a model v7 note that reads Improved HTTP/3 scoring. Treat the HTTP/2 fingerprint as an established technique that a site's stack may apply, not as a documented Cloudflare input. RFC 9113 §6.5 · Akamai: Passive Fingerprinting of HTTP/2 Clients · Cloudflare: Bot Management variables.

Browser and session state

ESTABLISHED: JavaScript Detections inject a script only in response to requests for HTML pages or page views, excluding AJAX calls. The result has a lifespan of 15 minutes and is stored in the cf_clearance cookie. The detection enforces nothing by itself: the site owner must write a rule on cf.bot_management.js_detection.passed. A client that does not run the script never receives a passing result. Cloudflare: JavaScript Detections.

ESTABLISHED: A passed challenge is recorded in the same cookie, which Cloudflare describes as securely tied to the specific visitor and device it was issued to, preventing reuse across machines. Its default lifetime is 30 minutes. Where a site runs Precursor in Armed mode, clearance is re-evaluated from ongoing behaviour and may be reduced or invalidated before it expires; Cloudflare's summary is that clearance is both time-bound (Interstitial) and behavior-bound (Precursor). A second cookie, __cf_bm, carries bot-score state for a session and expires after 30 minutes of inactivity. Cloudflare does not publish which attributes tie a clearance to a visitor. Cloudflare: Clearance · Challenge Passage · Cloudflare cookies.

WHAT A PROXY CHANGES, AND WHAT IT CANNOT

ESTABLISHED: For HTTPS, a client asks an HTTP proxy for a tunnel with CONNECT, after which the proxy must restrict its behavior to blind forwarding of data, in both directions, until the tunnel is closed. SOCKS5 CONNECT does the same job at the transport layer. The TLS handshake then runs end to end between your client and the site's edge. Two things follow. The site sees the exit's address and the exit's TCP connection, so IP, ASN, country and any transport-level fingerprint belong to the exit (JA4+ defines JA4T for TCP clients; Cloudflare's Bot Management variables list no TCP fingerprint field). Everything inside the tunnel belongs to your client and arrives unchanged: the ClientHello, the HTTP version, the headers and their order, cookies and JavaScript results. RFC 9110 §9.3.6 · RFC 1928 · JA4+ methods.

LayerWhat is readBehind a forward proxy it is set by
AddressIP, ASN, country, managed-list membershipthe exit
TCP connectionthe connecting host's TCP handshakethe exit
TLSClientHello: JA3, JA4your client
HTTPprotocol version, header set and order, User-Agentyour client
BrowserJavaScript Detections resultyour client
Session and behaviour__cf_bm, cf_clearance, request rate and sequenceyour client and your request pattern

ESTABLISHED: The operational inference is that a proxy is a choice at the first two rows only. Changing the exit can change a decision that was made on the address. A decision made on the client follows the client to every exit. And because Cloudflare does not say what ties a clearance to a visitor, changing the exit in the middle of a cleared session is a risk with no documented upside.

READ THE REFUSAL BEFORE CHANGING THE EXIT

ESTABLISHED: Cloudflare labels its refusals. Every Challenge Page will have the cf-mitigated header present and set to challenge, and it is served as text/html whatever was requested. The numbered errors appear in the HTML body of the response, each with a fixed HTTP status. Requests blocked by WAF custom rules or WAF managed rules do not get a 1020 error; they get a separate WAF block response. Cloudflare: Detect a Challenge Page response · Cloudflare 1xxx errors · Error 1020.

What came backCloudflare's descriptionLayer it names
cf-mitigated: challengeA Challenge Page was served in place of the resource. Challenges are triggered by a WAF, Bot Management or rate limiting rule.Any. Completing it takes a client that runs the page's JavaScript.
403, error 1005The site owner has banned the autonomous system number (ASN).Address: the whole network
403, error 1006, 1007 or 1008Your IP address has been bannedAddress: that IP
403, error 1009The site owner has banned the country or region.Address: country
403, error 1010The owner of this website has banned your access based on your browser's signature (Browser Integrity Check)Client: headers and User-Agent
429, error 1015You are being rate limitedBehaviour: request rate
403, error 1020A security rule with a Block action matched the requestNot visible from outside

ESTABLISHED: The operational inference is that 1005 through 1009 are the only responses that name the address as the reason, and each of them is an explicit decision by the site owner about a network, an address or a country; 1005 names a network, so another address inside it gets the same answer. A challenge, a WAF block response and 1020 do not say which input matched. For 1015 Cloudflare's guidance to visitors is to wait: Do not repeatedly try to access the website within a short period of time, as this may extend the block. For the bans and for 1010 and 1020 its stated resolution is to contact the site owner. Error 1005 · Error 1006 · Error 1009 · Error 1010 · Error 1015 · Browser Integrity Check.

WHERE PROXIES.SX FITS

ESTABLISHED + OURS. Our statements are checkable at the endpoints named. Quoted text and field names come from responses fetched on 12 November 2026 between 14:52 and 15:19 UTC. Counts are left out on purpose: they change by the hour, so fetch them.

OURS: We supply the address and the TCP connection, the first two rows of the layer table, and nothing above them. For HTTPS the Pool Gateway (gw.proxies.sx:7000 HTTP, :7001 SOCKS5) opens a tunnel to an exit and forwards bytes. Your client still completes the TLS handshake with the site and validates the site's own certificate, which you can confirm in your client's handshake log. Pool Gateway contract.

OURS: GET https://api.proxies.sx/v1/gateway/pool/stock needs no key and returns counts per pool and country, never an address. Its ipTypes block describes itself as Routable peer counts by exit-IP class (server-side ASN classification), with the classes mobile, residential, datacenter and unclassified, and adds that Modems in `pools.mbl` are all mobile by construction. The mbl pool listed six countries: us, gb, fr, nl, pl and ge (Georgia). The response qualifies its own numbers as inventory passing the current public stock filters, not a connection reservation or delivery guarantee; they are not a count of distinct addresses, and each response carries generatedAt and stale so you can tell how old it is. Live stock.

OURS: Routing is chosen in the proxy username, psx_<accountId>-<pool>-<country> plus optional tokens. The stock response names the class filter: Route with -iptype-mobile | -iptype-residential. A held session is -rot-sticky-sid-<id>; without a -sid- every connection is a new session. The rotation cookbook states the limit in its own words: Sticky pins the MODEM, not the IP, because carriers re-NAT the egress address on their own schedule, and Residential selection also does not guarantee an immutable public IP. Rotation cookbook · full token list.

OURS: For one whole device, GET https://api.proxies.sx/v1/pricing needs no key and lists the Private modem plans in stock under privateModems.plans[], described there as one dedicated 4G/5G modem per rental, unlimited traffic, paid from the balance. On 12 November 2026 the plans in stock covered nine country codes (AU, DE, FR, GB, GE, NL, NZ, SG, US); the list changes, so read it live. Each plan carries carrierName, period, priceUsd, stock, openvpn and p0f. The contract calls the product One whole 4G/5G modem rented to one customer. The public address still comes from the carrier. Live prices and plans · Private modems contract.

OURS: What we do not publish: a per-IP reputation score, a rating of exits against any bot-management vendor, a pass rate for any site, or exit addresses. The mobile and residential labels are our classification of an exit's network. They are not Cloudflare's assessment of an address, and Cloudflare's own model notes, quoted above, name residential proxies as a detection target.

WHAT AN AGENT SHOULD DO WITH THIS

OURS: each command reads a live endpoint or uses the documented username format. Replace the placeholders, and fetch only pages you are permitted to fetch.

1. Decide whose refusal it is. OURS: a refusal from our gateway carries an E_ code in the form CODE: message (req: <uuid>), and the error table states that such a response was refused before your request was forwarded. Anything else came from the site through the tunnel. ESTABLISHED: a response that went through Cloudflare carries a Cf-Ray header. OURS: the billing rule in the same table is the reason to diagnose once instead of retrying blind: once a route is open every byte in both directions is billed, including responses the target blocks, transfers that are cut off, and each retry. Error table · Cloudflare Ray ID.

2. Capture one refused request and classify it with the table above. OURS: the proxy host, port and username format are the documented ones; the target is yours to choose.

curl --silent --show-error --max-time 30 --suppress-connect-headers \
  --proxy http://gw.proxies.sx:7000 \
  --proxy-user 'psx_<accountId>-mbl-us-rot-sticky-sid-job42:<proxy_password>' \
  --dump-header headers.txt --output body.html \
  'https://<a page you are permitted to fetch>'
grep -i -E '^(HTTP/|cf-mitigated|cf-ray|content-type)' headers.txt
grep -o -i -E '(error|error code:?|cf-error-code">) ?1[0-9]{3}' body.html | head -n 1

ESTABLISHED: this shows how the site treats curl from that exit, and curl's ClientHello and headers are curl's. Log the same three things in the client you run in production (status, cf-mitigated, the 1XXX code) instead of assuming the curl result carries over.

3. Choose the address class before the run, not after a failure. OURS: read the counts, then name the pool and class in the username.

curl --fail --silent --show-error --max-time 10 \
  https://api.proxies.sx/v1/gateway/pool/stock \
  | jq '{generatedAt, stale, mbl: .pools.mbl,
         peer_us: .pools.peer.us, peer_us_classes: .ipTypes.peer.us}'

psx_<accountId>-mbl-us-rot-sticky-sid-job42                       carrier modem, US
psx_<accountId>-peer-us-iptype-residential-rot-sticky-sid-job42   residential-class peer, US
psx_<accountId>-peer-us-iptype-mobile-rot-sticky-sid-job42        mobile-class peer, US

OURS: a gateway answer of E_NO_STOCK_COUNTRY means nothing matches that pool, country and class; the error table says to change them only when your user chose that. ESTABLISHED: if the site answers 1005 through 1009, its owner has excluded that network, address or country. Treat that as an answer about access, not as a routing fault.

4. If the answer is a challenge or 1010, change the client before the exit. ESTABLISHED: a challenge can be triggered by any rule, the address included, but only a client that runs the page's JavaScript can complete it, and the clearance then belongs to that client and session; 1010 is decided on the client's headers. The operational inference is to run a client whose layers agree with each other (one that says it is a browser should be that browser's engine, and an HTTP library should say what it is) and to hold everything else constant when you compare exits, or you will not know which layer changed the result. For 1020 the matching rule is not visible from outside, and Cloudflare's stated resolution is to contact the site owner. OURS: keep one cookie jar per session and one -sid- per cookie jar, and do not rotate under a live clearance (30 minutes by default).

5. If the job needs the same device throughout, rent one. OURS: read the plans in stock, then follow the quickstart. Prices are in the response and nowhere in this post.

curl --fail --silent --show-error --max-time 10 \
  https://api.proxies.sx/v1/pricing \
  | jq '.privateModems.plans[]
        | {countryCode, carrierName, period, priceUsd, stock, p0f}'
Buy and drive it from a terminal:

A private modem: /quickstart/buy-modem.md. Metered GB on the Pool Gateway: /quickstart/buy-gb.md. Account: client.proxies.sx/signup.

OURS: the live API wins over this page: read /v1/pricing and /v1/gateway/pool/stock at the moment you plan.

6. Slow down and identify yourself where that is the real answer. ESTABLISHED: on 1015, wait. If you operate a crawler at scale, Cloudflare documents an identified route: a Verified bot declares who it is through a cryptographic Web Bot Auth signature, a published IP list with a stable user-agent, or reverse DNS, and its bar includes that the bot obeys robots.txt and crawl directives, maintains reasonable request rates. Web Bot Auth signs requests with HTTP Message Signatures. Cloudflare: Verified bots · Web Bot Auth · RFC 9421.

7. When you report a block to us, send the facts that locate it. OURS: the status, whether cf-mitigated was present, the 1XXX code, the client software, whether cookies were kept, your pool, country and -sid-, and the req id for any gateway error. Never send the proxy password. Channels are on the about page.

HONEST CAVEATS

VERIFY IT YOURSELF

Ground Truth · back to the feed · machine-readable: /news/feed.md