What is Littencaptcha?

Littencaptcha is a cloud-based CAPTCHA solving API. Submit any supported CAPTCHA challenge via a simple HTTP request and receive a valid token within seconds — charged only on success.

Drop-in compatible with existing integrations. If you already use a popular CAPTCHA solving service, you can switch to Littencaptcha by simply changing the base URL — the same endpoints and response format are fully supported.

Key features

FeatureDetails
Pay per successYou are only charged when a CAPTCHA is solved successfully. Failed tasks cost nothing.
No subscriptionTop up your balance and use it at your own pace. No monthly fees or commitments.
Low latencyAverage solve time under 5 seconds for all supported types.
API compatibleUses the same request format as other popular CAPTCHA solving services — no extra migration work required.
Free creditNew accounts receive $0.025 in free credit on registration. No card required.

Pricing

Captcha typePrice per solveStatus
Cloudflare Turnstile$0.001● Live
Altcha$0.0006● Live
FriendlyCaptcha$0.0012● Live
FaucetPay Captcha$0.0008● Live

Getting Started

Littencaptcha works through a simple two-step API: submit a CAPTCHA task, then retrieve the result. You can be up and running in under 5 minutes.

Fast integration
Works with any HTTP library — Python, JS, PHP, Go, cURL.
💳
No subscription
Pay only for successful solves. Free $0.025 on signup.
🔗
API compatible
Existing integrations work by swapping the base URL — no other changes needed.

Setup — 3 steps

1

Create a free account

Register at littencaptcha.com/register. Your account is activated instantly and credited with $0.025 — no credit card required. That's enough to test roughly 25 Turnstile solves.

2

Copy your API key

Go to your Dashboard. The API Key section shows your key. Copy it — you will pass it as clientKey in every API request. Treat it like a password; do not commit it to source control.

3

Submit and retrieve

Call POST /createTask to queue a solve. You get a taskId back immediately. Poll POST /getTaskResult with that ID every 2 seconds until "status": "ready".

How the API works

📤
Step 1
Submit task
POST /createTask
with your API key & CAPTCHA params
⚙️
Step 2
We solve it
Typically 1–8 s
depending on captcha type
Step 3
Get result
Poll /getTaskResult
every 2 s until status = ready

Code examples

The following examples solve a Cloudflare Turnstile. Swap out the task object for other CAPTCHA types — see Captcha Types.

# pip install requests
import requests, time

API_KEY = "YOUR_API_KEY"
BASE    = "https://api.littencaptcha.com"

# Step 1 — create task
resp = requests.post(BASE + "/createTask", json={
    "clientKey": API_KEY,
    "task": {
        "type":       "TurnstileTask",
        "websiteURL": "https://example.com/page",
        "websiteKey": "0x4AAAAAAABkMYinukE8nzYD",
    }
}).json()

if resp.get("errorId"):
    raise RuntimeError(resp["errorCode"])

task_id = resp["taskId"]

# Step 2 — poll until ready
for _ in range(30):
    time.sleep(2)
    r = requests.post(BASE + "/getTaskResult", json={
        "clientKey": API_KEY,
        "taskId":    task_id,
    }).json()
    if r["status"] == "ready":
        token = r["solution"]["token"]
        print("Token:", token)
        break
else:
    raise TimeoutError("Task did not finish in 60 s")
// Node.js — using built-in fetch (Node 18+)
const API_KEY = 'YOUR_API_KEY';
const BASE    = 'https://api.littencaptcha.com';

async function solveTurnstile(url, sitekey) {
  // Step 1 — create task
  const { taskId, errorCode } = await fetch(BASE + '/createTask', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ clientKey: API_KEY, task: { type: 'TurnstileTask', websiteURL: url, websiteKey: sitekey } })
  }).then(r => r.json());

  if (errorCode) throw new Error(errorCode);

  // Step 2 — poll until ready
  for (let i = 0; i < 30; i++) {
    await new Promise(r => setTimeout(r, 2000));
    const res = await fetch(BASE + '/getTaskResult', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ clientKey: API_KEY, taskId })
    }).then(r => r.json());
    if (res.status === 'ready') return res.solution.token;
  }
  throw new Error('Timed out');
}

