How to Solve Cloudflare Turnstile Without a Proxy

You don't always need a proxy to beat Cloudflare Turnstile. How the widget token works proxyless, a Python and JS walkthrough, and when you still need one.

Ask around about getting past Cloudflare Turnstile programmatically and the first thing you'll hear is "you need good proxies." Residential ones. Rotating ones. The expensive kind. For a lot of people that advice has calcified into a rule: no clean IPs, no Turnstile token.

It's half right. The half that's wrong is the half that costs you money every month. You can solve the Turnstile widget token without ever touching a proxy, and for a large share of automation and QA work that's all you actually need. Here's where the proxy assumption comes from, where it holds, where it falls apart, and how to call Peak with turnstiletaskproxyless so you stop paying a residential-proxy bill you didn't need.

Why everyone assumes Turnstile needs a proxy

The logic goes like this. You're running on a datacenter IP, maybe a cloud VM or a scraper box. Cloudflare keeps reputation scores on IP ranges, and datacenter egress scores badly because that's where most abusive traffic originates. So any challenge you hit gets harder, and the safe move is to route through a residential IP that looks like a real home connection.

That reasoning is sound for one specific thing: the Cloudflare interstitial, the full-page "Checking your browser" challenge that ends in a cf_clearance cookie. That cookie is bound to the IP that earned it. Reuse it from a different address and Cloudflare rejects it. If your target is gated by that 5-second challenge, your IP is part of the equation and a clean proxy genuinely helps. We wrote that up separately in the Cloudflare 5-second challenge explained and the cf_clearance cookie explained and how to reuse it.

The mistake is assuming the standalone Turnstile widget behaves the same way. It doesn't.

The Turnstile widget token is a different animal

Turnstile the widget, that little checkbox or invisible challenge embedded in a login or signup form, produces a token. When it passes, it drops a value into a hidden field named cf-turnstile-response, and your form submits that value to the origin server, which calls Cloudflare's siteverify endpoint to confirm it.

What does siteverify actually check? The token's validity, the sitekey it was minted for, and whether it's been used before. The token carries the sitekey binding and the challenge result. It is not cryptographically welded to the client IP the way cf_clearance is. That's the gap that makes proxyless solving possible. We go deeper on the field and its lifecycle in the cf-turnstile-response token explained.

So a solver can mint a valid token from its own clean browser pool, hand it back to you, and you inject it into your page. You never brought your IP into the token's creation, because the token doesn't depend on it the way the interstitial cookie does. Your origin server sees a real, verifiable token for the right sitekey, and that's what it checks.

Rule of thumb: if the thing blocking you is a widget that writes to cf-turnstile-response, you're likely fine proxyless. If it's a full-page interstitial that sets cf_clearance, your IP is in play and you want your own proxy.

How a proxyless token solve works end to end

The flow is short. You already know the two things that identify the challenge: the page URL and the sitekey (the 0x... value in the widget's data-sitekey attribute). You send those to Peak, Peak solves the challenge on a clean pool, and you get a token back in about a second. Then you drop the token into the hidden field and trigger the widget's callback so your page behaves as if a human clicked through.

No proxy field, no residential IP, no cookie juggling. Here's the request in Python.

import requests

resp = requests.post(
    "https://api.peak.fo/solve",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "task_type": "turnstiletaskproxyless",
        "url": "https://example.com/login",
        "sitekey": "0x4AAAAAAABxxxxxxxxxxxxx",
    },
    timeout=30,
)

data = resp.json()
if data["success"]:
    token = data["data"]["token"]
    print("token:", token, "cost:", data["cost"])
else:
    print("no solve, no charge")

The response looks like this:

{"success": true, "data": {"token": "1.7Nm..."}, "cost": 0.001}

Same call in Node:

const resp = await fetch("https://api.peak.fo/solve", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    task_type: "turnstiletaskproxyless",
    url: "https://example.com/login",
    sitekey: "0x4AAAAAAABxxxxxxxxxxxxx",
  }),
});

const data = await resp.json();
if (data.success) {
  console.log("token:", data.data.token, "cost:", data.cost);
}

