hCaptcha test sitekey: the official integration-testing keys.

hCaptcha publishes official test keys so you can wire up the widget and your siteverify call without solving anything. The publisher test sitekey is 10000000-ffff-ffff-ffff-000000000001: it always passes and always emits the same dummy token, which verifies against the all-zeros test secret. Here is the full set, a snippet to paste, and the one error the keys trip when you mix them wrong.

The keys

The docs list one publisher key set and two enterprise variants. All three sitekeys render a widget that never challenges, each emits its own fixed dummy token, and all three tokens verify against the same test secret: 0x0000000000000000000000000000000000000000.

Official hCaptcha test keys
# Publisher / Pro account keys: widget always passes, never challenges
sitekey:  10000000-ffff-ffff-ffff-000000000001
secret:   0x0000000000000000000000000000000000000000
token:    10000000-aaaa-bbbb-cccc-000000000001

# Enterprise: simulates a safe end user
sitekey:  20000000-ffff-ffff-ffff-000000000002
token:    20000000-aaaa-bbbb-cccc-000000000002

# Enterprise: simulates a detected bot
sitekey:  30000000-ffff-ffff-ffff-000000000003
token:    30000000-aaaa-bbbb-cccc-000000000003

# All three sets verify against the same test secret (the 0x00... one above).
hCaptcha's published integration-testing key sets (verified against docs.hcaptcha.com, June 2026)
Key setTest sitekeyDummy response token
Publisher / Pro (always passes)10000000-ffff-ffff-ffff-00000000000110000000-aaaa-bbbb-cccc-000000000001
Enterprise: safe end user20000000-ffff-ffff-ffff-00000000000220000000-aaaa-bbbb-cccc-000000000002
Enterprise: bot detected30000000-ffff-ffff-ffff-00000000000330000000-aaaa-bbbb-cccc-000000000003

The two enterprise sets exist so you can exercise both branches of your handling logic: 20000000-… simulates a clean end user, 30000000-… a detected bot. For enterprise testing the docs also note you should pass remoteip to siteverify, or some response fields (the risk score among them) stay disabled.

How the test flow behaves

With a test sitekey the widget loads normally, but the round is scripted. Per the docs, the keypair “will never challenge and always produce the same response token”. Concretely:

  • The checkbox passes on click; you never see an image grid or a drag puzzle.
  • The h-captcha-response field gets the fixed dummy token (for the publisher key: 10000000-aaaa-bbbb-cccc-000000000001), not a real P1_ token like the ones described in the hCaptcha token guide.
  • That dummy token returns success: true from siteverify when, and only when, you verify it with the test secret.

Because the token is a constant, the whole loop is deterministic. That is the point: you are testing that your form posts the field, your backend calls siteverify, and your success and failure branches both run. You are not testing hCaptcha itself.

Minimal working page

Save this as an HTML file and serve it from anywhere (even localhost; test keys skip domain checks). The widget renders, the checkbox passes, and the form posts the dummy token:

index.html with the test sitekey
<!DOCTYPE html>
<html>
  <head>
    <script src="https://js.hcaptcha.com/1/api.js" async defer></script>
  </head>
  <body>
    <form action="/submit" method="POST">
      <!-- Official test sitekey: renders the widget, never challenges. -->
      <div class="h-captcha"
           data-sitekey="10000000-ffff-ffff-ffff-000000000001"></div>
      <button type="submit">Submit</button>
    </form>
  </body>
</html>

On the server, verify what arrived in h-captcha-response against the test secret:

siteverify with the test pair
curl "https://api.hcaptcha.com/siteverify" \
  -d "secret=0x0000000000000000000000000000000000000000" \
  -d "response=10000000-aaaa-bbbb-cccc-000000000001"
Response
{
  "success": true,
  "challenge_ts": "2026-06-12T09:41:00.000Z",
  "hostname": "localhost"
}

The full server-side contract (parameters, response fields, production setup) is covered in the siteverify guide.

The not-using-dummy-passcode error

