# Migrating from 2Captcha

> Move reCAPTCHA image grid jobs from 2Captcha to Solvecha. The API is different, so this page maps each field.

2Captcha and Solvecha do not share an API, so this is not a drop-in switch. For reCAPTCHA image grids you change a few lines: the URL, the key, the image field, the task text and the way you read the answer.

2Captcha uses `createTask` and `getTaskResult` with a `GridTask`. Solvecha uses one path to create a job and to fetch its answer.

## Field mapping

| 2Captcha | Solvecha |
|---|---|
| `POST https://api.2captcha.com/createTask` | `POST https://api.solvecha.com/v1/recognition/recaptcha` |
| `clientKey` | `key`, or an `Authorization: Bearer` header |
| `task.type` `GridTask` | The path ends in `/recaptcha` |
| `task.body` (base64 image) | `image_data: ["<base64>"]` |
| `task.rows` and `task.columns` | `grid`: `3x3` or `4x4` |
| `task.comment` (the instruction) | `task`: the instruction text |
| `POST /getTaskResult` | `GET` the same path with `id` until error `14` is gone |
| `solution.click` (tile numbers from 1) | `data`: one `true` or `false` per tile, left to right, top to bottom |

The mapping was read from the 2Captcha documentation on 17 October 2026. Check it against their current pages before you rely on it.

## Before and after

```python
import requests

task = requests.post("https://api.2captcha.com/createTask", json={
    "clientKey": "YOUR_2CAPTCHA_KEY",
    "task": {
        "type": "GridTask",
        "body": image_b64,
        "rows": 3,
        "columns": 3,
        "comment": "Select all images with a bus",
    },
}).json()
# poll POST /getTaskResult with task["taskId"]; the answer is solution["click"]
```

```python
import time
import requests

headers = {"Authorization": "Bearer YOUR_API_KEY"}
job = requests.post(
    "https://api.solvecha.com/v1/recognition/recaptcha",
    headers=headers,
    json={"task": "Select all images with a bus", "grid": "3x3", "image_data": [image_b64]},
).json()

while True:
    time.sleep(1)
    r = requests.get("https://api.solvecha.com/v1/recognition/recaptcha", headers=headers, params={"id": job["data"]})
    if r.status_code != 409:  # error 14: not ready yet
        break
click = [i + 1 for i, selected in enumerate(r.json()["data"]) if selected]  # tile numbers from 1
```

## What is different

- **No token API and no instruction image.** Solvecha returns answers for the images you send. If you need a token, let the [browser extension](https://solvecha.com/docs/browser-extension.md) click the tiles in a real browser.
- **Price model.** Solvecha is a monthly plan with a daily quota of successful solves. 2Captcha prices are in euro, ours in US dollars. See [Plans and billing](https://solvecha.com/docs/plans-and-billing.md) and the [compare page](https://solvecha.com/compare).
- **Task text.** Send the full instruction sentence.

More on the format: [reCAPTCHA image grids](https://solvecha.com/docs/captcha-types/recaptcha.md) and [Create a reCAPTCHA job](https://solvecha.com/docs/api/create-recaptcha-job.md).