solveTurnstile('https://example.com/page', '0x4AAAAAAABkMYinukE8nzYD')
  .then(token => console.log('Token:', token))
  .catch(console.error);
# Step 1 — create task (save taskId from output)
curl -sX POST https://api.littencaptcha.com/createTask \
  -H 'Content-Type: application/json' \
  -d '{"clientKey":"YOUR_API_KEY","task":{"type":"TurnstileTask","websiteURL":"https://example.com","websiteKey":"0x4AAAAAAABkMYinukE8nzYD"}}'

# {"errorId":0,"taskId":48291}

# Step 2 — poll for result (replace 48291 with your taskId)
curl -sX POST https://api.littencaptcha.com/getTaskResult \
  -H 'Content-Type: application/json' \
  -d '{"clientKey":"YOUR_API_KEY","taskId":48291}'

# {"errorId":0,"status":"ready","solution":{"token":"0.vQz4Fg9bXk4r5RVkM..."}}

Best practices

Poll every 2 seconds — polling more frequently wastes requests without speeding up the result.
Set a maximum retry count (e.g. 30 attempts × 2 s = 60 s timeout) and raise an error if the task never completes.
Check "errorId" on every response — a value of 1 means something went wrong; read errorCode for details.
Store your API key in an environment variable or secrets manager — never hard-code it in committed source files.
On ERROR_CAPTCHA_UNSOLVABLE simply retry createTask — you are not charged for failed tasks.
createTask : Creating a task
Description
The method creates a task for solving the selected CAPTCHA type. Pass your API key, a typed task object with the CAPTCHA parameters, and receive a taskId immediately. The task is solved asynchronously — poll getTaskResult to retrieve the solution.
Method address
https://api.littencaptcha.com/createTask
Request format
POSTJSON

Request fields

FieldTypeDescription
clientKeystringrequiredYour API key from the Dashboard. Every request must include this.
taskobjectrequiredTask object containing at minimum a type field. Additional fields depend on the CAPTCHA type — see Cloudflare Turnstile or Altcha.

The task object

The task object structure varies per CAPTCHA type. The type field always selects which solver is used:

type valueCAPTCHAStatus
TurnstileTaskCloudflare Turnstile● Live
AltchaTaskAltcha● Live
FriendlyCaptchaTaskFriendlyCaptcha● Live
FaucetPayTaskFaucetPay Captcha● Live

Response — success

JSON
{
  "errorId": 0,
  "taskId":  48291
}

Response — error

JSON
{
  "errorId":          1,
  "errorCode":        "ERROR_KEY_DOES_NOT_EXIST",
  "errorDescription": "Invalid API key"
}

Request examples

{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type":       "TurnstileTask",
    "websiteURL": "https://example.com/protected",
    "websiteKey": "0x4AAAAAAABkMYinukE8nzYD"
  }
}
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type":      "AltchaTask",
    "challenge": "sha256-cc67f6d...",
    "salt":      "a1b2c3d4",
    "algorithm": "SHA-256",
    "maxNumber": 1000000
  }
}
getTaskResult : Getting task result
Description
The method retrieves the result of a task previously created with createTask. Call this endpoint repeatedly at a 2-second interval until status becomes "ready". The task is solved asynchronously — responses will return "processing" while the solver is working.
Method address
https://api.littencaptcha.com/getTaskResult
Request format
POSTJSON
Recommended polling interval: 2 seconds. Polling faster doesn't speed up the result and wastes requests. Set a maximum of 30 retries (60 s total) before treating the task as timed out.

Request fields

FieldTypeDescription
clientKeystringrequiredYour API key.
taskIdintegerrequiredThe taskId returned by createTask.

Possible response states

Still processing

The task has been received and is being worked on. Keep polling.

JSON
{
  "errorId": 0,
  "status":  "processing"
}

Ready — Turnstile token

Use solution.token as the value for cf-turnstile-response in your form or POST body.

JSON
{
  "errorId":  0,
  "status":   "ready",
  "solution": {
    "token": "0.vQz4Fg9bXk4r5RVkM...",
    "type":  "default"
  },
  "cost":     0.001,
  "solveMs": 3247
}

Ready — Altcha solution

Submit the entire solution object back to the Altcha widget or endpoint. Altcha encodes it as a base64 JSON payload.

