> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://platform.bctrl.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://platform.bctrl.ai/_mcp/server.

# Solve CAPTCHA

> Detect and solve a CAPTCHA on an active browser page.

Ask the Challenge solver to detect and solve a CAPTCHA in an active browser
Runtime. The solver applies the result to the page when possible and returns
the solution shape for inspection.

## Solve a challenge

```ts
const result = await bctrl.tools.call("captcha.solve", {
  pageId,
  timeoutMs: 120000,
}, { runtimeId: runtime.id });

if (result.success) {
  console.log(result.type, result.kind, result.artifact);
} else {
  console.log(result.reason, result.error);
}
```

`pageId` is optional. If omitted, the solver uses the Runtime's active page.
The Runtime must be active and use the browser runtime type. `timeoutMs` can be
up to `120000` milliseconds.

## Request parameters

| Parameter   | Type      | Required | Description                                            |
| ----------- | --------- | -------- | ------------------------------------------------------ |
| `pageId`    | `PageId`  | No       | Page to inspect. Uses the active page when omitted.    |
| `timeoutMs` | `integer` | No       | Maximum solve time in milliseconds. Maximum: `120000`. |

## Response

| Field             | Type                        | Always present | Description                                                    |
| ----------------- | --------------------------- | -------------- | -------------------------------------------------------------- |
| `success`         | `boolean`                   | Yes            | Whether the challenge was solved and applied.                  |
| `type`            | `CaptchaType`               | No             | Detected challenge type.                                       |
| `reason`          | `CaptchaSolveFailureReason` | No             | Why solving or applying the solution failed.                   |
| `kind`            | `CaptchaSolveArtifactKind`  | No             | Shape of the returned solution artifact.                       |
| `artifact`        | `CaptchaSolveArtifact`      | No             | Structured solution data, when available.                      |
| `token`           | `string`                    | No             | Token returned by the solver, when available.                  |
| `workerUserAgent` | `string`                    | No             | User agent associated with the solving worker, when available. |
| `duration`        | `number`                    | No             | Solve duration, when available.                                |
| `error`           | `string`                    | No             | Human-readable failure detail.                                 |

Challenge types include `recaptcha_v2`, `recaptcha_v3`, `turnstile`,
`hcaptcha`, `geetest_v3`, `geetest_v4`, `arkose`, `prosopo`, `mtcaptcha`,
`lemin`, `friendly_captcha`, `amazon_waf`, `altcha`, `datadome`, `basilisk`,
`yidun`, and `tendi`.

### Solution artifacts

Inspect `artifact.kind` before reading the artifact fields:

| `kind`          | Shape                                    | Description                                              |
| --------------- | ---------------------------------------- | -------------------------------------------------------- |
| `token`         | `{ token: string }`                      | Token-based solution.                                    |
| `fields`        | `{ fields: Record<string, string> }`     | Form fields to apply.                                    |
| `cookie`        | `{ cookie: Cookie }`                     | Cookie-based solution.                                   |
| `text`          | `{ text: string }`                       | Text returned by the solver.                             |
| `click_points`  | `{ points: { x: number; y: number }[] }` | Coordinates to click.                                    |
| `grid`          | `{ cells: number[] }`                    | Selected challenge cells.                                |
| `browser_state` | `{ browserState: BrowserState }`         | Browser state such as cookies, headers, storage, or URL. |

Failure reasons are `no_captcha`, `unsupported`, `rate_limited`,
`page_not_attached`, `solve_failed`, and `apply_failed`.

## Run asynchronously

```ts
const call = await bctrl.tools.start("captcha.solve", {
  pageId,
  timeoutMs: 120000,
}, { runtimeId: runtime.id });

const result = await bctrl.toolCalls.result(call.id, {
  waitSeconds: 120,
});
```

Use `bctrl.toolCalls.get(call.id)` to inspect progress or
`bctrl.toolCalls.cancel(call.id)` to cancel an active call.

## Next

* [Browser pages](/sdk/tools/browser/browser-pages-list) — choose the page to solve
* [Human in the loop](/sdk/tools/human/human-request) — request help from a person
* [Tools](/sdk/tools) — understand ToolCalls and execution modes