Skip to main content
Here is an example of how you can use our API to solve Cloudflare Turnstile in Python.
import requests

API_KEY = ""  # your solv.now api key
PROXY = ""  # url format. protocol://[user:pass@]host:port


def solve_turnstile(
    url: str,
    sitekey: str,
    proxy: str,
    action: str | None = None,
    cdata: str | None = None,
):
    """
    Solves a Turnstile captcha using solv.now API.

    Args:
        url (str): The URL of the page containing the Turnstile captcha.
        sitekey (str): The sitekey of the Turnstile captcha.
        proxy (str): The proxy to use for the request.
        action (str | None): The action parameter for the Turnstile captcha.
        cdata (str | None): The cdata parameter for the Turnstile captcha.

    Returns:
        str: The token returned by the Turnstile captcha.

    Raises:
        ValueError: If the sitekey is invalid.
    """
    if not sitekey.startswith("0x"):
        raise ValueError("Invalid sitekey")

    # An action cannot be empty, only null or alphanumeric.
    if action == "":
        action = None
    # Same logic goes for cdata.
    if cdata == "":
        cdata = None

    response = requests.post(
        "https://api.solv.now/v1/task/execute",
        headers={"X-Api-Key": API_KEY, "Content-Type": "application/json"},
        json={
            "task_type": "turnstile",
            "task_data": {
                "url": url,
                "sitekey": sitekey,
                "proxy": proxy,
                "action": action,
                "cdata": cdata,
            },
        },
    )

    data = response.json()
    if not data.get("success"):
        raise Exception(f"Error occurred while solving WAF: {data.get('message')}")
    return data["data"]["solution"]["token"]


def main():
    url = "https://turnstile-test.vercel.app/"
    sitekey = "0x4AAAAAAAA1WzHSsbGWTH88"

    token = solve_turnstile(url, sitekey, PROXY, action=None, cdata=None)

    # The website lets us check the token.
    check_response = requests.post(
        "https://turnstile-test.vercel.app/",
        data={"cf-turnstile-response": token, "name": "test", "type": "managed"},
    )

    assert check_response.status_code == 200
    print("Success:", check_response.json().get("success"))


if __name__ == "__main__":
    main()