JSON
{
  "errorId":  0,
  "status":   "ready",
  "solution": {
    "number":    48291,
    "algorithm": "SHA-256",
    "challenge": "sha256-cc67f6d...",
    "salt":      "a1b2c3d4e5f6",
    "signature": "hmac-sig..."
  },
  "cost":     0.0005,
  "solveMs": 412
}

Error

The task failed. errorId: 1 and errorCode explain the reason. On ERROR_CAPTCHA_UNSOLVABLE you are not charged — just retry.

JSON
{
  "errorId":          1,
  "errorCode":        "ERROR_CAPTCHA_UNSOLVABLE",
  "errorDescription": "Could not solve the CAPTCHA"
}

Polling pattern

def wait_for_result(session, base, key, task_id, timeout=60):
    for _ in range(timeout // 2):
        time.sleep(2)
        r = session.post(base + "/getTaskResult", json={
            "clientKey": key, "taskId": task_id
        }).json()
        if r.get("errorId"):
            raise RuntimeError(r.get("errorCode"))
        if r["status"] == "ready":
            return r["solution"]
    raise TimeoutError(f"Task {task_id} not done in {timeout}s")
async function waitForResult(apiKey, taskId, timeoutMs = 60000) {
  const deadline = Date.now() + timeoutMs;
  while (Date.now() < deadline) {
    await new Promise(r => setTimeout(r, 2000));
    const r = await fetch('/getTaskResult', {
      method: 'POST', headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({ clientKey: apiKey, taskId })
    }).then(x => x.json());
    if (r.errorId) throw new Error(r.errorCode);
    if (r.status === 'ready') return r.solution;
  }
  throw new Error(`Task ${taskId} timed out`);
}
getBalance : Getting account balance
Description
The method returns the current USD balance of your account. Use it to verify that your API key is active and to check available credit before running high-volume batch tasks.
Method address
https://api.littencaptcha.com/getBalance
Request format
POSTJSON

Request

FieldTypeDescription
clientKeystringrequiredYour API key.
JSON
{ "clientKey": "YOUR_API_KEY" }

Response

JSON
{
  "errorId": 0,
  "balance": 0.4200  // USD, 4 decimal places
}
💡
Tip: Call getBalance at the start of a batch run to check you have enough credit before queuing thousands of tasks. Each Turnstile solve costs $0.001, Altcha $0.0006, FriendlyCaptcha $0.0012, FaucetPay $0.0008.

Quick check example

Python
r = requests.post("https://api.littencaptcha.com/getBalance",
                  json={"clientKey": API_KEY}).json()
balance = r["balance"]
print(f"Balance: ${balance:.4f}")
if balance < 0.025:
    print("⚠ Low balance — top up before running batch")
getUserAgent : Getting the solver's User-Agent
Description
The method returns the exact User-Agent string used by Littencaptcha's internal browser when solving CAPTCHAs. Use this value to set the User-Agent header in your own HTTP requests, so the browser fingerprint matches the token that was generated — improving submission success rates on sites that validate it.
Method address
https://api.littencaptcha.com/getUserAgent
Request format
POSTJSON

Request fields

FieldTypeDescription
clientKeystringrequiredYour API key. The endpoint validates the key before returning the user agent.
JSON — request body
{ "clientKey": "YOUR_API_KEY" }

Response

JSON — response
{
  "errorId":   0,
  "userAgent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36"
}
The user agent may change when the internal browser is updated. Always call getUserAgent at the start of each session rather than hard-coding the value, so your requests stay in sync.

Why it matters

When Littencaptcha solves a Turnstile challenge, the token is cryptographically bound to the browser session that generated it — including its User-Agent. If you then submit that token using a different User-Agent string, some sites will reject the token as mismatched.

By fetching the solver's exact User-Agent and applying it to your outgoing requests, you ensure the fingerprint is consistent end-to-end, maximising the acceptance rate of submitted tokens.

🔒
Fingerprint consistency
Match the solver's browser so sites can't distinguish the token from a real human solve.
📈
Higher acceptance rate
Mismatched User-Agents are a common cause of token rejection — this call eliminates that risk.
🔄
Always up-to-date
Call it fresh each session instead of hard-coding, so browser updates are picked up automatically.

Usage example

import requests, time

API_KEY = "YOUR_API_KEY"
BASE    = "https://api.littencaptcha.com"

# 1 — fetch the solver's user agent once per session
ua_resp = requests.post(BASE + "/getUserAgent", json={"clientKey": API_KEY}).json()
solver_ua = ua_resp["userAgent"]

# 2 — solve the CAPTCHA
task_id = requests.post(BASE + "/createTask", json={
    "clientKey": API_KEY,
    "task": {
        "type":       "TurnstileTask",
        "websiteURL": "https://example.com/login",
        "websiteKey": "0x4AAAAAAABkMYinukE8nzYD",
    }
}).json()["taskId"]

for _ in range(30):
    time.sleep(2)
    r = requests.post(BASE + "/getTaskResult",
                      json={"clientKey": API_KEY, "taskId": task_id}).json()
    if r["status"] == "ready":
        token = r["solution"]["token"]
        break

# 3 — submit using the SAME user agent the solver used
session = requests.Session()
session.headers["User-Agent"] = solver_ua

session.post("https://example.com/login", data={
    "username":              "alice",
    "password":              "secret",
    "cf-turnstile-response": token,
})
const API_KEY = 'YOUR_API_KEY';
const BASE    = 'https://api.littencaptcha.com';

// 1 — fetch solver's user agent
const { userAgent } = await fetch(BASE + '/getUserAgent', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ clientKey: API_KEY }),
}).then(r => r.json());

