Skip to content
Cloudflare Docs

Test your Turnstile implementation

Use dummy sitekeys and secret keys to test your Turnstile implementation without triggering real challenges that would interfere with automated testing suites.

Automated testing suites (like Selenium, Cypress, or Playwright) are detected as bots by Turnstile, which can cause:

  • Tests to fail when Turnstile blocks automated browsers
  • Unpredictable test results due to challenge variations
  • Interference with form submission testing
  • Difficulty testing complete user flows

Dummy keys solve this by providing predictable, controlled responses that work with automated testing tools.

Test sitekeys

SitekeyBehaviorWidget TypeUse case
1x00000000000000000000AAAlways passesVisibleTest successful form submissions
2x00000000000000000000ABAlways failsVisibleTest error handling and retry logic
1x00000000000000000000BBAlways passesInvisibleTest invisible widget success flows
2x00000000000000000000BBAlways failsInvisibleTest invisible widget error handling
3x00000000000000000000FFForces interactive challengeVisibleTest user interaction scenarios

Test secret keys

Use these secret keys for server-side validation testing:

Secret keyBehaviorUse case
1x0000000000000000000000000000000AAAlways passes validationTest successful token validation
2x0000000000000000000000000000000AAAlways fails validationTest validation error handling
3x0000000000000000000000000000000AAReturns "token already spent" errorTest duplicate token handling

Implementation

Local development

Test keys work on any domain, including:

  • localhost
  • 127.0.0.1
  • 0.0.0.0
  • Any development domain

Cloudflare recommends that sitekeys used in production do not allow local domains (localhost or 127.0.0.1), but users can choose to add local domains to the list of allowed domains under Hostname Management. Dummy sitekeys can be used from any domain, including on localhost.

Client-side testing

Replace your production sitekey with a test sitekey.

<!-- Development/Testing -->
<div class="cf-turnstile" data-sitekey="1x00000000000000000000AA"></div>
<!-- Production -->
<div class="cf-turnstile" data-sitekey="your-real-sitekey"></div>

Server-side testing

Replace your production secret key with a test secret key.

JavaScript
// Environment-based configuration
const SECRET_KEY = process.env.NODE_ENV === 'production'
? process.env.TURNSTILE_SECRET_KEY
: '1x0000000000000000000000000000000AA';
// Use in validation
const validation = await validateTurnstile(token, SECRET_KEY);

Environment configuration

Set up different keys for different environments.

Terminal window
# .env.development
TURNSTILE_SITEKEY=1x00000000000000000000AA
TURNSTILE_SECRET_KEY=1x0000000000000000000000000000000AA
# .env.test
TURNSTILE_SITEKEY=2x00000000000000000000AB
TURNSTILE_SECRET_KEY=2x0000000000000000000000000000000AA
# .env.production
TURNSTILE_SITEKEY=your-real-sitekey
TURNSTILE_SECRET_KEY=your-real-secret-key

Dummy token behavior

Token generation

Test sitekeys generate a dummy token: XXXX.DUMMY.TOKEN.XXXX

Token validation

  • Test secret keys: Only accept the dummy token, reject real tokens.
  • Production secret keys: Only accept real tokens, reject dummy tokens.

Validation response

Success response
{
"success": true,
"challenge_ts": "2022-02-28T15:14:30.096Z",
"hostname": "localhost",
"error-codes": [],
"action": "test",
"cdata": "test-data"
}
Failure response
{
"success": false,
"error-codes": ["invalid-input-response"]
}
Token already redeemed
{
"success": false,
"error-codes": ["timeout-or-duplicate"]
}

Testing scenarios

Test sitekeyTest secret key
Test case
1x00000000000000000000AA1x0000000000000000000000000000000AAThis combination will always result in successful validation.
2x00000000000000000000AB2x0000000000000000000000000000000AAThis combination will always fail.
1x00000000000000000000AA3x0000000000000000000000000000000AAThis combination will always fail with "timeout-or-duplicate" error.