FunCaptcha

Attention!
Built-in proxies are used by default — their cost is already included in the service. You only need to specify your own proxies in cases where the website does not accept the token or access to the built-in services is restricted.

If you are using a proxy, please use a proxy with username and password authentication.
IMPORTANT: Some parameter values are dynamic — they change with each render of the page using FunCaptcha. Extract them immediately before creating the task to avoid errors during solving.

Task Type

Task TypeDescription
FunCaptchaTaskSolve FunCaptcha (with or without proxy)

Request Parameters

ParameterTypeRequiredDescription
type String Required FunCaptchaTask
websiteURL String Required The URL of the page where the captcha is located.
websitePublicKey String Required FunCaptcha key (value public key or pk).
data String Optional Additional parameter. Required if the site uses data[blob].
Important: Do not load the captcha iframe to extract blob. Once the captcha is loaded, the value becomes invalid.
funcaptchaApiJSSubdomain String Optional Arkose Labs subdomain (value surl). Specify only if it differs from the default: client-api.arkoselabs.com.
Important: Specify only the domain, without the https:// prefix.
userAgent String Optional Browser User-Agent. Pass only a current Windows OS UA.
cookies String Optional Additional cookies in format: cookieName1=value1; cookieName2=value2
proxyType String Optional http - regular http/https proxy;
https - try this option only if "http" doesn't work;
socks4 - socks4 proxy;
socks5 - socks5 proxy.
proxyAddress String Optional IPv4/IPv6 proxy IP address.
proxyPort Integer Optional Proxy port.
proxyLogin String Optional Proxy-server login.
proxyPassword String Optional Proxy-server password.

Create Task - Without Proxy

Request

POST https://captcha69.com/createTask
Content-Type: application/json

{
  "clientKey": "max1_YOUR_API_KEY",
  "task": {
    "type": "FunCaptchaTask",
    "websiteURL": "https://www.example.com",
    "websitePublicKey": "EX72CCFB-26EX-40E5-91E6-85EX70BE98ED",
    "funcaptchaApiJSSubdomain": "example-api.arkoselabs.com",
    "data": "{\"blob\":\"nj9UbL+yio7goOlTQ/b64t.ayrrBnP6kPgzlKYCP/kv491lKS...Wot/7gjpyIxs7VYb0+QuRcfQ/t6bzh5pXDkOFSskA/V/ITSVZSAlglIplLcdreZ4PE8skfMU6k1Q\"}",
    "userAgent": "userAgentPlaceholder"
  }
}

Response

{
  "errorId": 0,
  "taskId": 407533077
}

Create Task - With Proxy

Request

POST https://captcha69.com/createTask
Content-Type: application/json

{
  "clientKey": "max1_YOUR_API_KEY",
  "task": {
    "type": "FunCaptchaTask",
    "websiteURL": "https://www.example.com",
    "websitePublicKey": "EX72CCFB-26EX-40E5-91E6-85EX70BE98ED",
    "funcaptchaApiJSSubdomain": "example-api.arkoselabs.com",
    "data": "{\"blob\":\"nj9UbL+yio7goOlTQ/b64t.ayrrBnP6kPgzlKYCP/kv491lKS...\"}",
    "userAgent": "userAgentPlaceholder",
    "proxyType": "http",
    "proxyAddress": "8.8.8.8",
    "proxyPort": 8080,
    "proxyLogin": "proxyLoginHere",
    "proxyPassword": "proxyPasswordHere"
  }
}

Response

{
  "errorId": 0,
  "taskId": 407533077
}

Get Task Result

Request

POST https://captcha69.com/getTaskResult
Content-Type: application/json

{
  "clientKey": "max1_YOUR_API_KEY",
  "taskId": 407533077
}

Response

{
  "errorId": 0,
  "errorCode": null,
  "errorDescription": null,
  "solution": {
    "token": "337187b9f57678923.5060184402|r=us-west-2|lang=en|pk=EX72CCFB-26EX-40E5-91E6-85EX70BE98ED|at=40|ag=101|cdn_url=https%3A%2F%2Fclient-api.arkoselabs.com%2Fcdn%2Ffc|surl=https%3A%2F%2Fclient-api.arkoselabs.com|smurl=https%3A%2F%2Fclient-api.arkoselabs.com%2Fcdn%2Ffc%2Fassets%2Fstyle-manager",
    "userAgent": "userAgentPlaceholder"
  },
  "status": "ready"
}

Solution Properties

PropertyTypeDescription
token String The FunCaptcha solution token to be used on the target website.

Finding FunCaptcha Parameters

websitePublicKey and funcaptchaApiJSSubdomain

Open DevTools → Elements and find the hidden input with ID verification-token or FunCaptcha-Token. These contain the pk (websitePublicKey) and surl (funcaptchaApiJSSubdomain) values.

Get parameters via console:

const v = document.querySelector("#verification-token, #FunCaptcha-Token").value;
const p = Object.fromEntries(v.split("|").map(x => x.split("=")));
console.log("pk:", p.pk);
console.log("surl:", decodeURIComponent(p.surl));

data (blob)

If the site uses an additional blob parameter, you can obtain it as follows:

The blob parameter can be located in:

  • HTML attributes: e.g., data-blob or other data-* attributes.
  • JSON API response: returned after a user action (e.g., click or captcha request).
  • Query parameter in URL within JSON: sometimes blob is passed as part of the URL.
Important: Do not load the captcha iframe to extract blob. Once the captcha is loaded, the parameter becomes invalid.