// 2 — solve Turnstile
const { taskId } = await fetch(BASE + '/createTask', {
  method: 'POST', headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({ clientKey: API_KEY, task: {
    type: 'TurnstileTask', websiteURL: 'https://example.com/login',
    websiteKey: '0x4AAAAAAABkMYinukE8nzYD'
  }}),
}).then(r => r.json());

// ... poll getTaskResult for the token ...

// 3 — submit with matching user agent
await fetch('https://example.com/api/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json', 'User-Agent': userAgent },
  body: JSON.stringify({ username: 'alice', password: 'secret', 'cf-turnstile-response': token }),
});
Compatible API : Drop-in endpoint layer
Description
Littencaptcha exposes a widely-used CAPTCHA service endpoint format via /in.php and /res.php. If your existing integration already uses this format, switch to Littencaptcha by changing the base URL — no other code changes required.
Base URL
https://littencaptcha.com
Endpoints
/in.php/res.php

POST /in.php — Submit task

POST/in.php

Accepts both application/x-www-form-urlencoded and JSON. Returns OK|task_id on success, or ERROR|code on failure.

FieldTypeDescription
keystringrequiredYour API key.
methodstringrequiredturnstile or altcha
pageurlstringrequiredPage URL (for Turnstile).
sitekeystringrequiredSite key (for Turnstile).
cURL
curl -sX POST https://api.littencaptcha.com/in.php \
  -d "key=YOUR_API_KEY&method=turnstile&pageurl=https://example.com&sitekey=0x4AAA…"
# Returns: OK|48291

GET /res.php — Get result

GET/res.php?action=get&key=API_KEY&id=TASK_ID

Returns CAPCHA_NOT_READY while solving, OK|token on success, or ERROR|code on failure. Use action=getbalance to check balance.

cURL
curl "https://api.littencaptcha.com/res.php?action=get&key=YOUR_API_KEY&id=48291"
# Returns: OK|0.vQz4Fg9bXk4r5RVkM...

Cloudflare Turnstile

Task type: TurnstileTask
● Live

Cloudflare Turnstile is a browser-side CAPTCHA alternative. Littencaptcha solves it by simulating a real browser visit to the target page. You provide the page URL and the widget's sitekey — a valid token is returned within a few seconds.

Cloudflare Turnstile $1.00 / 1,000 tokens 99% success
Widget appearance
Verify you are human
CLOUDFLARE Privacy · Terms
Initial state
Verifying…
CLOUDFLARE Privacy · Terms
Verifying
Success!
CLOUDFLARE Privacy · Terms
Solved ✓

How to find the sitekey

Every Turnstile widget has a unique sitekey. You need to extract it from the target page before submitting a task.

A

Look in the HTML source

Right-click the page → View Page Source (or press Ctrl+U). Search for cf-turnstile. The data-sitekey attribute on that element is what you need.

B

Or check the network tab

