How to find an hCaptcha sitekey.
An hCaptcha sitekey is the public UUID that identifies a widget, and it is
sitting in the page right now. The fastest way to read it is the
data-sitekey attribute in DevTools. For invisible widgets it hides
in the render() call or on the iframe URL instead. Here is how to
find it every way, and what the sitekey gets you.
What a sitekey is
Every hCaptcha widget is tied to a sitekey, a UUID like
f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8 that tells hCaptcha which site the
challenge belongs to. It is public on purpose: the browser has to
know it to render the widget, so it always appears somewhere in the page. The
matching secret key lives on the site owner’s server and is used
only at siteverify time, so you never see it from the front end.
To solve an hCaptcha programmatically you need two things: the sitekey and the url of the page the challenge appears on. Both are front-end values you can read in a few seconds.
Method 1: inspect the widget in DevTools
The classic drop-in widget renders a <div class="h-captcha"> with the
key on its data-sitekey attribute. Right-click the captcha, choose
Inspect, and read it straight off the element:
<!-- The classic drop-in: the key is the data-sitekey attribute. -->
<div class="h-captcha"
data-sitekey="f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8"></div>
<!-- After a solve, hCaptcha injects the token into a hidden field: -->
<textarea name="h-captcha-response">P1_eyJ0eXAi...UV8w</textarea>
If the element collapsed into an iframe, look at the wrapping <div>
just outside it. The data-sitekey lives on the container, not on the
iframe hCaptcha injects.
Method 2: View Source and search for data-sitekey
For server-rendered widgets the attribute is already in the raw HTML. Open
View Source (or press Ctrl-U), then
Ctrl-F for data-sitekey. The UUID right after it is the key.
If View Source comes up empty, the widget is rendered by JavaScript after load, so
search the live DOM in the Elements panel instead, or use Method 3.
Method 3: pull it from the invisible widget
Invisible widgets often render no visible box and no data-sitekey div. The
key still has to reach hCaptcha, so it shows up in one of two places. The first is the
explicit hcaptcha.render() call in the page’s script:
<!-- Explicit render: the key is the first argument's sitekey field. -->
<script>
hcaptcha.render('captcha-box', {
sitekey: 'f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8',
size: 'invisible',
callback: onSolved
});
</script>
The second is the hCaptcha iframe itself. Find the iframe in the Elements panel and read
the sitekey= parameter on its src URL:
<!-- Invisible widgets often expose the key only on the iframe URL. -->
<iframe
src="https://newassets.hcaptcha.com/captcha/v1/.../static/hcaptcha.html#frame=challenge&id=...&sitekey=f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8&...">
</iframe>
A reliable catch-all: search the rendered DOM for the literal string
sitekey. Between the container attribute, the render call, and the iframe
URL, it turns up every time.
Method 4: read it programmatically
If you are already driving the page with a headless browser, let it read the key for you. In Playwright, grab the attribute off the first matching element:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
page = p.chromium.launch().new_page()
page.goto("https://target.example/login")
# Read the sitekey straight off the rendered widget.
sitekey = page.locator("[data-sitekey]").first.get_attribute("data-sitekey")
print(sitekey, page.url) # the two values NoneCap needs The same idea in Puppeteer uses page.$eval:
import puppeteer from "puppeteer";
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.goto("https://target.example/login");
// Read the sitekey straight off the rendered widget.
const sitekey = await page.$eval("[data-sitekey]", (el) =>
el.getAttribute("data-sitekey")
);
console.log(sitekey, page.url()); // the two values NoneCap needs
The selector [data-sitekey] covers the common case. For an invisible widget
with no such attribute, read the iframe src instead and parse the
sitekey query parameter out of it.
Sitekey types and what to send
The sitekey itself does not tell you the widget mode, but the mode decides what you send NoneCap. Here is how the three line up:
| Widget type | Where the sitekey lives | What you tell NoneCap |
|---|---|---|
| Checkbox | A visible widget renders; data-sitekey sits on its <div class="h-captcha"> | type: "hcaptcha" + sitekey + url |
| Invisible | No visible box; the key is in the hcaptcha.render() call or the iframe ?sitekey= | type: "hcaptcha" + sitekey + url |
Enterprise (rqdata) | Same data-sitekey, but the page also passes a fresh rqdata blob per challenge | type: "hcaptcha_enterprise" + sitekey + url + rqdata |
What the sitekey and url get you
Once you have the sitekey and the page url, you have everything NoneCap needs
to mint a token. POST them to /v1/solves, block for the result with
?wait=N, and read back a real P1_ token:
curl "https://api.nonecap.com/v1/solves?wait=90" \
-H "Authorization: Bearer $NONECAP_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "hcaptcha",
"sitekey": "f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8",
"url": "https://target.example/login"
}' {
"id": "solve_01HQF7K3JKWZX",
"object": "solve",
"type": "hcaptcha",
"status": "solved",
"token": "P1_eyJ0eXAi...UV8w",
"credits_charged": 1
}
Submit that token as the form’s h-captcha-response and the page
treats it as a real pass. NoneCap returns tokens that invisible and enterprise sitekeys
accept, not just image-recognition output. The
full solve object and every language sample are in the
API reference.
Enterprise sitekeys need more than the sitekey
For enterprise hCaptcha, the sitekey alone is not enough. Each challenge is bound to a fresh
rqdatablob that the page generates per request and ties to the session, so you have to capture that blob too and send it withtype: "hcaptcha_enterprise". Readingdata-sitekeylooks identical; the extra step is grabbing the liverqdata. See hCaptcha enterprise rqdata for how to find and forward it.
Wiring this into a real run? The same sitekey read drops straight into a
Playwright or
Puppeteer flow: read the key, mint the token, inject it
into h-captcha-response, and submit.
Last updated June 2026.
Frequently asked
What does an hCaptcha sitekey look like?
f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8. It is public by design: it identifies the site that owns the widget and is safe to read from page source. The secret half (the key used at siteverify) stays on the site owner’s server and is never exposed in the browser.I cannot find data-sitekey in the HTML. Where else is it?
<div class="h-captcha"> at all. Look for the sitekey passed into the hcaptcha.render() call in the page’s JavaScript, or open the hCaptcha iframe in DevTools and read the sitekey= parameter on its src URL. Searching the rendered DOM for the string sitekey finds it in every case.Is the sitekey the same as the secret key?
api.hcaptcha.com/siteverify to validate a token. NoneCap only needs the public sitekey and the page url; it never sees or needs the secret.What can I do once I have the sitekey and url?
P1_ token you submit as the form’s h-captcha-response. Billing is one credit per hCaptcha challenge round, charged on success only, and credits run $0.40 to $0.50 per 1,000. New accounts get 100 free credits. See pricing.