🎯 A customizable, anti-detection cloud browser powered by self-developed Chromium designed for web crawlers and AI Agents.👉Try Now
Back to Blog

How to Detect Cloudflare Turnstile Parameters: sitekey, cData, action

Ethan Brown
Ethan Brown

Advanced Bot Mitigation Engineer

06-Jul-2026

TL;DR:

  • Cloudflare Turnstile is configured by a handful of parameters, and they are readable from the page. The sitekey is always present; action, cData, and the callback are set by the site when it uses them.
  • Implicit-mode widgets carry the parameters as data-* attributes. Read data-sitekey, data-action, data-cdata, and data-callback straight off the .cf-turnstile element.
  • Explicit-mode widgets pass the parameters to turnstile.render(). Hook that call before the page runs it and you capture the full options object — sitekey, action, cData, and chlPageData.
  • In a live run the widget exposed sitekey 0x4AAAAAAAW9zqSPAlyOSMfO and a callback. The render hook stayed empty because that page uses implicit mode — the parameters were in the DOM instead.
  • Do this in a real browser. The parameters only exist once the widget script has run, so read them from a rendered page, not raw HTML.
  • Free to start. New Scrapeless accounts include free Scraping Browser runtime — sign up at app.scrapeless.com.

Introduction: the parameters that configure a Turnstile widget

Cloudflare Turnstile is the widget a site embeds to verify a visitor is human — the successor to a checkbox CAPTCHA. When it loads, it is configured by a small set of parameters: a public site key that identifies the widget, an optional action label that names the protected event, an optional cData payload the site attaches, and a callback that receives the token once the widget passes. Knowing how to read those parameters off a page is the first step to understanding, testing, or automating any Turnstile-protected flow.

There are two ways a site wires Turnstile up, and each exposes the parameters differently. This guide covers both — reading them from the DOM in implicit mode, and capturing them from the turnstile.render() call in explicit mode — with a live run against a real Turnstile widget.


The parameters, and what each one is

Parameter Attribute / option What it is
Site key data-sitekey / sitekey Public key identifying the widget; always present (format 0x…).
Action data-action / action Optional label naming the protected event (e.g. login).
cData data-cdata / cData Optional customer data string the site attaches to the challenge.
Callback data-callback / callback The function that receives the token when the widget passes.
chlPageData chlPageData Page data passed in explicit renders on some managed flows.

The site key is public by design — it's meant to be in the page. The action and cData values exist only when the site chooses to set them.


Why Scrapeless Scraping Browser

Scrapeless Scraping Browser is a customizable, anti-detection cloud browser designed for web crawlers and AI agents. For reading widget parameters specifically, it brings:

  • Real cloud-side rendering — the widget script actually runs, so the parameters exist to read.
  • A standard Puppeteer connectionpuppeteer.connect() returns an ordinary Browser; you inspect the page normally.
  • evaluateOnNewDocument support — inject a hook before the page's own scripts run, which is what explicit-mode capture needs.
  • Residential proxies in 195+ countries — reach pages that only serve their real widget to clean egress.

Get your API key on the free plan at app.scrapeless.com.


Prerequisites

  • Node.js 18 or newer
  • A Scrapeless account and API key — sign up at app.scrapeless.com
  • Basic familiarity with Puppeteer and the DOM

Install

bash Copy
npm install puppeteer-core
bash Copy
export SCRAPELESS_API_KEY="your_api_token_here"

Implicit mode: read the parameters from the DOM

The common case is an implicit widget: a <div class="cf-turnstile" data-sitekey="…"> element that Turnstile auto-renders. The parameters are the element's data-* custom attributes, so read them once the widget has mounted:

javascript Copy
import puppeteer from 'puppeteer-core';

const params = new URLSearchParams({
  token: process.env.SCRAPELESS_API_KEY,
  sessionTTL: '180',
  proxyCountry: 'US',
});
const browser = await puppeteer.connect({
  browserWSEndpoint: `wss://browser.scrapeless.com/api/v2/browser?${params}`,
});

const page = await browser.newPage();
await page.goto('https://www.scrapingcourse.com/login/cf-turnstile', {
  waitUntil: 'domcontentloaded',
  timeout: 60000,
});
await new Promise((r) => setTimeout(r, 6000)); // let the widget script mount

const widget = await page.evaluate(() => {
  const el = document.querySelector('.cf-turnstile, [data-sitekey]');
  if (!el) return null;
  const attrs = {};
  for (const a of el.attributes) attrs[a.name] = a.value;
  return attrs;
});

