Migration from Cloudflare Turnstile
This guide helps you migrate from Cloudflare Turnstile to MTCaptcha by swapping the client widget and replacing Turnstile’s siteverify flow with MTCaptcha CheckToken.
Why migrate from Cloudflare Turnstile​
- Privacy and GDPR alignment: MTCaptcha documents privacy-aware handling suitable for EU-facing properties. See Privacy GDPR Compliance.
- WCAG 2.1 AAA accessibility: Align with accessibility-oriented CAPTCHA UX and documentation. See Accessibility Compliance.
- Global reliability, including China: MTCaptcha is delivered with mainland China in mind. See Works in China.
Migration at a glance​
| Cloudflare Turnstile | MTCaptcha | |
|---|---|---|
| Client script | https://challenges.cloudflare.com/turnstile/v0/api.js | https://service.mtcaptcha.com/mtcv1/client/mtcaptcha.min.js |
| Widget class | .cf-turnstile (container <div class="cf-turnstile" data-sitekey="…"></div>) | .mtcaptcha (use <div class="mtcaptcha"></div>) |
| Token name | cf-turnstile-response (hidden input / form field) | mtcaptcha-verifiedtoken (hidden input name) |
| Backend API | POST https://challenges.cloudflare.com/turnstile/v0/siteverify (secret + response) | GET https://service.mtcaptcha.com/mtcv1/api/checktoken (privatekey + token) |
Keep your MTCaptcha PrivateKey on the server. Browser code should only ever see the public SiteKey inside mtcaptchaConfig.
Step 1: Replace client-side script and widget​
<!-- Remove [Cloudflare Turnstile] -->
<script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
<div class="cf-turnstile" data-sitekey="YOUR_TURNSTILE_SITE_KEY"></div>
<!-- Add [MTCaptcha] -->
<script>
var mtcaptchaConfig = { "sitekey": "YOUR_SITEKEY" };
</script>
<script src="https://service.mtcaptcha.com/mtcv1/client/mtcaptcha.min.js" async defer></script>
<div class="mtcaptcha"></div>
Set mtcaptchaConfig (with quoted "sitekey") before loading mtcaptcha.min.js.
If you used Turnstile appearance, callback, or refresh-expired options, port that behavior to MTCaptcha using JavaScript APIs and JS Callbacks.
Step 2: Update server-side verification​
Replace Turnstile siteverify with MTCaptcha CheckToken:
GET https://service.mtcaptcha.com/mtcv1/api/checktoken?privatekey=YOUR_PRIVATEKEY&token=VERIFIED_TOKEN
Pass the submitted mtcaptcha-verifiedtoken value as token.
Treat each token as short-lived. Validate soon after submission and avoid reusing the same token for multiple CheckToken calls unless you intentionally configure exceptions. See Validate Token (With Private Key).
Use https://service2.mtcaptcha.com/mtcv1/api/checktoken when you need fixed outbound IP allowlists (Validate Token).
Troubleshooting​
| Symptom | What to check |
|---|---|
| Blank widget / script 403 | Domain not allowed for your SiteKey in Admin Portal. |
| CSP errors | Allow https://service.mtcaptcha.com (and service2 if used). |
Still reading cf-turnstile-response | Update form handling to mtcaptcha-verifiedtoken everywhere (tests included). |
token-expired | User delayed submit; regenerate token with a fresh solve. |
| Strict outbound firewall | Switch CheckToken host to service2.mtcaptcha.com per docs. |
Further reading​
- MTCaptcha Quick Start
- Validate Token (With Private Key)
- Low Friction Invisible Captcha
- Works in China
Post-Migration Checklist​
- Removed Turnstile script, widget container, and
siteverifyintegration. -
mtcaptchaConfigwith"sitekey": "YOUR_SITEKEY"precedesmtcaptcha.min.js. - Server verifies
mtcaptcha-verifiedtokenviahttps://service.mtcaptcha.com/mtcv1/api/checktoken. - Ported Turnstile callbacks/refresh behavior to MTCaptcha where required.
- Tested production + staging hostnames against Admin Portal settings.
- CSP/network allows MTCaptcha assets and API.