API docs

CAPTCHA solving API

Standard createTask / getTaskResult. Base URL: https://landing.eysi.net/api

Overview

REST · JSON
Base URL
https://landing.eysi.net/api
Authentication
Send clientKey in the body, or the X-API-Key header
Content-Type
application/json
Rate limit
120 requests / minute / IP (contact us to raise it)
Billing
Charged per request accepted, right or wrong answer alike

1. Create task — POST /createTask

Request

{
  "clientKey": "ac-xxxxxxxxxxxxxxxx",
  "task": {
    "type": "ReCaptchaV2TaskProxyLess",
    "websiteURL": "https://target.com/login",
    "websiteKey": "6Lc..."
  }
}

Response

{
  "errorId": 0,
  "taskId": "9f1c2b7e-...-a91f",
  "status": "idle",
  "balance": 49.9992
}

2. Get result — POST /getTaskResult

Request

{
  "clientKey": "ac-xxxxxxxxxxxxxxxx",
  "taskId": "9f1c2b7e-...-a91f"
}

Poll again every 2–3 seconds until status = ready.

Response

{
  "errorId": 0,
  "status": "ready",
  "solution": {
    "gRecaptchaResponse": "03AGdBq25...",
    "userAgent": "Mozilla/5.0 ..."
  },
  "cost": 0.0008,
  "solveMs": 3480
}

3. Check balance — POST /getBalance

Request

{ "clientKey": "ac-xxxxxxxxxxxxxxxx" }

Response

{ "errorId": 0, "balance": 49.9992, "currency": "USD" }

Examples by language

curl -X POST https://landing.eysi.net/api/createTask \
  -H "Content-Type: application/json" \
  -d '{"clientKey":"ac-xxxx","task":{"type":"AntiTurnstileTaskProxyLess","websiteURL":"https://target.com","websiteKey":"0x4AAA..."}}'

curl -X POST https://landing.eysi.net/api/getTaskResult \
  -H "Content-Type: application/json" \
  -d '{"clientKey":"ac-xxxx","taskId":"9f1c2b7e-..."}'
import requests, time

API, KEY = "https://landing.eysi.net/api", "ac-xxxx"

r = requests.post(f"{API}/createTask", json={
    "clientKey": KEY,
    "task": {"type": "ImageToTextTask", "body": "<base64 image>"},
}).json()

if r["errorId"]:
    raise Exception(r["errorDescription"])

while True:
    res = requests.post(f"{API}/getTaskResult",
        json={"clientKey": KEY, "taskId": r["taskId"]}).json()
    if res.get("status") == "ready":
        print(res["solution"]); break
    if res["errorId"]:
        raise Exception(res["errorDescription"])
    time.sleep(2)
const API = "https://landing.eysi.net/api", KEY = "ac-xxxx";

const post = (path, body) =>
  fetch(`${API}${path}`, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify(body),
  }).then(r => r.json());

const { taskId } = await post("/createTask", {
  clientKey: KEY,
  task: { type: "ReCaptchaV3TaskProxyLess", websiteURL: "https://target.com",
          websiteKey: "6Lc...", pageAction: "login" },
});

while (true) {
  const res = await post("/getTaskResult", { clientKey: KEY, taskId });
  if (res.status === "ready") { console.log(res.solution); break; }
  await new Promise(r => setTimeout(r, 2000));
}
<?php
$api = 'https://landing.eysi.net/api'; $key = 'ac-xxxx';

function post($url, $data) {
    $ch = curl_init($url);
    curl_setopt_array($ch, [
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode($data),
    ]);
    return json_decode(curl_exec($ch), true);
}

$task = post("$api/createTask", [
    'clientKey' => $key,
    'task' => ['type' => 'AntiCloudflareTask', 'websiteURL' => 'https://target.com'],
]);

do {
    sleep(2);
    $res = post("$api/getTaskResult", ['clientKey' => $key, 'taskId' => $task['taskId']]);
} while (($res['status'] ?? '') === 'processing');

print_r($res['solution']);

Task type list

Field names inside task follow the international standard, so your existing code only needs a new endpoint and clientKey.

