API Documentation

Solve CAPTCHAs with two HTTP requests. Submit, poll, done.

API Live100 free solves per API keypip install gatesolve →

Quick Start

1

Join the waitlist

Sign up with your email at the waitlist. We're finishing up the solver backend — you'll get a key starting with gs_ and 1,000 free solves when we launch.

curl -X POST https://gatesolve.dev/api/waitlist \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com"}'

# Response: { "status": "waitlisted", "message": "You're on the list!" }
2

Submit a solve request

POST with your CAPTCHA details. Returns immediately with a solve ID.

3

Poll for the solution

GET the solve ID every 2-3 seconds. When status is solved, grab the token.

Auto-Detect CAPTCHA

NEW

Don't know the CAPTCHA type or sitekey? Auto-detect it from any URL. No manual HTML inspection needed.

GET /api/detect/sitekey?url=https://example.com/login

Returns the primary CAPTCHA type, siteKey, and confidence score. Pass results directly to /api/solve.

cURL — Detect + Solve
# Auto-detect CAPTCHA type and sitekey from any URL
curl "https://gatesolve.dev/api/detect/sitekey?url=https://example.com/login"

# Response:
# {
#   "primary": { "type": "recaptcha-v2", "siteKey": "6Le-wvkS...", "confidence": 0.95 },
#   "captchas": [...],
#   "pageTitle": "Login Page"
# }

# Then solve with the detected values:
curl -X POST https://gatesolve.dev/api/solve \
  -H "Authorization: Bearer gs_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "recaptcha-v2", "siteKey": "6Le-wvkS...", "pageUrl": "https://example.com/login" }'
Python SDK — Detect + Solve
from gatesolve import GateSolve
import requests

# Step 1: Auto-detect
detect = requests.get(
    "https://gatesolve.dev/api/detect/sitekey",
    params={"url": "https://example.com/login"}
).json()

if detect["primary"]:
    # Step 2: Solve with detected values
    client = GateSolve(api_key="gs_YOUR_API_KEY")
    token = client.solve(
        type=detect["primary"]["type"],
        site_key=detect["primary"]["siteKey"],
        page_url="https://example.com/login",
    )
    print(token)
MCP (Claude Code / Cursor)
# In Claude Code / Cursor, the MCP flow is:
# 1. Agent calls detect_sitekey tool with the URL
# 2. Gets back type + siteKey automatically
# 3. Calls solve_captcha with those values
# Zero manual inspection needed.

Base URL

https://gatesolve.dev/api

Also available at /api/v1 for versioned access.

Authentication

Pass your API key in the Authorization header:

Authorization: Bearer gs_YOUR_API_KEY
Free tier100 solves per API key, no credit card
MPP/TempoPay-per-solve via blockchain at /api/mpp/solve
x402 (soon)Native x402 micropayments coming next
POST

/api/solve

Submit a CAPTCHA to be solved. Returns a solve ID for polling.

Request Body

ParameterTypeRequiredDescription
typestringYesCAPTCHA type (see table below)
siteKeystringYesThe CAPTCHA site key from the target page
pageUrlstringYesURL of the page with the CAPTCHA

Response (202 Accepted)

{
  "id": "a1b2c3d4-e5f6-...",
  "status": "pending",
  "message": "Solve started. Poll for result.",
  "poll": "https://gatesolve.dev/api/solve?id=a1b2c3d4-e5f6-...",
  "estimated_time": "7-15 seconds"
}
GET

/api/solve?id={solve_id}

Poll for the result of a solve request. Call every 2-3 seconds.

200 — Solved
{
  "id": "a1b2c3d4-e5f6-...",
  "status": "solved",
  "token": "0.AbCdEfGhIjKlMnOpQrStUvWxYz...",
  "solvedIn": "9.2s",
  "type": "cloudflare-turnstile"
}
202 — Still processing
{
  "id": "a1b2c3d4-e5f6-...",
  "status": "pending",
  "message": "Solve in progress. Poll again in 2-3 seconds.",
  "poll": "https://gatesolve.dev/api/solve?id=a1b2c3d4-e5f6-..."
}
400/401/402 — Error
{
  "error": "invalid_captcha_type",
  "message": "Unsupported: 'foo'. Supported: cloudflare-turnstile, recaptcha-v2, recaptcha-v3, hcaptcha",
  "status": 400
}

Code Examples

Python SDKRecommended
# Install the Python SDK
pip install gatesolve

# Usage
from gatesolve import GateSolve

