How to solve a mathematical captcha

The hard part of a mathematical captcha is not the arithmetic — it is automating "image in, answer out". Here is the whole path in order: grab the image, submit it, poll for the answer, type it back, and what to do when it comes back wrong.

Step 1: grab the challenge image

Locate the image in your page or request first. In a browser it is usually an <img id="captchaImage">; older sites may keep it in a <canvas> or as a CSS background. Drawing whatever you found into a canvas and exporting base64 is the most reliable way to get it.

// grab the challenge image and turn it into base64
const img = document.querySelector('#captchaImage')
const canvas = document.createElement('canvas')
canvas.width = img.naturalWidth || img.width
canvas.height = img.naturalHeight || img.height
canvas.getContext('2d').drawImage(img, 0, 0)
const base64 = canvas.toDataURL('image/png').replace(/^data:image/png;base64,/, '')

Most mathematical captchas hand out a single image, so one element in image_data is enough.

Step 2: submit it to the recognition endpoint

Mathematical captchas are the textcaptcha type in the API: send the image, get the answer back as a string.

curl -X POST https://fuckcaptcha.top/v1/recognition/textcaptcha \
  -H 'Authorization: Basic nsk_YOUR_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"image_data":["<base64 from step 1>"]}'

# -> {"data":"nsj_f350ba75d856c66b0b924340"}

An accepted submission returns a job id (data) immediately and charges one credit; a submission that is refused is not charged.

Step 3: poll for the answer

Recognition is asynchronous and an arithmetic image usually finishes in one to three seconds. While polling, error 14 means it is still working, so ask again in 500ms.

# error 14 means it is still working — ask again in 500ms
curl "https://fuckcaptcha.top/v1/recognition/textcaptcha?id=nsj_f350ba75d856c66b0b924340&key=nsk_YOUR_KEY"

# pending  -> {"error":14,"message":"Incomplete job"}
# finished -> {"data":["7"],"metadata":{}}

The data field is an array; its first element is the answer string, for example "7".

Step 4: type the answer back

Put the answer into the input box and fire an input and a change event yourself — many legacy forms only enable submit after those events.

// type the answer back, and let the form know it changed
const input = document.querySelector('#captchaInput')
input.value = '7'                     // data[0] from the poll response
input.dispatchEvent(new Event('input', { bubbles: true }))
input.dispatchEvent(new Event('change', { bubbles: true }))

The whole thing as a Python script

Here are the four steps in one place; change the key and the image source and it runs.

import base64, time, requests

KEY, API = "nsk_YOUR_KEY", "https://fuckcaptcha.top"

def solve(image_bytes):
    b64 = base64.b64encode(image_bytes).decode()
    job = requests.post(f"{API}/v1/recognition/textcaptcha",
                        json={"image_data": [b64]},
                        headers={"Authorization": f"Basic {KEY}"}, timeout=30).json()["data"]
    for _ in range(30):
        time.sleep(1)
        r = requests.get(f"{API}/v1/recognition/textcaptcha",
                         params={"id": job, "key": KEY}, timeout=30).json()
        if "error" not in r:
            return r["data"][0] if isinstance(r["data"], list) else r["data"]
        if r["error"] != 14:
            raise RuntimeError(r)      # 12, 13, 16 ... are terminal
    raise TimeoutError("no answer within 30s")

When the answer is wrong

If you would rather not write code

The browser extension recognises these images and fills the answer in automatically, using the same allowance as the API. If you only hit a mathematical captcha occasionally, the extension is cheaper than maintaining a scraper.

FAQ

Why does polling keep returning error 14?

That means the job is still being worked on. An arithmetic image usually finishes in one to three seconds; if it is still 14 after a minute, submit a fresh image (each accepted job is charged one credit).

Do I convert "three + four" to numbers myself?

No. The endpoint returns the final answer (7); converting words and doing the addition both happen on the recognition side.

Do I need cookies or a signed-in session to submit?

Recognition only needs the image. Fetching it and typing the answer back both happen inside your own session — we do not need your cookies or account.

Am I charged when recognition fails?

A submission that is refused is not charged; once a job is accepted it costs one credit, so retrying is best done with a fresh image.

Related

Read the API reference Download the Chrome extension