Overview
The Embedded Wallet Kit supports Cloudflare Turnstile captcha protection to help prevent abuse and ensure that authentication requests are performed by real users. When enabled, fresh captcha tokens are required for every Signup request and every InitOtp request (including OTP resends). There are two ways to use captcha with the Embedded Wallet Kit:- Using the built-in Auth component — captcha is handled automatically, no additional code required.
- Building a custom auth UI — you’ll need to integrate Turnstile components yourself in the right places.
Enabling Captcha in the Dashboard
Navigate to Wallet Kit settings
Go to the Turnkey Dashboard, navigate to the Wallet Kit page.
Detecting captcha status on the frontend
Once captcha is enabled in the dashboard, theturnstileSiteKey field will be present in the config returned by the Embedded Wallet Kit (populated from the getWalletKitClientParams request). You can use this to determine whether captcha is active:
Option 1: Using the Built-in Auth Component
If you’re using the Embedded Wallet Kit’s built-in auth component (viahandleLogin), captcha is handled entirely for you. The auth component automatically:
- Pre-warms a captcha token in the background when the user is not authenticated
- Shows a visible Turnstile challenge only if Cloudflare requires user interaction
- Attaches captcha tokens to all Signup and InitOtp requests
- Manages token refresh for the OTP verification step
Option 2: Custom Auth UI
If you’re building your own auth modal or layout, you’ll need to integrate Turnstile components in two places:- The initial auth screen — where users enter their email/phone or choose a sign-up method
- The OTP verification screen — where users enter the OTP code (and can resend)
initOtp cannot be reused for a subsequent signup or another initOtp call.
Install the Turnstile library
We recommend using@marsidev/react-turnstile, a lightweight React wrapper around the Cloudflare Turnstile widget:
Setting up the Turnstile component
Import the component and types:Appearance modes
Cloudflare Turnstile supports several appearance modes. For the best user experience, we recommend:"interaction-only"— The widget is completely hidden unless Cloudflare determines it needs user interaction. This is ideal for most cases as users won’t see anything unless a challenge is required."always"— The widget is always visible. Use this if you want users to always see the captcha.
appearance: "interaction-only" pairs well with this — the widget stays invisible for most users, and only appears when Cloudflare needs interaction.
Auth screen integration
Add a Turnstile component to your auth screen. This component will generate a token that gets consumed when the user initiates a Signup or InitOtp request.OTP screen integration
A second Turnstile component is needed on the OTP verification screen. This generates fresh tokens for completing the OTP or resending it — both of which are captcha-protected requests.Consuming tokens
Each captcha token can only be used once. After consuming a token (e.g., when callinginitOtp), you must reset the widget to generate a new one for the next request:
The
captchaToken parameter is accepted by initOtp, completeOtp, completeOauth, loginOrSignupWithWallet, and OAuth handle methods. When captcha is not enabled, omitting the token has no effect.Best Practices
- Deploy first, enable second: Integrate captcha components into your app before enabling captcha in the dashboard. The Turnstile widget will silently idle when captcha is not enabled (no
turnstileSiteKeyin config). - Always reset after consuming: Call
turnstileRef.current?.reset()after using a token so the widget can generate a fresh one for the next request. - Handle expiration: Turnstile tokens expire after a short period. Listen to the
onExpirecallback and clear your stored token so that users aren’t submitting stale tokens. - Disable submit buttons while waiting: Consider disabling auth buttons until a valid captcha token is available to prevent failed requests.