Przegląd
Metody JSON
Zadania z tokenem
- reCAPTCHA v2
- reCAPTCHA v2 Enterprise
- reCAPTCHA v3
- Cloudflare Turnstile
- GeeTest v3 / v4
- FunCaptcha (Arkose Labs)
- Amazon AWS WAF
- MTCaptcha
- Friendly Captcha
- Lemin Cropped Captcha
- DataDome
- KeyCaptcha
- Capy Puzzle
- Strona Cloudflare Challenge
- Cutcaptcha
- CyberSiARA
- atbCAPTCHA
- Tencent Captcha
- Prosopo Procaptcha
- CaptchaFox
- Altcha
- NetEase Yidun
- Yandex SmartCaptcha
- VK Captcha
- Binance Captcha
- Własne zadanie (Imperva, Temu i inne)
Dokumentacja UNLOCK API
Wyślij CAPTCHA jako zadanie, a potem odbierz odpowiedź. API używa tych samych nazw metod, nazw zadań i kodów błędów co inne API do rozwiązywania CAPTCHA, więc większość istniejącego kodu działa po zmianie hosta i klucza.
Jak działa żądanie
- 1
createTaskUtwórz zadanie
POST /createTask z Twoim kluczem i obiektem zadania. Otrzymujesz taskId. Cena jest od razu pobierana z salda.
- 2
getTaskResultSprawdź wynik
Odczekaj około 5 sekund, a potem wysyłaj POST /getTaskResult co 5 sekund, aż status będzie ready.
- 3
solutionUżyj odpowiedzi
Wstaw token lub tekst z solution do formularza strony. Jeśli zadanie się nie powiedzie, opłata wraca na saldo.
Podstawy
- Bazowy URL
https://unlock-api.com- Klucz API
- 32 znaki, na stronie konta. Wysyłaj go jako clientKey (JSON) lub key (in.php, res.php).
- Format
- Metody JSON: POST z treścią JSON. in.php i res.php: pola formularza GET lub POST; dodaj json=1, aby otrzymać odpowiedzi w JSON.
- Limity
- 1200 żądań na minutę na konto, łącznie ze sprawdzaniem wyników. Po utworzeniu zadania odczekaj około 5 sekund, potem sprawdzaj co 5 sekund.
- Limit czasu
- Zadanie nierozwiązane w ciągu 5 minut kończy się błędem ERROR_CAPTCHA_UNSOLVABLE, a opłata wraca na saldo.
- Rozliczenia
- Cena zadania jest pobierana przy jego utworzeniu. Nieudane zadania są zwracane automatycznie.
Szybki start
Rozwiąż reCAPTCHA v2 metodami JSON. Zastąp YOUR_API_KEY swoim kluczem.
import time, requests
API = "https://unlock-api.com"
KEY = "YOUR_API_KEY"
task = requests.post(f"{API}/createTask", json={
"clientKey": KEY,
"task": {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6LcR_RsTAAAAAFJR_5ZdbQd0SMxL7yIDmSXH1-lo"
}
}).json()
if task["errorId"]:
raise SystemExit(task["errorCode"])
for _ in range(60): # 60 x 5 s = the 5 minute task limit
time.sleep(5)
r = requests.post(f"{API}/getTaskResult", json={"clientKey": KEY, "taskId": task["taskId"]}).json()
if r["errorId"]:
raise SystemExit(f"{r['errorCode']}: {r.get('errorDescription', '')}") # failed tasks are refunded
if r["status"] == "ready":
print(r["solution"]["gRecaptchaResponse"])
break
else:
raise SystemExit("timed out")const API = "https://unlock-api.com";
const KEY = "YOUR_API_KEY";
const post = (path, body) => fetch(API + path, { method: "POST", headers: { "content-type": "application/json" }, body: JSON.stringify(body) }).then((r) => r.json());
const task = await post("/createTask", {
clientKey: KEY,
task: {
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6LcR_RsTAAAAAFJR_5ZdbQd0SMxL7yIDmSXH1-lo"
},
});
if (task.errorId) throw new Error(task.errorCode);
let solution = null;
for (let n = 0; n < 60 && !solution; n++) { // 60 x 5 s = the 5 minute task limit
await new Promise((r) => setTimeout(r, 5000));
const r = await post("/getTaskResult", { clientKey: KEY, taskId: task.taskId });
if (r.errorId) throw new Error(r.errorCode + ": " + r.errorDescription); // failed tasks are refunded
if (r.status === "ready") solution = r.solution;
}
if (!solution) throw new Error("timed out");
console.log(solution.gRecaptchaResponse);<?php
$api = "https://unlock-api.com";
$key = "YOUR_API_KEY";
function post($url, $body) {
$c = curl_init($url);
curl_setopt_array($c, [CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ["Content-Type: application/json"], CURLOPT_POSTFIELDS => json_encode($body)]);
return json_decode(curl_exec($c), true);
}
$task = post("$api/createTask", ["clientKey" => $key, "task" => json_decode('{"type":"RecaptchaV2TaskProxyless","websiteURL":"https://example.com/login","websiteKey":"6LcR_RsTAAAAAFJR_5ZdbQd0SMxL7yIDmSXH1-lo"}', true)]);
if ($task["errorId"]) exit($task["errorCode"]);
for ($n = 0; $n < 60; $n++) { // 60 x 5 s = the 5 minute task limit
sleep(5);
$r = post("$api/getTaskResult", ["clientKey" => $key, "taskId" => $task["taskId"]]);
if ($r["errorId"]) exit($r["errorCode"] . ": " . $r["errorDescription"]); // failed tasks are refunded
if ($r["status"] === "ready") break;
}
if ($r["status"] !== "ready") exit("timed out");
print_r($r["solution"]["gRecaptchaResponse"]);package main
import (
"bytes"
"encoding/json"
"fmt"
"net/http"
"time"
)
const api = "https://unlock-api.com"
const key = "YOUR_API_KEY"
func post(method string, body map[string]any) map[string]any {
b, _ := json.Marshal(body)
res, err := http.Post(api+"/"+method, "application/json", bytes.NewReader(b))
if err != nil {
panic(err)
}
defer res.Body.Close()
var out map[string]any
json.NewDecoder(res.Body).Decode(&out)
return out
}
func main() {
task := post("createTask", map[string]any{
"clientKey": key,
"task": map[string]any{
"type": "RecaptchaV2TaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "6LcR_RsTAAAAAFJR_5ZdbQd0SMxL7yIDmSXH1-lo",
},
})
if task["errorId"].(float64) != 0 {
panic(task["errorCode"])
}
for n := 0; n < 60; n++ { // 60 x 5 s = the 5 minute task limit
time.Sleep(5 * time.Second)
r := post("getTaskResult", map[string]any{"clientKey": key, "taskId": task["taskId"]})
if r["errorId"].(float64) != 0 {
panic(r["errorCode"]) // failed tasks are refunded
}
if r["status"] == "ready" {
fmt.Println(r["solution"])
return
}
}
panic("timed out")
}import java.net.URI;
import java.net.http.*;
import java.util.regex.*;
public class Solve {
static final String API = "https://unlock-api.com", KEY = "YOUR_API_KEY";
static final HttpClient HTTP = HttpClient.newHttpClient();
static String post(String method, String json) throws Exception {
var req = HttpRequest.newBuilder(URI.create(API + "/" + method))
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(json)).build();
return HTTP.send(req, HttpResponse.BodyHandlers.ofString()).body();
}
public static void main(String[] args) throws Exception {
String task = "{\"type\":\"RecaptchaV2TaskProxyless\",\"websiteURL\":\"https://example.com/login\",\"websiteKey\":\"6LcR_RsTAAAAAFJR_5ZdbQd0SMxL7yIDmSXH1-lo\"}";
String created = post("createTask", "{\"clientKey\":\"" + KEY + "\",\"task\":" + task + "}");
Matcher id = Pattern.compile("\"taskId\":(\\d+)").matcher(created);
if (!id.find()) throw new RuntimeException(created);
for (int n = 0; n < 60; n++) { // 60 x 5 s = the 5 minute task limit
Thread.sleep(5000);
String r = post("getTaskResult", "{\"clientKey\":\"" + KEY + "\",\"taskId\":" + id.group(1) + "}");
if (r.contains("\"errorId\":1")) throw new RuntimeException(r); // failed tasks are refunded
if (r.contains("\"status\":\"ready\"")) { System.out.println(r); return; }
}
throw new RuntimeException("timed out");
}
}using System.Net.Http.Json;
using System.Text.Json;
const string Api = "https://unlock-api.com";
const string Key = "YOUR_API_KEY";
var http = new HttpClient();
async Task<JsonElement> Post(string method, object body) =>
await (await http.PostAsJsonAsync($"{Api}/{method}", body)).Content.ReadFromJsonAsync<JsonElement>();
var task = await Post("createTask", new {
clientKey = Key,
task = JsonSerializer.Deserialize<JsonElement>("""
{"type":"RecaptchaV2TaskProxyless","websiteURL":"https://example.com/login","websiteKey":"6LcR_RsTAAAAAFJR_5ZdbQd0SMxL7yIDmSXH1-lo"}
""")
});
if (task.GetProperty("errorId").GetInt32() != 0) throw new Exception(task.GetProperty("errorCode").GetString());
for (var n = 0; n < 60; n++) { // 60 x 5 s = the 5 minute task limit
await Task.Delay(5000);
var r = await Post("getTaskResult", new { clientKey = Key, taskId = task.GetProperty("taskId").GetInt64() });
if (r.GetProperty("errorId").GetInt32() != 0) throw new Exception(r.GetProperty("errorCode").GetString()); // failed tasks are refunded
if (r.GetProperty("status").GetString() == "ready") { Console.WriteLine(r.GetProperty("solution")); return; }
}
throw new Exception("timed out");curl -s https://unlock-api.com/createTask \
-H "Content-Type: application/json" \
-d '{"clientKey":"YOUR_API_KEY","task":{"type":"RecaptchaV2TaskProxyless","websiteURL":"https://example.com/login","websiteKey":"6LcR_RsTAAAAAFJR_5ZdbQd0SMxL7yIDmSXH1-lo"}}'
# {"errorId":0,"taskId":1001}
curl -s https://unlock-api.com/getTaskResult \
-H "Content-Type: application/json" \
-d '{"clientKey":"YOUR_API_KEY","taskId":1001}'
# {"errorId":0,"status":"processing"} then {"errorId":0,"status":"ready","solution":{...},"cost":"0.001"}Metody
createTaskTworzy zadanie i zwraca jego id. Cena typu zadania jest pobierana z salda, gdy zadanie zostanie przyjęte, i zwracana, jeśli zadanie się nie powiedzie.getTaskResultZwraca stan zadania. W trakcie rozwiązywania status ma wartość processing. Po zakończeniu status ma wartość ready, a solution zawiera odpowiedź. Nieudane zadanie zwraca errorId 1 z przyczyną, a opłata za nie jest już z powrotem na saldzie.getBalanceZwraca saldo konta w dolarach amerykańskich.getTokenTworzy zadanie i czeka na odpowiedź w tym samym żądaniu, do 50 sekund. Jeśli do tego czasu zadanie nie jest gotowe, odpowiedź zawiera status processing i taskId; dalej sprawdzaj je przez getTaskResult. Callbacki z wynikiem nie są wysyłane dla zadań getToken.getQueueStatsZwraca bieżącą kolejkę: zadania oczekujące, zadania w trakcie rozwiązywania i średni czas rozwiązania z ostatniej godziny. Liczby pochodzą z prawdziwych zadań, nie z szacunków.getSpendingStatsZwraca Twoje wydatki z jednego dnia UTC, godzina po godzinie: liczbę zadań i wydaną kwotę. Zadania nieudane i zwrócone nie są liczone.reportCorrect, reportIncorrectZgłoś poprawną lub błędną odpowiedź. Te wywołania są przyjmowane, aby istniejące biblioteki dalej działały; zgłoszenie nie zmienia opłaty.testEcho do debugowania. Zwraca otrzymaną treść JSON bez clientKey. Bez sprawdzania klucza i bez opłaty.
Poradniki
- Klucze API i bezpieczeństwoJak wysyłać klucz, używać kilku kluczy i dopuścić tylko własne serwery.
- Limity, czas i rozliczeniaLimity żądań, jak często sprawdzać wyniki, limit czasu i kiedy pobierana jest opłata.
- Kody błędówWszystkie kody błędów: co oznaczają, co zrobić i czy pobierana jest opłata.
- Korzystanie z proxyKiedy rozwiązywać przez własne proxy i jak je wysłać.
- Callbacki z wynikiemOdbieraj wynik na swoim serwerze zamiast go sprawdzać.
- API formularzy: in.php i res.phpKlasyczne żądania in.php i res.php dla kodu pisanego pod starsze API do rozwiązywania CAPTCHA.
Typy zadań
Każdy typ ma własną stronę ze wszystkimi parametrami, obiektem solution i przykładami.
Zadania z tokenem
- reCAPTCHA v2
RecaptchaV2TaskProxylessuserrecaptcha - reCAPTCHA v2 Enterprise
RecaptchaV2EnterpriseTaskProxylessuserrecaptcha, enterprise=1 - reCAPTCHA v3
RecaptchaV3TaskProxylessuserrecaptcha, version=v3 - Cloudflare Turnstile
TurnstileTaskProxylessturnstile - GeeTest v3 / v4
GeeTestTaskProxylessgeetest, geetest_v4 - FunCaptcha (Arkose Labs)
FunCaptchaTaskProxylessfuncaptcha - Amazon AWS WAF
AmazonTaskProxylessamazon_waf - MTCaptcha
MtCaptchaTaskProxylessmt_captcha - Friendly Captcha
FriendlyCaptchaTaskProxylessfriendly_captcha - Lemin Cropped Captcha
LeminTaskProxylesslemin - DataDome
DataDomeSliderTaskdatadome - KeyCaptcha
KeyCaptchaTaskProxylesskeycaptcha - Capy Puzzle
CapyTaskProxylesscapy - Strona Cloudflare Challenge
AntiCloudflareTaskcloudflare_challenge - Cutcaptcha
CutCaptchaTaskProxylesscutcaptcha - CyberSiARA
AntiCyberSiAraTaskProxylesscybersiara - atbCAPTCHA
AtbCaptchaTaskProxylessatb_captcha - Tencent Captcha
TencentTaskProxylesstencent - Prosopo Procaptcha
ProsopoTaskProxylessprosopo - CaptchaFox
CaptchaFoxTaskProxylesscaptchafox - Altcha
AltchaTaskProxylessaltcha - NetEase Yidun
YidunTaskProxylessyidun - Yandex SmartCaptcha
YandexSmartCaptchaTaskProxylessyandex - VK Captcha
VKCaptchaTaskProxylessvkcaptcha - Binance Captcha
BinanceTaskProxylessbinance - Własne zadanie (Imperva, Temu i inne)
CustomTaskincapsula, temuimage, hunt, tspd, basilisk
Zadania z obrazkami i audio
- Tekst z obrazka
ImageToTextTaskpost, base64 - Pytanie tekstowe
TextCaptchaTasktextcaptcha - Siatka obrazków
GridTaskpost, recaptcha=1 - Współrzędne kliknięcia
CoordinatesTaskpost, coordinatescaptcha=1 - Obrót
RotateTaskrotatecaptcha - Audio
AudioTaskaudio - Ramka wokół obiektu
BoundingBoxTaskbounding_box - Obrysowanie
DrawAroundTaskpost, canvas=1 - Przeciągnij i upuść
DragAndDropTask- - Złożone zadanie z obrazkami
ComplexImageTask-