# Migrate From CapSolver: AntiTurnstileTaskProxyLess on ZeroCaptcha

> Move Cloudflare Turnstile tasks from CapSolver to ZeroCaptcha: AntiTurnstileTaskProxyLess and its metadata fields work as they are. Change host and key.

- Source: https://zerocaptcha.io/guides/migrate-from-capsolver
- Published: 2026-09-30
- Updated: 2026-10-01
- Author: ZeroCaptcha Engineering

CapSolver's Cloudflare Turnstile task, `AntiTurnstileTaskProxyLess`, is one of the task types ZeroCaptcha
accepts as it is. A client written for CapSolver's `createTask` and `getTaskResult` sends the
same JSON to ZeroCaptcha, with the action and cData nested in `metadata` the way CapSolver
documents them. The work is changing the host and the key, then checking a few details. This guide
lists them.

ZeroCaptcha is not affiliated with CapSolver. Facts about CapSolver below come from its public
pages, checked 1 October 2026.

## What CapSolver's request looks like

CapSolver documents Turnstile at
[its Cloudflare Turnstile guide](https://docs.capsolver.com/en/guide/captcha/cloudflare_turnstile/): a
`createTask` call to `https://api.capsolver.com/createTask` with the task type
`AntiTurnstileTaskProxyLess`, `websiteURL`, `websiteKey`, and an optional `metadata` object
holding `action` and `cdata`.

## The same request on ZeroCaptcha

```json
{
  "clientKey": "zc_live_…",
  "task": {
    "type": "AntiTurnstileTaskProxyLess",
    "websiteURL": "https://shop.example.com/login",
    "websiteKey": "0x4AAAAAAAB1cD2eF3gH4iJ5",
    "metadata": { "action": "login", "cdata": "sess_91f2c0" }
  }
}
```

Post it to `/createTask` on your ZeroCaptcha API host instead of `api.capsolver.com`. The reply is
`{"errorId": 0, "taskId": "…"}`. Then poll `/getTaskResult` with `clientKey` and `taskId`, as
before, every second or two.

ZeroCaptcha treats `AntiTurnstileTaskProxyLess` exactly like its own `TurnstileTaskProxyless`:
same price, same checks, same result. `AntiTurnstileTask` maps to `TurnstileTask`, which solves
through your proxy. Fields the task does not use, such as `userAgent`, are accepted and ignored.

## In code

With Python and `requests`, the whole change is two values:

```python
import os, time, uuid, requests

API = os.environ["ZEROCAPTCHA_API"]   # was https://api.capsolver.com
KEY = os.environ["ZEROCAPTCHA_KEY"]   # was your CapSolver key

# New: an Idempotency-Key, so a retried create returns the same task instead of a second one.
created = requests.post(f"{API}/createTask", timeout=15, headers={"Idempotency-Key": str(uuid.uuid4())}, json={
    "clientKey": KEY,
    "task": {
        "type": "AntiTurnstileTaskProxyLess",
        "websiteURL": "https://shop.example.com/login",
        "websiteKey": "0x4AAAAAAAB1cD2eF3gH4iJ5",
        # Unchanged from CapSolver: the widget's data-action and data-cdata (or turnstile.render()'s
        # action and cData) in metadata. Leave out any the widget does not set.
        "metadata": {"action": "login", "cdata": "session-7f3a9c2e"},
    },
}).json()
if created["errorId"]:
    raise RuntimeError(created["errorCode"])

while True:
    time.sleep(2)
    result = requests.post(f"{API}/getTaskResult", timeout=15,
                           json={"clientKey": KEY, "taskId": created["taskId"]}).json()
    if result["errorId"]:
        raise RuntimeError(result["errorCode"])
    if result["status"] == "ready":
        print(result["solution"]["token"])
        break
```

For production code with a deadline, retries and idempotency, start from the
[quickstart](https://zerocaptcha.io/docs/quickstart) or the [Python page](https://zerocaptcha.io/cloudflare-turnstile-solver/python). The
[Cloudflare Turnstile solver](https://zerocaptcha.io/cloudflare-turnstile-solver) page has the same flow in Node.js, Go, PHP, Java, C# and
curl.

## Keeping both providers configured

During the move, it helps to run both side by side. Keep the host, the key and the task type in
one small configuration object per provider, and choose the provider per worker or per job. Since
both accept `AntiTurnstileTaskProxyLess` in the same JSON shape, the only values that differ are
the host and the key:

```python
PROVIDERS = {
    "capsolver":   {"api": "https://api.capsolver.com", "key": os.environ["CAPSOLVER_KEY"]},
    "zerocaptcha": {"api": os.environ["ZEROCAPTCHA_API"], "key": os.environ["ZEROCAPTCHA_KEY"]},
}
```

Log which provider solved each task along with the outcome, so you can compare success and solve
time on your own pages before moving everything.

## What a failed task costs

On ZeroCaptcha, a task's price is held when you create it and released at once if the task fails
or times out, so a failed task costs nothing. `getTaskResult` then answers `errorId` 1 with a code
such as `ERROR_CAPTCHA_UNSOLVABLE` or `ERROR_TASK_TIMEOUT`. A task your balance cannot cover is
refused up front with `ERROR_ZERO_BALANCE`. [Captcha API error codes](https://zerocaptcha.io/guides/captcha-api-error-codes)
covers the full list.

## Differences to check

- **Task IDs are UUIDs**, such as `0192f3a4-7b1c-7d2e-9f10-3c4d5e6f7a8b`. Keep them as strings.
- **The solution holds the token and its type**, `solution.token` and `solution.type`
  (`turnstile`). There is no `userAgent` in it. The ready reply adds `cost`, `solveCount`,
  `createTime`, `endTime` and `expiresAt`, which says when the token stops working.
- **Proxies are HTTP or HTTPS.** SOCKS is not supported yet. See
  [Solve Cloudflare Turnstile with a proxy](https://zerocaptcha.io/guides/solve-cloudflare-turnstile-with-a-proxy).
- **"Slow down" is `ERROR_RATE_LIMIT`**, with a `Retry-After` header that says how long to wait. `createTask` has no call budget of its own: your balance and your share of
  the queue bound it. See [Rate limits and concurrency](https://zerocaptcha.io/guides/rate-limits-and-concurrency).
- **Cloudflare challenge pages.** CapSolver lists a Cloudflare Challenge task on
  [its site](https://www.capsolver.com/). ZeroCaptcha accepts AntiCloudflareTask as CloudflareChallengeTask, through your proxy only. See the
  [Cloudflare WAF and 5-second challenge solver](https://zerocaptcha.io/cloudflare-challenge-solver) page.

## Prices

CapSolver lists Cloudflare Turnstile at $1.2 per 1k and Cloudflare Challenge at $1.2 per 1k on
[its home page](https://www.capsolver.com/) (checked 1 October 2026). ZeroCaptcha's price per
1,000 solved tasks is on its [pricing page](https://zerocaptcha.io/pricing). ZeroCaptcha charges only when a token is
ready, from a prepaid US dollar balance you top up in crypto.

## Rolling it out

1. Create a ZeroCaptcha account and key, and add funds: see the [quickstart](https://zerocaptcha.io/docs/quickstart).
2. Put the API host and key in configuration.
3. Send one worker's tasks to ZeroCaptcha and compare results on your own pages.
4. Watch the [status page](https://zerocaptcha.io/status) for the platform's success rate and median solve time.
5. Move the rest.

The [CapSolver alternative](https://zerocaptcha.io/compare/capsolver-alternative) page compares the two services side by
side.

## Questions

### Does ZeroCaptcha accept CapSolver's metadata object?

Yes. The action is read from metadata.action and cData from metadata.cdata when they are not given at the top level of the task.

### Will my CapSolver client read ZeroCaptcha's result?

A solved task answers with status ready and the token in solution.token. A client that expects other solution fields, such as a user agent, needs to stop relying on them.

### Is there an equivalent of CapSolver's Cloudflare Challenge task?

Yes. AntiCloudflareTask is accepted as CloudflareChallengeTask, through your proxy, and the reply carries the cf_clearance cookie and the user agent as CapSolver's does.