Open DevTools → Network → filter by challenges.cloudflare.com. The request URL contains the sitekey as a query parameter.

HTML — example widget markup
<!-- The value of data-sitekey is what you pass as websiteKey -->
<div class="cf-turnstile"
     data-sitekey="0x4AAAAAAABkMYinukE8nzYD"
     data-action="login"></div>

Task parameters

FieldTypeDescription
typestringrequiredMust be "TurnstileTask"
websiteURLstringrequiredFull URL of the page where the Turnstile widget is embedded (e.g. https://example.com/login). Must match the URL Cloudflare expects.
websiteKeystringrequiredThe Turnstile sitekey — the data-sitekey value from the widget's HTML element.
proxystringoptionalProxy to route the browser through: http://user:pass@host:port. Leave empty in the vast majority of cases — only needed when the target site restricts access by IP region.

Request example

JSON — createTask body
{
  "clientKey": "YOUR_API_KEY",
  "task": {
    "type":       "TurnstileTask",
    "websiteURL": "https://example.com/login",
    "websiteKey": "0x4AAAAAAABkMYinukE8nzYD"
  }
}

Using the token

Once the task is "ready", read solution.token from the result. Submit it as the cf-turnstile-response field in your form or POST body — the same field the widget would normally fill in automatically.

# Python — inject token into a form POST
token = solution["token"]
resp = session.post("https://example.com/login", data={
    "username":              "alice",
    "password":              "secret",
    "cf-turnstile-response": token,
})
// JavaScript — inject token into a JSON API call
const token = solution.token;
const res = await fetch('https://example.com/api/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: 'alice', password: 'secret',
    'cf-turnstile-response': token,
  }),
});
Tokens expire quickly — typically within 5 minutes. Submit the token to the target site immediately after receiving it. If the site rejects the token, the task may have expired — just create a new task.

Altcha

Task type: AltchaTask
● Live

Altcha is a privacy-respecting CAPTCHA alternative that works entirely through server-side Proof-of-Work computation — no images, no cookies, no tracking. Littencaptcha solves Altcha challenges almost instantly (typically under 1 second).

Altcha $0.60 / 1,000 tokens 100% success
Widget appearance
Verifying, please wait…
Computing PoW
Verified
Solved ✓

How Altcha works

📋
1. Fetch challenge
GET challengeurl
Site returns JSON with challenge, salt, signature
⚙️
2. We solve PoW
Send to Littencaptcha
We find the nonce that satisfies the hash condition
3. Submit solution
Base64-encoded JSON
Send the solution payload in the form field

How to get challenge parameters

1

Find the widget

Inspect the page HTML and look for an <altcha-widget> element. Note its challengeurl attribute.

2

Fetch the challenge JSON

Make a GET request to that challengeurl. The response is a JSON object containing challenge, salt, algorithm, maxnumber, and signature.

3

Pass all fields to AltchaTask

Include all values from the challenge response in your AltchaTask object. The more fields you include, the higher the verification success rate.

HTML — example Altcha widget
<altcha-widget
  challengeurl="https://example.com/api/altcha-challenge"
  name="altcha"></altcha-widget>
Python — full Altcha flow
import requests, time, json, base64

API_KEY = "YOUR_API_KEY"
BASE    = "https://api.littencaptcha.com"

# Step 1 — fetch challenge from target site
chall = requests.get("https://example.com/api/altcha-challenge").json()

# Step 2 — create AltchaTask
task_id = requests.post(BASE + "/createTask", json={
    "clientKey": API_KEY,
    "task": {
        "type":      "AltchaTask",
        "challenge": chall["challenge"],
        "salt":      chall["salt"],
        "algorithm": chall.get("algorithm", "SHA-256"),
        "maxNumber": chall.get("maxnumber", 1000000),
        "signature": chall.get("signature", ""),
    }
}).json()["taskId"]

# Step 3 — poll for result
for _ in range(30):
    time.sleep(2)
    r = requests.post(BASE + "/getTaskResult",
                      json={"clientKey": API_KEY, "taskId": task_id}).json()
    if r["status"] == "ready":
        sol = r["solution"]
        # Altcha expects a base64-encoded JSON payload
        payload = base64.b64encode(json.dumps(sol).encode()).decode()
        break

