Skip to main content
Surfsky exposes CAPTCHA commands through a page-level CDP session. Enable anti_captcha when starting the browser, choose a solver for the challenge, and verify the page state after solving.

Enable solving

Add this to the browser start body:
Use auto_captcha_types to restrict automatic detection to the types your page needs. It does not restrict an explicit manual Captcha.solve request.

Provider configuration

Some solvers are free. The others are built in but paid separately: each of their solves is charged on top of browser time, as described in Charges. The Cost column below shows which is which.

Choose a method

Support can vary by challenge version and site configuration. Test on your target page and check that the protected content loads.

Connect and solve

This Python example starts a browser, connects Playwright, and attempts a manual Turnstile solve. Install the packages and set your Surfsky credentials:
Replace TARGET_URL with the page you are testing. Save as solve.py:
Run it:
A successful attempt returns {"status": "success", "type": "turnstile", "solution": "<token>"}. If no challenge is present, the command fails with the CDP error No captcha detected on the page. The final API request stops the browser when the example exits. For JavaScript, start with the Playwright lifecycle, add anti_captcha to its start body, and create the CDP session with await page.context().newCDPSession(page). The command parameters are the same.

With an SDK

The Python and TypeScript SDKs start the session and speak CDP themselves. Pass anti_captcha to client.browser() and send the commands with browser.send. Install the Python or TypeScript SDK, set TARGET_URL and your credentials as above, and run:
The browser stops when the block exits. browser.send waits 60 seconds for a reply: for a solver whose timeout is longer, such as reCAPTCHA, start the browser with command_timeout=200 in Python (seconds) or commandTimeout: 200_000 in TypeScript (milliseconds). Events arrive through browser.cdp.on(event, handler). The handler gets the event’s fields and the page’s session id.

Manual solving

Captcha.solve waits for one attempt to finish:
Pass only the options listed in the selected solver’s guide. Solvers may ignore other fields even when the request accepts them. Results include status and type. Statuses include success, failed, timeout, and not_detected, which means there was nothing to solve, for example a widget that had already passed. On success, solution holds the answer when the solver has one, such as a token or the recognized text. Invalid parameters and detection failures raise CDP errors instead of returning a status object. A charged solve also returns usage, on failed and timeout too:
usage.cost_usd is what the solve was charged.

Automatic solving

Use Captcha.autoSolve to start background detection on the page. Attach event listeners before starting it, then navigate:
The response {"status": "started"} confirms that background solving started. Wait for the expected page content or response to confirm completion, and set a timeout for that wait. type restricts detection to one allowed type. Omit it to detect among the configured auto_captcha_types. Calling autoSolve again replaces the current background loop; disconnecting the CDP client ends it. After three failed solves in a row of one type, the loop stops solving that type, sends a Captcha.solveFailed event with error, and keeps solving the others; with type set, the loop ends. A challenge that has already passed is skipped without events.

Events

Payload fields depend on the event. Captcha.solveCompleted and Captcha.solveFailed carry the same fields as a Captcha.solve result, usage included. A solve that ended in an error sends error and the type when known.

Charges

A paid solve is charged whatever its outcome, failed and timeout included: how hard a challenge gets depends mostly on the proxy and the browser session. The charge equals the solve’s usage.cost_usd and is recorded against the browser session. Nothing is charged when the challenge passes on its own, such as a reCAPTCHA checkbox that passes without a challenge or a GeeTest widget that passes on its button. Automatic mode solves, and charges for, every type it is allowed, and the default auto_captcha_types includes paid types. Set your own list to control what is charged.

Troubleshooting

Use DevTools or Screencast to observe one attempt before increasing concurrency. Keep provider keys out of logs and source control.