The test keys only work as a matched set. Mix a test value with a real one and siteverify fails with a dedicated error code:

Mixed test/real values
{
  "success": false,
  "error-codes": ["not-using-dummy-passcode"]
}

hCaptcha documents not-using-dummy-passcode as “You have used a testing sitekey but have not used its matching secret.” The usual ways to hit it:

  • Test sitekey on the page, real secret on the server. The widget emitted the dummy token, your real secret cannot validate it.
  • Test secret on the server, real token in the request. The test secret only accepts the dummy passcodes.
  • Tokens crossed between sets, e.g. the 20000000-… token verified while the page used the 10000000-… sitekey.

The fix is mechanical: pick one row from the table and use its sitekey, the shared test secret, and its dummy token together. The related sitekey-secret-mismatch code (“The sitekey is not registered with the provided secret.”) is the same class of mistake with real keys; both are broken down in hCaptcha error codes.

Test keys provide no anti-bot protection. The sitekey, secret, and dummy token are public, so anyone can pass your form while they are live. The docs tell you to keep them strictly in test environments; load the key from config per environment so production can never boot with the all-zeros secret.

What the test keys cannot tell you

Everything interesting about hCaptcha in production is absent from the test flow. The dummy round never renders a real challenge, so you learn nothing about the challenge types your users will see, how often multi-round challenges occur, or how your UI behaves while the iframe is open. The token is a fixed string, so token expiry (~120 s), single-use semantics, and already-seen-response handling go unexercised. And there is no test path at all for enterprise rqdata binding; the enterprise test keys simulate risk verdicts, not the rqdata challenge flow.

To cover that gap, point your staging environment at a real sitekey (your production one, or a second registered key) and use real tokens. If you do not want a human clicking challenges on every CI run, mint the token through NoneCap: send the sitekey and page URL to POST /v1/solves and you get back a real P1_ token that behaves exactly like production, including expiry and single use.

Real token for a real sitekey in staging
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://staging.your-site.example/signup"
  }'

Submit the returned token as h-captcha-response and your real secret validates it at siteverify. Billing starts at one credit per challenge round, charged on success only, at $0.25 to $0.50 per 1,000 credits; new accounts get 100 free credits to test with. Request details are in the API reference, and finding your sitekey takes a few seconds if you do not have it handy.

Last updated June 2026.

Frequently asked

What is the hCaptcha test sitekey?
10000000-ffff-ffff-ffff-000000000001. It is the official publisher integration-testing key: the widget renders, never shows a challenge, and always produces the dummy token 10000000-aaaa-bbbb-cccc-000000000001, which verifies as success: true against the test secret 0x0000000000000000000000000000000000000000.
Why am I getting not-using-dummy-passcode from siteverify?
You mixed a test value with a real one. hCaptcha documents the error as “You have used a testing sitekey but have not used its matching secret.” In practice it appears whenever the test sitekey, test secret, and dummy token are not all from the same test set. Switch all three to the values from one row of the table above, or all three to your real production values. More codes are in hCaptcha error codes.
Is there a test sitekey that always shows a challenge?
No. The official docs list only always-pass test keys; none of them ever render a challenge. If you need to see a real challenge during development, hCaptcha’s suggestion is to register a second real sitekey on your account and set it to “Always Challenge” mode in the dashboard.
Can I ship the test sitekey to production?
Do not. The docs are explicit that test keys provide no anti-bot protection: every visitor passes, and the dummy token validates for anyone who knows the public test secret. Gate the key by environment so production always loads your real sitekey.
Does the dummy token verify against my real secret?
No. The dummy token 10000000-aaaa-bbbb-cccc-000000000001 only returns success: true with the all-zeros test secret. Against a real secret, siteverify rejects it. The reverse mix (test secret + real token) fails with not-using-dummy-passcode. See the siteverify guide for the full verification flow.

Start solving hCaptcha in minutes.

100 free credits on signup. Pay per solve, credits never expire, failed solves auto-refunded.