# Step 4 — submit payload in the form
requests.post("https://example.com/submit", data={
    "altcha": payload,
    "email":  "[email protected]",
})

Task parameters

FieldTypeDescription
typestringrequiredMust be "AltchaTask"
challengestringrequiredThe challenge hash from the site's challenge endpoint (usually starts with sha256-).
saltstringrequiredSalt string from the challenge endpoint. Used to compute the correct hash.
algorithmstringoptionalHash algorithm to use. Default: "SHA-256". Match the value from the challenge response.
maxNumberintegeroptionalUpper bound for nonce search. Default: 1000000. Pass the challenge response's maxnumber if present.
signaturestringoptionalHMAC signature from the challenge endpoint. Pass it back in the solution for server-side verification.

Friendly Captcha

Task type: FriendlyCaptchaTask
● Live

Friendly Captcha is a privacy-first CAPTCHA alternative that uses proof-of-work puzzles solved in the browser — no cookies, no tracking, no third-party requests. Littencaptcha handles the puzzle computation on your behalf and returns a valid solution token.

Friendly Captcha $1.20 / 1,000 tokens 99% success
Widget appearance
I am human ···
Initial state
Solving puzzle… ···
Verifying
I am human ···
Solved ✓

How to find the sitekey

Each Friendly Captcha widget has a sitekey identifying your account. You need to extract it from the target page before submitting a task.

A

Look in the HTML source

Right-click the page → View Page Source. Search for frc-captcha or friendly-challenge. The data-sitekey attribute is your sitekey.

B

Or inspect the widget element

Open DevTools → Elements, click the CAPTCHA widget. Look for the data-sitekey attribute on the <div class="frc-captcha"> element.

HTML — example widget markup
<!-- data-sitekey is what you pass as websiteKey -->
<div class="frc-captcha"
     data-sitekey="FCMTST000000000000000000"
     data-puzzle-endpoint="https://api.friendlycaptcha.com/api/v1/puzzle"></div>

Task parameters

FieldTypeDescription
typestringrequiredFriendlyCaptchaTask
websiteURLstringrequiredFull URL of the page containing the widget.
websiteKeystringrequiredThe data-sitekey value from the widget element.
puzzleEndpointstringoptionalCustom puzzle endpoint URL. Defaults to https://api.friendlycaptcha.com/api/v1/puzzle.

Request example

import requests, time

API_KEY = "YOUR_API_KEY"
BASE    = "https://api.littencaptcha.com"

# Step 1 — create task
resp = requests.post(BASE + "/createTask", json={
    "clientKey": API_KEY,
    "task": {
        "type":       "FriendlyCaptchaTask",
        "websiteURL": "https://example.com/login",
        "websiteKey": "FCMTST000000000000000000",
    }
})
task_id = resp.json()["taskId"]

# Step 2 — poll for result
while True:
    time.sleep(3)
    result = requests.post(BASE + "/getTaskResult", json={
        "clientKey": API_KEY, "taskId": task_id
    }).json()
    if result["status"] == "ready":
        token = result["solution"]["token"]
        break
const resp = await fetch('https://api.littencaptcha.com/createTask', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    clientKey: 'YOUR_API_KEY',
    task: {
      type:       'FriendlyCaptchaTask',
      websiteURL: 'https://example.com/login',
      websiteKey: 'FCMTST000000000000000000',
    }
  })
});
const { taskId } = await resp.json();
curl -sX POST https://api.littencaptcha.com/createTask \
  -H 'Content-Type: application/json' \
  -d '{"clientKey":"YOUR_API_KEY","task":{"type":"FriendlyCaptchaTask","websiteURL":"https://example.com/login","websiteKey":"FCMTST000000000000000000"}}'

Using the token

Submit the returned token in the form field named frc-captcha-solution (v1) or frc-captcha-response (v2). The server validates it against the Friendly Captcha API.

# Python — inject token into a form POST
resp = session.post("https://example.com/login", data={
    "username":              "alice",
    "password":              "secret",
    "frc-captcha-solution":  token,
})
// JavaScript — inject token into a JSON API call
const res = await fetch('https://example.com/api/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: 'alice', password: 'secret',
    'frc-captcha-solution': token,
  }),
});
Tokens expire quickly — submit the solution to the target site immediately after receiving it. If rejected, the puzzle may have expired — create a new task.

