> ## Documentation Index
> Fetch the complete documentation index at: https://docs.surfsky.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Turnstile

> Solve a Turnstile challenge and verify that the protected page becomes available.

Turnstile can use the internal manual solver or automatic mode. For a first test, use manual mode after the challenge appears.

<span id="overview" />

<span id="prerequisites" />

<span id="quick-start" />

## Before you start

Use the [CAPTCHA setup example](/captcha-solving#connect-and-solve) to start a browser with `anti_captcha.enabled: true` and create a page-level `cdp` session. The snippets below use an async Playwright or Puppeteer session after navigating to your target.

The internal solver does not require an external provider key. To test it without another solver acting on the same challenge, start with `disable_external_providers: true`.

<span id="method-1-simple-manual-solving-recommended" />

<span id="solving-methods" />

## Manual solving

Wait for the challenge to appear, then send:

<CodeGroup>
  ```python Python theme={null}
  result = await cdp.send("Captcha.solve", {
      "type": "turnstile",
      "timeout": 60000,
  })
  if result["status"] != "success":
      raise RuntimeError(result)
  ```

  ```javascript JavaScript theme={null}
  const result = await cdp.send("Captcha.solve", {
    type: "turnstile",
    timeout: 60000,
  });
  if (result.status !== "success") throw new Error(JSON.stringify(result));
  ```
</CodeGroup>

The timeout is in milliseconds. Detection can raise a CDP error when the expected challenge is absent. After success, wait for a selector or response that identifies the protected content.

<span id="method-2-auto-solving" />

## Automatic solving

Include `"turnstile"` in `anti_captcha.auto_captcha_types` at startup. Attach [solve event listeners](/captcha-solving#automatic-solving), then start detection before navigating:

```javascript theme={null}
await cdp.send("Captcha.autoSolve", { type: "turnstile" });
await page.goto(targetUrl, { waitUntil: "domcontentloaded" });
```

`status: "started"` confirms the background loop started. Observe failures and use a bounded wait for your page result. Keep the CDP session connected until the job completes.

<span id="best-practices" />

<span id="need-help" />

<span id="related" />

<span id="troubleshooting-auto-mode" />

## If solving fails

If detection fails, inspect the page for a Turnstile iframe and wait for it to load. A page may have passed verification already, or it may be blocked before displaying a challenge.

Check [solver configuration](/captcha-solving#provider-configuration), inspect one attempt in [DevTools](/debugging), and record the result or error before retrying. Stop the browser when the job ends.
