How to bypass ALTCHA
Introduction
ALTCHA (Automated Logical Turing Test of Human Attention) is a modern captcha based on cryptographic Proof-of-Work (PoW) that does not require users to solve visual puzzles. Instead, the browser computes a special nonce value, confirming that the request was initiated by a real person.
In this guide, you will learn:
- How ALTCHA technology works
- Which parameters are required to solve it via API
- Step-by-step integration process with code examples
- How to handle errors and optimize requests
Important: Unlike traditional captchas, ALTCHA contains no images, text, or interactive elements — the entire verification is based on mathematical proof.
How ALTCHA Works
| Characteristic | Description |
|---|---|
| Verification Type | Proof-of-Work (cryptographic challenge) |
| Visual Elements | None |
| Mechanism | Server issues a challenge, client computes nonce |
| Validation | Server mathematically verifies the solution |
| Result | Token to be included in the target request |
Key Features:
-
Proof-of-Work Instead of Visual Tasks
The server sends the client a JSON with parameters: challenge, difficulty, salt, algorithm. The browser iterates through nonce values until the hash meets the difficulty condition. -
Stateless Verification
Validation occurs purely based on mathematics: the server can independently verify the provided nonce without sessions or cookies. -
Asynchronous Execution
Computations run in the background (via Web Worker), without blocking the user interface. -
Simple Integration
All logic is based on exchanging JSON data via standard HTTP requests.
Preparation: Required Parameters
To solve ALTCHA via the RuCaptcha API, you need to provide the following parameters:
Base Parameters (for both task types)
| Property | Type | Required | Description |
|---|---|---|---|
| type | String | Yes | Task type: AltchaTask (with proxy) or AltchaTaskProxyless (without proxy) |
| websiteURL | String | Yes | Full URL of the page where the captcha is loaded |
| challengeURL | String | Yes* | Value of the challenge_url attribute from the <altcha-widget> element |
| challengeJSON | String | Yes* | Direct content of the challenge file in JSON format |
* The request must include one of the parameters:
challengeURLorchallengeJSON.
Proxy Parameters (only for AltchaTask type)
| Property | Type | Required | Description |
|---|---|---|---|
| proxyType | String | Yes | Proxy type: http, https, socks5 |
| proxyAddress | String | Yes | IP address or hostname of the proxy server |
| proxyPort | Integer | Yes | Proxy server port |
| proxyLogin | String | No | Login for proxy authentication |
| proxyPassword | String | No | Password for proxy authentication |
For the AltchaTaskProxyless task type, no proxy is required.
Step-by-Step Guide: Solving ALTCHA via API
Step 1: Extract Challenge Data
- Open the target website in a browser with DevTools enabled (F12)
- Go to the Network tab → enable Preserve log
- Find the
<altcha-widget>element in the page source:
html
<altcha-widget
challenge_url="https://example.com/api/altcha/challenge?sitekey=abc123"
...>
</altcha-widget>
- Copy the value of the
challenge_urlattribute
Alternative: Manually request the challenge_url and copy the JSON response:
json
{
"algorithm": "SHA-256",
"challenge": "eab91764d3f9d0c0e8fd...",
"difficulty": 24,
"salt": "random_salt_value",
"max_number": 1000000
}
Step 2: Submit the Task for Solving
Task creation endpoint: https://api.2captcha.com/createTask
Example request with challengeURL (AltchaTaskProxyless):
json
{
"clientKey": "YOUR_API_KEY",
"task": {
"type": "AltchaTaskProxyless",
"websiteURL": "https://example.com/",
"challengeURL": "https://example.com/api/altcha/challenge?sitekey=abc123"
}
}
Example request with challengeJSON and proxy (AltchaTask):
json
{
"clientKey": "YOUR_API_KEY",
"task": {
"type": "AltchaTask",
"websiteURL": "https://example.com/",
"challengeJSON": "{\"algorithm\":\"SHA-256\",\"challenge\":\"eab91764...\",\"difficulty\":24}",
"proxyType": "http",
"proxyAddress": "192.168.1.1",
"proxyPort": 8080,
"proxyLogin": "login",
"proxyPassword": "password"
}
}
Step 3: Receive the Task ID
On success, you will receive:
json
{
"errorId": 0,
"taskId": "1234567890"
}
Save the taskId to poll for the result.
Step 4: Request the Result
Result retrieval endpoint:
https://api.2captcha.com/getTaskResult
Request:
json
{
"clientKey": "YOUR_API_KEY",
"taskId": "1234567890"
}
Successful response:
json
{
"errorId": 0,
"status": "ready",
"solution": {
"token": "eyJhbGdvcml0aG0iOiJTSEEtMjU2IiwiY2hhbGxlbmdlIjoiZWFiOTE3NjRkM2Y5ZDBjMGU4ZmR..."
},
"cost": "0.0012",
"createTime": 1754563182,
"endTime": 1754563190
}
Step 5: Use the Token
Include the received token in your target request to the website. It is typically sent in the request body or header:
javascript
// Example: adding token to POST request body
fetch("https://example.com/api/protected-endpoint", {
method: "POST",
headers: {
"Content-Type": "application/json"
},
body: JSON.stringify({
altcha_token: "eyJhbGdvcml0aG0iOiJTSEEtMjU2IiwiY2hhbGxlbmdlIjoiZWFiOTE3NjRkM2Y5ZDBjMGU4ZmR...",
// other form data
})
});
The token is valid for a limited time (usually 2-5 minutes) — use it immediately after receiving!
Code Examples
Python (requests)
python
import requests
import time
API_KEY = "YOUR_API_KEY"
CREATE_TASK_URL = "https://api.2captcha.com/createTask"
GET_RESULT_URL = "https://api.2captcha.com/getTaskResult"
def solve_altcha(website_url: str, challenge_url: str = None, challenge_json: str = None, use_proxy: bool = False):
if not challenge_url and not challenge_json:
raise ValueError("Specify challengeURL or challengeJSON")
task = {
"clientKey": API_KEY,
"task": {
"type": "AltchaTaskProxyless" if not use_proxy else "AltchaTask",
"websiteURL": website_url
}
}
if challenge_url:
task["task"]["challengeURL"] = challenge_url
if challenge_json:
task["task"]["challengeJSON"] = challenge_json
if use_proxy:
task["task"].update({
"proxyType": "http",
"proxyAddress": "1.2.3.4",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "pass"
})
# Create task
response = requests.post(CREATE_TASK_URL, json=task)
result = response.json()
if result.get("errorId") != 0:
raise Exception(f"Task creation error: {result}")
task_id = result["taskId"]
# Poll for result
while True:
time.sleep(5)
res = requests.post(GET_RESULT_URL, json={
"clientKey": API_KEY,
"taskId": task_id
}).json()
if res.get("status") == "ready":
return res["solution"]["token"]
elif res.get("errorId") != 0:
raise Exception(f"Solving error: {res}")
# Usage
token = solve_altcha(
website_url="https://example.com/",
challenge_url="https://example.com/api/altcha/challenge?sitekey=abc123"
)
print(f"Token received: {token[:50]}...")
Node.js (axios)
javascript
const axios = require('axios');
const API_KEY = 'YOUR_API_KEY';
const CREATE_TASK_URL = 'https://api.2captcha.com/createTask';
const GET_RESULT_URL = 'https://api.2captcha.com/getTaskResult';
async function solveAltcha(websiteURL, challengeURL = null, challengeJSON = null) {
if (!challengeURL && !challengeJSON) {
throw new Error('Specify challengeURL or challengeJSON');
}
const task = {
clientKey: API_KEY,
task: {
type: 'AltchaTaskProxyless',
websiteURL
}
};
if (challengeURL) task.task.challengeURL = challengeURL;
if (challengeJSON) task.task.challengeJSON = challengeJSON;
// Create task
const { data: createResponse } = await axios.post(CREATE_TASK_URL, task);
if (createResponse.errorId !== 0) {
throw new Error(`Error: ${JSON.stringify(createResponse)}`);
}
const taskId = createResponse.taskId;
// Poll for result
while (true) {
await new Promise(resolve => setTimeout(resolve, 5000));
const { data: result } = await axios.post(GET_RESULT_URL, {
clientKey: API_KEY,
taskId
});
if (result.status === 'ready') {
return result.solution.token;
}
if (result.errorId !== 0) {
throw new Error(`Solving error: ${JSON.stringify(result)}`);
}
}
}
// Usage
solveAltcha(
'https://example.com/',
'https://example.com/api/altcha/challenge?sitekey=abc123'
).then(token => {
console.log('Token:', token);
});
Error Handling and Recommendations
Common API Errors
| Error Code | Description | Solution |
|---|---|---|
| ERROR_WRONG_USER_KEY | Invalid API key | Verify clientKey in your dashboard |
| ERROR_NO_SLOT_AVAILABLE | No available workers | Retry the request after 10-15 seconds |
| ERROR_CAPTCHA_UNSOLVABLE | Captcha cannot be solved | Verify parameter freshness, try a different proxy |
Stability Recommendations
-
Use Fresh Challenge Data
Challenges have a limited lifespan. Extract them immediately before submitting the task. -
Optimal Polling Interval
Poll task status every 5-10 seconds — a balance between speed and API load. -
Proxy Rotation When Using AltchaTask
Rotate proxies to avoid IP-based blocking during high-volume requests. -
Logging for Debugging
RecordtaskId, creation/retrieval timestamps, and errors — this simplifies issue diagnosis. -
Timeouts and Retries
If no solution is received within 60-90 seconds, consider the task expired and create a new one.
Useful Links
Conclusion
ALTCHA is a modern approach to protecting against automated requests: instead of visual puzzles, it uses cryptographic proof-of-work, making the mechanism invisible to users and more resilient against simple forms of automation.
For correct integration, it is important to:
- Ensure accurate transmission of parameters related to challenge
- Account for usage context, including websiteURL and other related data
- Properly handle system responses and use received tokens within the intended workflow
Key point: Operational stability directly depends on the freshness and correctness of transmitted data. Even with a correct implementation, it is essential to include error handling and retry logic.