FaucetPay Captcha

Task type: FaucetPayTask
● Live

FaucetPay Captcha is a visual challenge used by crypto faucet and claim sites. Littencaptcha solves it server-side — no browser, no proxy, no manual interaction required. You provide the page URL and sitekey and receive a valid token within seconds.

FaucetPay Captcha $0.80 / 1,000 solves 99% success
Challenge types
FaucetPay initial state Initial state (checkbox)
FaucetPay slider puzzle Slider puzzle (drag to fit)
FaucetPay icon selection Icon selection (tap in order)

How to find the sitekey

Open the target faucet page, open DevTools (F12) → Network tab, then trigger the captcha widget. Look for a request to faucetpay.io — the sitekey parameter in the URL or request body is your website key.

A

View Page Source

Right-click → View Page Source. Search for faucetpay or sitekey. The value next to it is your key.

B

Inspect the widget element

Open DevTools → Elements, click the captcha widget. Look for a data-sitekey or sitekey attribute on the widget's container element.

Task parameters

FieldTypeDescription
typestringrequiredFaucetPayTask
websiteURLstringrequiredFull URL of the page containing the captcha widget.
websiteKeystringrequiredThe FaucetPay sitekey from the target page.
cookiesbooleanoptionalSet true to return response cookies alongside the token.

Request example

import requests, time

API_KEY = "YOUR_API_KEY"
BASE    = "https://api.littencaptcha.com"

# Step 1 — create task
resp = requests.post(BASE + "/createTask", json={
    "clientKey": API_KEY,
    "task": {
        "type":       "FaucetPayTask",
        "websiteURL": "https://example-faucet.com/claim",
        "websiteKey": "YOUR_SITE_KEY",
    }
})
task_id = resp.json()["taskId"]

# Step 2 — poll for result
while True:
    time.sleep(3)
    result = requests.post(BASE + "/getTaskResult", json={
        "clientKey": API_KEY, "taskId": task_id
    }).json()
    if result["status"] == "ready":
        token = result["solution"]["token"]
        break
const resp = await fetch('https://api.littencaptcha.com/createTask', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    clientKey: 'YOUR_API_KEY',
    task: {
      type:       'FaucetPayTask',
      websiteURL: 'https://example-faucet.com/claim',
      websiteKey: 'YOUR_SITE_KEY',
    }
  })
});
const { taskId } = await resp.json();

// Poll every 3 seconds
let token;
while (!token) {
  await new Promise(r => setTimeout(r, 3000));
  const res = await fetch('https://api.littencaptcha.com/getTaskResult', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({ clientKey: 'YOUR_API_KEY', taskId })
  }).then(r => r.json());
  if (res.status === 'ready') token = res.solution.token;
}
curl -sX POST https://api.littencaptcha.com/createTask \
  -H 'Content-Type: application/json' \
  -d '{"clientKey":"YOUR_API_KEY","task":{"type":"FaucetPayTask","websiteURL":"https://example-faucet.com/claim","websiteKey":"YOUR_SITE_KEY"}}'

Using the token

Submit the returned token in the form field the faucet site expects — typically named faucetpay_response or similar. Inspect the site's form HTML to confirm the exact field name.

{
  "errorId": 0,
  "status":  "ready",
  "solution": {
    "token": "FP_TOKEN_STRING_HERE"
  },
  "cost":    0.0006,
  "solveMs": 4200
}
# Python — inject token into the faucet claim form
resp = session.post("https://example-faucet.com/claim", data={
    "address":           "your_wallet_address",
    "faucetpay_response": token,
})
Tokens expire quickly — submit to the target site immediately after receiving. If the site rejects it, create a new task.

reCAPTCHA v2

🚧
Coming soon. Support for Google reCAPTCHA v2 (checkbox and invisible) is currently in development. Create an account to be notified when it launches.

Once available, the task type will be RecaptchaV2Task with a price of $0.001 per solve.

hCaptcha

🚧
Coming soon. hCaptcha support is planned for a future release. Create an account to be notified when it launches.

Once available, the task type will be HCaptchaTask with a price of $0.001 per solve.

Error Codes

When a request encounters a problem, the API responds with "errorId": 1 plus a machine-readable errorCode string and a human-readable errorDescription. Always check errorId first in your code.