Task type Services Required parameters Note Price / 1,000
reCAPTCHA v2 Google
websiteURL, websiteKey $1.60
reCAPTCHA v2 (own proxy) Google
websiteURL, websiteKey, proxy proxy required $1.60
reCAPTCHA v2 Enterprise Google
websiteURL, websiteKey $2.40
reCAPTCHA v2 Enterprise (own proxy) Google
websiteURL, websiteKey, proxy proxy required $2.40
reCAPTCHA v3 Google
websiteURL, websiteKey, pageAction $2.00
reCAPTCHA v3 (own proxy) Google
websiteURL, websiteKey, pageAction, proxy proxy required $2.00
reCAPTCHA v3 Enterprise Google
websiteURL, websiteKey, pageAction $6.00
reCAPTCHA v3 Enterprise (own proxy) Google
websiteURL, websiteKey, pageAction, proxy proxy required $6.00
Cloudflare Turnstile Cloudflare
websiteURL, websiteKey $2.00
Cloudflare Challenge Cloudflare
websiteURL, proxy proxy required $3.00
GeeTest
websiteURL, gt, challenge $2.40
GeeTest v4
websiteURL, captchaId $2.40
GeeTest v4 (own proxy)
websiteURL, captchaId, proxy proxy required $2.40
GeeTest (own proxy)
websiteURL, gt, challenge, proxy proxy required $2.40
MTCaptcha
websiteURL, websiteKey $2.40
MTCaptcha (own proxy)
websiteURL, websiteKey, proxy proxy required $2.40
DataDome
captchaUrl, userAgent, proxy proxy required $4.00
AWS WAF
websiteURL $3.00
AWS WAF (own proxy)
websiteURL, proxy proxy required $3.00
Botdeflector
websiteURL, domain, flowToken $3.00
Image to Text (OCR)
body instant result $0.80
AWS WAF grid recognition
images, question instant result $0.80
Vision Engine
module, image, imageBackground instant result $1.20

Parameters by type

reCAPTCHA v2 / v3

{
  "type": "ReCaptchaV3TaskProxyLess",
  "websiteURL": "https://target.com/login",
  "websiteKey": "6Lc...",
  "pageAction": "login",          // v3
  "isInvisible": false,           // v2 invisible
  "enterprisePayload": { "s": "..." },
  "apiDomain": "recaptcha.net"
}

solution: gRecaptchaResponse, userAgent

Cloudflare Turnstile

{
  "type": "AntiTurnstileTaskProxyLess",
  "websiteURL": "https://target.com",
  "websiteKey": "0x4AAA...",
  "metadata": {
    "action": "data-action of the widget",
    "cdata": "data-cdata of the widget"
  }
}

What you get back: token · type · userAgent

Handles every widget mode (managed, non-interactive, invisible) automatically — no proxy needed. Coming from another service? Just send action / data / pagedata flat — we move them into metadata for you.

Turnstile or Challenge?

What you see on the target pageUse this typeYou get back
The page loads normally and only shows a single Cloudflare widget in the form (an element whose data-sitekey starts with 0x4) AntiTurnstileTaskProxyLess token
The whole page is blocked, showing "Just a moment…" with a 403 — you never reach the content AntiCloudflareTask proxy required cookies.cf_clearance

Picking the wrong one always fails: Turnstile needs the widget sitekey, while a Challenge page has no sitekey at all.

Cloudflare Challenge (proxy required)

2 – 20s
{
  "type": "AntiCloudflareTask",
  "websiteURL": "https://target.com",     // required
  "proxy": "http:1.2.3.4:8080:user:pass",  // required
  "userAgent": "Mozilla/5.0 ... Chrome/141.0.0.0 ...",  // recommended
  "html": "<!DOCTYPE html>...Just a moment..."  // recommended
}

What you get back:

{
  "cookies": { "cf_clearance": "Bcg6jNLz..." },
  "token": "Bcg6jNLz...",
  "userAgent": "Mozilla/5.0 ..."
}
Four things you must get right, or it will fail:
  1. Use a static or sticky proxy and keep the session alive for at least 3 minutes. Rotating proxies will fail.
  2. Send the exact userAgent you use (Chrome only), and reuse that same string for later requests.
  3. Include the html of the 403 "Just a moment…" page fetched through that same proxy — some sites require it.
  4. Request the target site with a TLS-fingerprint library, sending the cf_clearance cookie and the matching User-Agent.

DataDome (proxy required)

{
  "type": "DatadomeSliderTask",
  "captchaUrl": "https://geo.captcha-delivery.com/captcha/?initialCid=...",
  "userAgent": "Mozilla/5.0 ...",
  "proxy": "http:1.2.3.4:8080:user:pass"
}

solution: cookie (datadome=…). the userAgent must match the UA you use to request the target page; if captchaUrl contains t=bv your IP is blocked.

