> ## 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.

# AWS WAF Captcha Bypass - Automatic Solver

> Pass the AWS WAF captcha page: setup, manual and automatic solving, charges, and troubleshooting with code examples.

AWS WAF can answer a request with its own captcha page instead of the site's content: HTTP 405, a "Human Verification" title, and a puzzle drawn by `captcha.js`. Passing it sets the `aws-waf-token` cookie, and the site lets the browser through until the token expires.

Each solve is [charged](/captcha-solving#charges).

## Before you start

Enable the solver when [starting the browser](/captcha-solving#enable-solving). AWS WAF is solved automatically only when it is in `auto_captcha_types`:

```json theme={null}
{
  "anti_captcha": {
    "enabled": true,
    "auto_captcha_types": ["aws_waf"]
  }
}
```

## Manual captcha solving

Send `Captcha.solve` once the captcha page has loaded:

```python Python (async Playwright) theme={null}
cdp = await page.context.new_cdp_session(page)
result = await cdp.send("Captcha.solve", {"type": "aws_waf"})
print(result["status"], result.get("usage"))
```

```javascript JavaScript (Playwright) theme={null}
const cdp = await page.context().newCDPSession(page);
const result = await cdp.send("Captcha.solve", { type: "aws_waf" });
console.log(result.status, result.usage);
```

```python Python SDK theme={null}
result = await browser.send("Captcha.solve", {"type": "aws_waf"})
print(result["status"], result.get("usage"))
```

```typescript TypeScript SDK theme={null}
const result = await browser.send("Captcha.solve", { type: "aws_waf" });
console.log(result.status, result.usage);
```

After a pass, the page loads again with the site's content, as after any passed puzzle. `success` means the captcha page did not come back. There is no `solution`: the page keeps its own `aws-waf-token` cookie.

A page that only checks the browser, without a puzzle, needs no solve: the browser passes it by itself.

## Automatic captcha solving

Attach listeners and enable automatic mode before navigating:

```python Python (async Playwright) theme={null}
cdp = await page.context.new_cdp_session(page)
cdp.on("Captcha.solveCompleted", lambda event: print("Completed:", event))
cdp.on("Captcha.solveFailed", lambda event: print("Failed:", event))
await cdp.send("Captcha.autoSolve", {"type": "aws_waf"})
await page.goto(target_url, wait_until="domcontentloaded")
```

```javascript JavaScript (Playwright) theme={null}
const cdp = await page.context().newCDPSession(page);
cdp.on("Captcha.solveCompleted", event => console.log("Completed:", event));
cdp.on("Captcha.solveFailed", event => console.error("Failed:", event));
await cdp.send("Captcha.autoSolve", { type: "aws_waf" });
await page.goto(targetUrl, { waitUntil: "domcontentloaded" });
```

```python Python SDK theme={null}
browser.cdp.on("Captcha.solveCompleted", lambda event, _: print("Completed:", event))
browser.cdp.on("Captcha.solveFailed", lambda event, _: print("Failed:", event))
await browser.send("Captcha.autoSolve", {"type": "aws_waf"})
await browser.goto(target_url, wait_until="domcontentloaded")
```

```typescript TypeScript SDK theme={null}
browser.cdp.on("Captcha.solveCompleted", (event) => console.log("Completed:", event));
browser.cdp.on("Captcha.solveFailed", (event) => console.error("Failed:", event));
await browser.send("Captcha.autoSolve", { type: "aws_waf" });
await browser.goto(targetUrl, { waitUntil: "domcontentloaded" });
```

The page loads again once the puzzle passes: after `Captcha.solveCompleted`, wait for the site's own content before reading the page.

## Troubleshooting

`failed` means AWS WAF showed its captcha page again; retry, or use another proxy. A captcha that a site draws into its own page, instead of AWS WAF's captcha page, is not solved: the command fails with `No captcha detected on the page`.

See [CAPTCHA troubleshooting](/captcha-solving#troubleshooting) for shared errors and [DevTools](/debugging) to inspect a running attempt.

Questions? Contact [support](mailto:hello@surfsky.io).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.