JSON — error response shape
{
  "errorId":          1,
  "errorCode":        "ERROR_KEY_DOES_NOT_EXIST",
  "errorDescription": "Invalid API key"
}
Successful responses always have "errorId": 0 — you can use this as a quick success check before reading any other field.

Error reference

Error codeHTTPMeaning & fix
ERROR_KEY_DOES_NOT_EXIST401 The clientKey is missing, misspelled, or has been revoked. Fix: copy your key from the Dashboard and ensure you are not accidentally adding whitespace or using an old key.
ERROR_ZERO_BALANCE402 Your account has insufficient balance to queue this task. Fix: top up your balance in the Dashboard. Call getBalance first when running in batch to avoid this mid-run.
ERROR_TASK_NOT_SUPPORTED400 The type value in your task object is not recognised. Fix: check the spelling against the supported types (TurnstileTask, AltchaTask). This also occurs for types that are coming soon.
ERROR_TASK_ABSENT404 No task was found matching the given taskId for your API key. Fix: verify the taskId was returned by a createTask call made with the same API key.
ERROR_CAPTCHA_UNSOLVABLE200 The solver was unable to complete this challenge. You are not charged. Fix: simply retry — most challenges succeed on a second or third attempt. If failures persist, double-check that websiteURL and websiteKey are correct.

Error handling example

Python
def create_task(session, base, key, task):
    r = session.post(base + "/createTask", json={
        "clientKey": key, "task": task
    }).json()

    if r.get("errorId"):
        code = r.get("errorCode", "UNKNOWN")
        if code == "ERROR_ZERO_BALANCE":
            raise RuntimeError("Top up your balance before continuing")
        if code == "ERROR_KEY_DOES_NOT_EXIST":
            raise ValueError("Check your API key in the Dashboard")
        raise RuntimeError(code)

    return r["taskId"]

FAQ

Common questions about Littencaptcha.

Can I switch from another CAPTCHA service without rewriting my code? +

Yes. Littencaptcha implements both the native API and a compatible endpoint layer (/in.php and /res.php). Change your base URL to littencaptcha.com and you're done — no other code changes needed.

How do I top up my balance? +

Go to your Dashboard → Billing. We accept major credit and debit cards. The minimum top-up is $1.00. New accounts get $0.10 free credit on registration.

What happens if a CAPTCHA is not solved? +

Failed tasks return ERROR_CAPTCHA_UNSOLVABLE and your balance is not charged. You pay only for successful solves. Simply retry — in most cases a second attempt succeeds.

How long does it take to solve a CAPTCHA? +

Altcha tasks are solved in under 1 second (pure computation). Cloudflare Turnstile takes between 2 and 8 seconds depending on the target page. Recommended polling interval: 2 seconds.

Do I need a proxy to solve Turnstile? +

No. The proxy field in TurnstileTask is optional — omit it in the vast majority of cases. Use a proxy only if the target site has strict IP-based restrictions.

Where do I find the Turnstile sitekey? +

Open the target page, right-click → Inspect, and search for data-sitekey in the HTML. You can also look for it in the turnstile.js script initialization.

Is there a rate limit? +

There is no hard rate limit on concurrent tasks. For very high volumes (>50 concurrent tasks) please contact us so we can ensure optimal routing for your account.

What languages can I use? +

Any language that can make HTTP requests — Python, JavaScript/Node.js, PHP, Go, C#, Ruby, etc. Since we are 2Captcha-compatible, any existing 2Captcha SDK works by changing the base URL.

Updates

Release history and changelog for Littencaptcha.

Jul 2025
v1.1.0
2Captcha-Compatible Layer
NEW /in.php endpoint — submit tasks in 2Captcha format
NEW /res.php endpoint — retrieve results & balance
IMP Dashboard billing page with transaction history
Jul 2025
v1.0.0
Initial Release
NEW Cloudflare Turnstile solving (TurnstileTask)
NEW Altcha solving (AltchaTask)
NEW Native API: /createTask, /getTaskResult, /getBalance
NEW User dashboard with balance & API key management
NEW $0.10 free credit on registration
Soon
v1.2.0 — Planned
More CAPTCHA Types
NEW reCAPTCHA v2 support
NEW hCaptcha support
IMP Webhook notifications for completed tasks