GeeTest v3 / v4

// v3 — take gt and challenge from the target page
{ "type": "GeeTestTaskProxyLess",
  "websiteURL": "https://target.com",
  "gt": "...", "challenge": "...",
  "geetestApiServerSubdomain": "api.geetest.com" }  // optional

// v4 — uses captchaId, NO gt/challenge
{ "type": "GeeTestV4TaskProxyLess",
  "websiteURL": "https://target.com",
  "captchaId": "...",
  "riskType": "slide" }  // optional
v3 returns: challenge · validate · seccode
v4 returns: captcha_id · lot_number · pass_token · gen_time · captcha_output
Each parameter set works only once — fetch a fresh one from the target page for the next call.

AWS WAF

{ "type": "AntiAwsWafTaskProxyLess",
  "websiteURL": "https://target.com" }

// for stubborn pages, also send the values from window.gokuProps
{ "type": "AntiAwsWafTaskProxyLess",
  "websiteURL": "https://target.com",
  "awsKey": "AQID...",
  "awsIv": "A6we...",
  "awsContext": "rGXm...",
  "awsChallengeJS": "https://....../challenge.js" }

Returns cookie (aws-waf-token). The key / iv / context values live in window.gokuProps on the captcha page — re-read them for every call, they expire fast.

MTCaptcha · Botdeflector

{ "type": "MtCaptchaTaskProxyLess",
  "websiteURL": "https://target.com",
  "websiteKey": "MTPublic-..." }

{ "type": "AntiBotdeflectorTaskProxyLess",
  "websiteURL": "https://target.com",
  "domain": "target.com",
  "flowToken": "..." }

Returns token. MTCaptcha sitekeys always start with MTPublic-.

Image recognition (instant result)

{ "type": "ImageToTextTask",
  "body": "<base64 no data: prefix>",
  "module": "common" }

{ "type": "VisionEngine",
  "module": "slider_1",
  "image": "<base64>",
  "imageBackground": "<base64>" }
These tasks return the answer right inside the createTask response — one call, no getTaskResult needed.
ImageToTextTask: module common by default; for digit-only images use module number and send an images array of up to 9. Returns text · answers · confidence.
VisionEngine: module is botdeflector · slider_1 · rotate_1 · rotate_2 · shein · ocr_gif. Only shein also needs question. Returns points — the coordinates to click.
AwsWafClassification: send images and question, get back objects — the indexes of the tiles to click.

Proxy format

"proxy": "http:1.2.3.4:8080:username:password"     // with authentication
"proxy": "socks5:1.2.3.4:1080:username:password"   // socks4 / socks5 / http / https
"proxy": "1.2.3.4:8080:username:password"          // no prefix = http
"proxy": "1.2.3.4:8080"                            // no authentication
"proxy": "http://username:[email protected]:8080"   // URL form

A malformed value is rejected immediately with ERROR_BAD_PROXY — you are not charged. For IP-authenticated proxies, contact support for the list of IPs to whitelist.

Only the types marked proxy required need this field; the rest use our infrastructure, so you do not need a proxy.

Error codes

errorCodeMeaningHow to fix
ERROR_KEY_DOES_NOT_EXISTinvalid or missing clientKeyCheck your API key in the dashboard
ERROR_ZERO_BALANCEInsufficient USD balanceDeposit more USDT
ERROR_TASK_NOT_SUPPORTEDtask.type does not existCheck the task type table above
ERROR_TASKID_INVALIDtaskId does not belong to this accountUse the taskId you just created
ERROR_TIMEOUTThe task timed outCoins refunded, send the task again
ERROR_TASK_TIMEOUTThe solver took too longCoins refunded, send the task again
ERROR_SOLVE_FAILEDCaptcha could not be solvedCoins refunded, try again or change proxy
ERROR_CAPTCHA_UNSOLVABLECaptcha could not be recognisedCoins refunded, please try again
ERROR_INVALID_TASK_DATAMissing / invalid parameters in the taskCheck the "Parameters by type" section (no charge)
ERROR_PROXY_REQUIREDThis task type requires a proxyAdd the proxy field (no charge)
ERROR_PROXY_BANNEDProxy blocked by the target siteUse a different proxy
ERROR_INVALID_IMAGEImage size / format is invalidSend clean base64, without the data: prefix
ERROR_SERVICE_UNAVAILABLEThe system is overloadedCoins refunded, try again in a few minutes
ERROR_ACCOUNT_SUSPENDEDAccount suspendedContact support