client = GateSolve(api_key="gs_YOUR_API_KEY")
token = client.solve(
    type="cloudflare-turnstile",
    site_key="0x4AAAAAAAB...",
    page_url="https://example.com",
)
print(token)  # Ready to use
cURL
# 1. Submit a solve request
curl -X POST https://gatesolve.dev/api/solve \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer gs_YOUR_API_KEY" \
  -d '{
    "type": "cloudflare-turnstile",
    "siteKey": "0x4AAAAAAAB...",
    "pageUrl": "https://example.com"
  }'

# Response: { "id": "abc-123", "status": "pending", "poll": "https://gatesolve.dev/api/solve?id=abc-123" }

# 2. Poll for result (every 2-3 seconds)
curl https://gatesolve.dev/api/solve?id=abc-123

# Response: { "id": "abc-123", "status": "solved", "token": "0.AbCdEf...", "solvedIn": "9.2s" }
Python (requests)
import requests
import time

API_KEY = "gs_YOUR_API_KEY"

# Submit solve request
resp = requests.post(
    "https://gatesolve.dev/api/solve",
    headers={
        "Content-Type": "application/json",
        "Authorization": f"Bearer {API_KEY}",
    },
    json={
        "type": "cloudflare-turnstile",
        "siteKey": "0x4AAAAAAAB...",
        "pageUrl": "https://example.com",
    },
)
solve_id = resp.json()["id"]

# Poll for result
while True:
    result = requests.get(f"https://gatesolve.dev/api/solve?id={solve_id}").json()
    if result["status"] == "solved":
        print(f"Token: {result['token']}")
        break
    time.sleep(3)
TypeScript
const API_KEY = "gs_YOUR_API_KEY";

// Submit solve request
const submit = await fetch("https://gatesolve.dev/api/solve", {
  method: "POST",
  headers: {
    "Content-Type": "application/json",
    Authorization: `Bearer ${API_KEY}`,
  },
  body: JSON.stringify({
    type: "cloudflare-turnstile",
    siteKey: "0x4AAAAAAAB...",
    pageUrl: "https://example.com",
  }),
});
const { id } = await submit.json();

// Poll for result
const poll = async (): Promise<string> => {
  const res = await fetch(`https://gatesolve.dev/api/solve?id=${id}`);
  const data = await res.json();
  if (data.status === "solved") return data.token;
  await new Promise((r) => setTimeout(r, 3000));
  return poll();
};
const token = await poll();

Supported CAPTCHA Types

NameType ValuePriceAvg TimeStatus
Cloudflare Turnstilecloudflare-turnstile$0.02~9sLive
reCAPTCHA v2recaptcha-v2$0.03~12sLive
reCAPTCHA v3recaptcha-v3$0.02~8sLive
hCaptchahcaptcha$0.03~10sLive

Error Codes

StatusErrorDescription
400missing_fieldsMissing type, siteKey, or pageUrl
400invalid_captcha_typeUnsupported CAPTCHA type
401invalid_api_keyAPI key not found or revoked
402free_tier_exceeded100 free solves used up. Use MPP for paid solves.
404not_foundSolve request ID not found

Webhook Callbacks

Instead of polling, provide a callbackUrl in your solve request. GateSolve will POST the result to your URL when the solve completes.

// Include callbackUrl in your solve request:
{
  "type": "cloudflare-turnstile",
  "siteKey": "0x4AAAA...",
  "pageUrl": "https://example.com",
  "callbackUrl": "https://your-server.com/webhook/captcha"
}

// GateSolve will POST to your callbackUrl when solved:
{
  "id": "a1b2c3d4-...",
  "status": "solved",
  "token": "0.AbCdEfGh...",
  "solvedIn": "9.2s",
  "type": "cloudflare-turnstile"
}

Optional: callbackUrl is not required. Polling still works as fallback.

Validation: Must be a valid http or https URL.

Timeout: Webhook POST has a 10-second timeout.

Rate Limits

Free tier: 2 concurrent solves, 100 total per key

MPP/Paid: 10 concurrent solves, unlimited total

Polling: We recommend polling every 2-3 seconds. No rate limit on GET polls.

Utility Endpoints

GET/api/health

Service health, solver status, and solve metrics

GET/api/v1/types

List all supported CAPTCHA types with pricing

GET/api/v1/usageAUTH

Check API key quota — used, remaining, limit, and global stats

POST/api/v1/solve/dry-runNO AUTH

Validate a solve request without consuming credits. Returns estimated time, cost, and warnings.

GET/api/detect?url=XNO AUTH

Classify URL access blocks (captcha, js-challenge, auth-wall, rate-limited, blocked-silent)

GET/openapi.json

OpenAPI 3.1 spec for programmatic API discovery

Start solving in 30 seconds

Get a free API key with 100 solves. No credit card required.