console.log(widget);
// {
//   id: "waf",
//   class: "cf-turnstile",
//   "data-sitekey": "0x4AAAAAAAW9zqSPAlyOSMfO",
//   "data-callback": "javascriptCallback"
// }
await browser.close();

In a live run this returned the widget's data-sitekey (0x4AAAAAAAW9zqSPAlyOSMfO) and its data-callback. This particular page does not set data-action or data-cdata — those keys simply aren't present, which is normal: they show up only when the site configures them, and you read them the same way when they do.

Get your API key on the free plan: app.scrapeless.com


Explicit mode: capture the parameters from turnstile.render()

When a site renders Turnstile explicitly, it calls turnstile.render(container, options) in JavaScript, and the parameters live in that options object — not in the DOM. To read them, hook turnstile.render before the page's own script runs, using evaluateOnNewDocument and a property setter via Object.defineProperty:

javascript Copy
await page.evaluateOnNewDocument(() => {
  window.__tsParams = [];
  Object.defineProperty(window, 'turnstile', {
    configurable: true,
    get() { return this.__ts; },
    set(v) {
      this.__ts = v;
      if (v && v.render && !v.__wrapped) {
        const orig = v.render.bind(v);
        v.render = (el, opts) => { window.__tsParams.push(opts || {}); return orig(el, opts); };
        v.__wrapped = true;
      }
    },
  });
});

await page.goto('https://example.com/turnstile-page', { waitUntil: 'domcontentloaded' });
await new Promise((r) => setTimeout(r, 7000));

const captured = await page.evaluate(() => window.__tsParams);
console.log(captured);
// explicit render → [{ sitekey: "0x…", action: "login", cData: "…", callback: [Function] }]

The hook wraps render the moment the site assigns window.turnstile, so every explicit render is captured with its full options — sitekey, action, cData, and chlPageData when present. On an implicit-mode page this array stays empty, because the site never calls render() itself — a reliable signal that you should read the parameters from the DOM attributes instead. Run both and use whichever one is populated.


Notes

  • The site key is public; treat action and cData as optional. Guard for their absence rather than assuming every widget sets them.
  • Read from a rendered page, not raw HTML. In explicit mode the parameters never appear in the served markup — they exist only after the widget script runs, which is why a real browser is required.
  • Prefer a durable selector. .cf-turnstile and [data-sitekey] are stable anchors; the surrounding markup is not.
  • The token is a separate step. Reading the parameters is not the same as passing the widget — the cf-turnstile-response token is produced by the callback after the widget validates, and is verified server-side per Cloudflare's Turnstile server-side validation docs.

Conclusion: the widget's configuration, read from the page

Turnstile's parameters are not hidden — the site key is meant to be public, and the action and cData values are readable wherever the site sets them. Read them from the data-* attributes in implicit mode, or hook turnstile.render() to capture the options object in explicit mode, and run both so whichever the page uses is covered. For the mechanics of driving the cloud browser, the Scraping Browser docs cover the full flow, and the anti-bot side is unpacked in the guide on clearing Cloudflare challenges; the docs cover the rest.


Ready to Build Your AI-Powered Data Pipeline?

Join our community to claim a free plan and connect with developers working on anti-bot flows: Discord · Telegram.

Sign up at app.scrapeless.com for free Scraping Browser runtime, and see pricing for scale.


FAQ

Q: What parameters does a Turnstile widget have?
A public sitekey (always present, format 0x…), an optional action label, an optional cData string, and a callback that receives the token. Explicit renders may also pass chlPageData.

Q: Where do I find the site key?
On the widget element as data-sitekey in implicit mode, or in the options passed to turnstile.render() in explicit mode. In a live run it read 0x4AAAAAAAW9zqSPAlyOSMfO.

Q: Why is data-action or data-cdata missing?
Because the site didn't set them — both are optional. When a site uses them, they appear as data-action / data-cdata (implicit) or action / cData (explicit), read the same way.

Q: Why do I need a real browser instead of fetching the HTML?
In explicit mode the parameters are passed in JavaScript and never appear in the served markup; they exist only after the widget script runs. A cloud browser renders the page so the values are present.

Q: Does reading the parameters pass the challenge?
No. The parameters configure the widget; the cf-turnstile-response token is produced separately by the callback after the widget validates, and is checked server-side.

At Scrapeless, we only access publicly available data while strictly complying with applicable laws, regulations, and website privacy policies. The content in this blog is for demonstration purposes only and does not involve any illegal or infringing activities. We make no guarantees and disclaim all liability for the use of information from this blog or third-party links. Before engaging in any scraping activities, consult your legal advisor and review the target website's terms of service or obtain the necessary permissions.

Most Popular Articles

Catalogue