You can also find the blob parameter using network requests in DevTools:

  1. Go to the page with the captcha, open DevTools, and trigger the captcha to appear. Then open the Network tab and find a request like:
    https://arkoselabs.example.com/fc/gt2/public_key/176068BF-9607-4799-B53D-366BE98E2B84
  1. Block the loading of the captcha iframe to obtain a valid blob. To do this, press Ctrl + Shift + P, type Enable network request blocking, enable request blocking, and add a pattern such as: /fc/gt2
    After reloading the page, the frame will be blocked. Copy the value of the blob parameter.

Code Examples

Node.js - Automatic FunCaptcha Solving with blob
const { chromium } = require("playwright");

const apiKey = "max1_YOUR_API_KEY";
const websiteURL = "https://www.example.com/";

async function captureBlobAndPublicKey(page) {
    return new Promise(resolve => {
        page.on("request", req => {
            const url = req.url();

            if (url.includes("/fc/gt2/public_key/")) {
                const publicKey = url.split("/fc/gt2/public_key/")[1].split("/")[0];
                const post = req.postData();

                if (post && post.includes("data[blob]")) {
                    const params = new URLSearchParams(post);
                    const blob = params.get("data[blob]");

                    console.log("Extracted blob:", blob);
                    console.log("Extracted public_key:", publicKey);

                    resolve({ blob, publicKey });
                }
            }
        });
    });
}

async function createTask(blob, publicKey) {
    const task = {
        type: "FunCaptchaTask",
        websiteURL,
        websitePublicKey: publicKey,
        data: JSON.stringify({ blob }),
        userAgent: "userAgentPlaceholder"
    };

    const res = await fetch("https://captcha69.com/createTask", {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({ clientKey: apiKey, task })
    });

    const json = await res.json();

    if (!json.taskId) {
        console.error("createTask error:", json);
        process.exit(1);
    }

    console.log("Task created:", json.taskId);
    return json.taskId;
}

async function getTaskResult(taskId) {
    while (true) {
        const res = await fetch("https://captcha69.com/getTaskResult", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ clientKey: apiKey, taskId })
        });

        const json = await res.json();

        if (json.status === "ready") return json.solution;

        console.log("Processing...");
        await new Promise(r => setTimeout(r, 2500));
    }
}

(async () => {
    const browser = await chromium.launch({ headless: false });
    const page = await browser.newPage();

    await page.route("**/fc/gt2/**", route => route.abort());

    console.log("Opening page...");
    await page.goto(websiteURL, { waitUntil: "domcontentloaded" });

    console.log("Capturing public_key + blob...");
    // IMPORTANT: You need to trigger the captcha here
    // e.g., await page.click('text="Create account"');

    const { blob, publicKey } = await captureBlobAndPublicKey(page);

    if (!blob || !publicKey) {
        console.error("Failed to extract blob or public_key");
        await browser.close();
        return;
    }

    console.log("Creating task...");
    const taskId = await createTask(blob, publicKey);

    console.log("Waiting for solution...");
    const solution = await getTaskResult(taskId);

    console.log("CAPTCHA SOLVED");
    console.log("Token:", solution.token);

    await browser.close();
})();
Python - Automatic FunCaptcha Solving with blob
import asyncio
import json
import time
import requests
from playwright.async_api import async_playwright

API_KEY = "max1_YOUR_API_KEY"
WEBSITE_URL = "https://www.example.com/"

async def capture_blob_and_public_key(page):
    future = asyncio.Future()

    async def on_request(request):
        url = request.url

        if "/fc/gt2/public_key/" in url:
            public_key = url.split("/fc/gt2/public_key/")[1].split("/")[0]
            post_data = request.post_data

            if post_data and "data[blob]" in post_data:
                params = dict(x.split("=") for x in post_data.split("&"))
                blob = params.get("data[blob]")

                print("Extracted blob:", blob)
                print("Extracted public_key:", public_key)

                future.set_result((blob, public_key))

    page.on("request", on_request)
    return await future

def create_task(blob, public_key):
    task = {
        "type": "FunCaptchaTask",
        "websiteURL": WEBSITE_URL,
        "websitePublicKey": public_key,
        "data": json.dumps({"blob": blob}),
        "userAgent": "userAgentPlaceholder"
    }

    res = requests.post(
        "https://captcha69.com/createTask",
        json={"clientKey": API_KEY, "task": task},
        headers={"Content-Type": "application/json"}
    )

    data = res.json()

    if "taskId" not in data:
        raise Exception(f"createTask error: {data}")

    print("Task created:", data["taskId"])
    return data["taskId"]

def get_task_result(task_id):
    while True:
        res = requests.post(
            "https://captcha69.com/getTaskResult",
            json={"clientKey": API_KEY, "taskId": task_id},
            headers={"Content-Type": "application/json"}
        )

        data = res.json()

        if data.get("status") == "ready":
            return data["solution"]

        print("Processing...")
        time.sleep(2.5)

async def main():
    async with async_playwright() as p:
        browser = await p.chromium.launch(headless=False)
        page = await browser.new_page()

        await page.route("**/fc/gt2/**", lambda route: route.abort())

        print("Opening page...")
        await page.goto(WEBSITE_URL, wait_until="domcontentloaded")

        print("Capturing public_key + blob...")
        # IMPORTANT: You need to trigger the captcha here

        blob, public_key = await capture_blob_and_public_key(page)

        if not blob or not public_key:
            print("Failed to extract blob or public_key")
            await browser.close()
            return

        print("Creating task...")
        task_id = create_task(blob, public_key)

        print("Waiting for solution...")
        solution = get_task_result(task_id)

        print("CAPTCHA SOLVED")
        print("Token:", solution["token"])

        await browser.close()

asyncio.run(main())