Once you have the token, inject it into the page. If you're driving a real browser with Playwright or Puppeteer, set the hidden field and fire the callback the widget registered:

// in page context, after you have `token`
const el = document.querySelector('[name="cf-turnstile-response"]');
if (el) el.value = token;

// fire the widget callback so the form sees a pass
if (window.turnstile && typeof turnstile.getResponse === "function") {
  // some integrations read the field directly on submit;
  // others expect the data-callback to run
}

Many integrations read cf-turnstile-response straight off the form at submit time, so setting the field value is enough. Others wire up a data-callback that enables a submit button or kicks off an XHR, in which case you call that callback with the token. Check the widget markup on your target to see which pattern it uses. Full copy-paste examples live on the Python integration page and the JavaScript integration page.

Proxyless isn't magic, and here's where it stops

I'm not going to pretend this clears every wall. Two cases where proxyless alone won't carry you:

  • The full-page interstitial. If your target throws the "Checking your browser" page before you ever see a form, you're dealing with cf_clearance, and that cookie is IP-bound. A token minted elsewhere won't save a session on your datacenter IP. Use turnstiletask with your own proxy so the clearance and your requests share an address.
  • Region-locked or IP-sensitive targets. Some origins check geography or run their own IP reputation on top of Cloudflare. If the site only serves certain regions, or your downstream requests after the token also go through the same IP and that IP matters to the origin, bring your own proxy so the whole session is consistent.

There's also a plain honesty point: proxyless token solves have a success rate below 100%, because challenge difficulty varies and some sitekeys are configured aggressively. Peak charges only for successful solves, so a miss costs you nothing. You retry, or you fall back to bring-your-own-proxy for that target. The downside of trying proxyless first is zero, which is a good reason to try it first.

Proxyless token vs bring-your-own-proxy: when each wins

FactorProxyless token (turnstiletaskproxyless)Bring-your-own-proxy (turnstiletask)
What it clearsStandalone Turnstile widget tokenWidget token tied to a session on your IP
Interstitial / cf_clearanceNot coveredCovered when paired with your proxy
Region-locked targetsNo control over exit geographyYou pick the region via your proxy
SetupURL + sitekey, nothing elseURL + sitekey + a working proxy
Running costSolve fee onlySolve fee + your proxy bill
Best forLogin/signup forms, QA automation, scraping public data behind a widgetInterstitials, geo-gated sites, sessions where the origin cares about your IP

Most people reach for proxies out of habit and end up paying for the proxy on top of the solve when the widget never needed one. Start proxyless, measure your success rate on your actual targets, and only reach for turnstiletask when you hit one of the cases above. More on the IP side of the decision in residential vs datacenter proxies for solving.

The cost angle nobody mentions

Here's the part that moves the budget. Residential proxies are usually billed by the gigabyte, and a few dollars per GB is normal. A scraping or automation workload that pushes real traffic can run a residential-proxy bill that dwarfs what you'd ever spend on solves.

Turnstile solves on Peak run $1 per 1,000 pay-per-solve, dropping to $0.35 per 1,000 at volume. Proxyless carries a small premium over the standard rate, and that premium is still a rounding error next to a residential-proxy invoice. When you skip the proxy entirely, you delete a whole line item. You're paying roughly a tenth of a cent per token instead of a tenth of a cent per token plus whatever the proxy vendor charges to carry your bytes.

And because you pay only for successful solves, the worst case on a proxyless attempt is that it misses and you owe nothing for it. Full numbers are on Peak pricing.

Try it on your own target

You get 1,000 free solves with no card. Grab your sitekey off the target page, send a turnstiletaskproxyless request with the URL, and see what your success rate looks like before you commit to anything. If the widget's the only wall, you're done, and you never opened a proxy dashboard.

One note on staying on the right side of things: this is for automation, QA, and scraping public data you're allowed to access. Respect the target's terms of service and robots rules, and don't point it at anything involving someone else's credentials. Clearing a bot wall on a site you have a legitimate reason to be on is the use case. Breaking into accounts isn't.