How to Solve hCaptcha Programmatically: Complete Developer Guide
Complete guide to solving hCaptcha challenges via API — covering HardCaptchaTaskProxyless, enterprise mode, finding site keys, and integration examples in Python and JavaScript.
Solving hCaptcha programmatically is one of the most common requirements for developers building web scrapers, automation tools, and testing frameworks. hCaptcha has grown to protect millions of websites since its launch in 2019, and understanding how to handle it through an API is an essential skill for any automation developer.
This guide covers everything you need: how hCaptcha works under the hood, how to locate the site key, how to use both proxyless and proxy-based task types, how to handle enterprise challenges, and full working code examples in Python and JavaScript.
What Is hCaptcha and How Does It Work?
hCaptcha is a bot-detection service that presents users with image classification challenges. When a user encounters hCaptcha, they typically see a grid of images and are asked to select the ones matching a given description, such as “Select all images containing a bus” or “Click on the images with traffic lights.”
Behind the scenes, hCaptcha operates in several stages:
- JavaScript initialization — The hCaptcha script loads on the page and collects browser fingerprint data, mouse movements, and other behavioral signals.
- Risk assessment — hCaptcha’s backend evaluates whether the visitor looks like a bot based on collected signals. Low-risk visitors may pass without a challenge.
- Visual challenge — If the risk score is high enough, hCaptcha presents an image classification task. The difficulty scales with the risk level.
- Token generation — Upon successful completion, hCaptcha generates an
h-captcha-responsetoken that the website’s backend verifies through hCaptcha’s API.
The key difference from reCAPTCHA is hCaptcha’s business model: site owners get paid for serving hCaptcha challenges, while the image labeling data generated by users is sold to machine learning companies. This financial incentive has driven rapid adoption, especially after Cloudflare switched from reCAPTCHA to hCaptcha in 2020.
Why hCaptcha Adoption Is Growing
Several factors have accelerated hCaptcha’s market share beyond the Cloudflare partnership:
- Privacy compliance. Unlike reCAPTCHA, hCaptcha does not feed data into an advertising network. This makes it a better fit for GDPR-conscious sites in Europe.
- Revenue sharing. Site owners earn money for each challenge served, creating a direct financial incentive to choose hCaptcha over free alternatives.
- No Google dependency. Organizations that want to avoid Google services for competitive or philosophical reasons can use hCaptcha without any Google infrastructure.
- Proof-of-work layer. hCaptcha includes computational proof-of-work challenges that increase the cost of running bots at scale, independent of the visual challenge itself.
For automation developers, this adoption trend means hCaptcha encounters will only become more frequent. Having a reliable solving pipeline is not optional — it is a baseline requirement.
Finding the hCaptcha Site Key
Before you can solve an hCaptcha challenge through an API, you need two pieces of information:
- Website URL — The page where the CAPTCHA appears.
- Site key — A public key that identifies the hCaptcha widget on that specific site.
Method 1: Inspect the HTML Source
Open the page in your browser and search the source for the hCaptcha container element:
<div class="h-captcha" data-sitekey="a5f74b19-9e45-40e0-b45d-47ff91b7a6c2"></div>
The data-sitekey attribute contains the site key.
Method 2: Monitor Network Requests
Open your browser’s DevTools, go to the Network tab, and look for requests to hcaptcha.com/checksiteconfig. The request parameters will include the site key:
https://hcaptcha.com/checksiteconfig?v=...&sitekey=a5f74b19-9e45-40e0-b45d-47ff91b7a6c2&...
Method 3: Search JavaScript Variables
Some sites load the site key dynamically. Search the page’s JavaScript for patterns like sitekey, hcaptcha, or data-sitekey to find it embedded in script blocks.
Task Types: Proxyless vs Proxy
uCaptcha supports two task types for hCaptcha:
HardCaptchaTaskProxyless
This is the simplest option. The solving infrastructure handles the challenge without requiring you to provide a proxy. Use this when:
- You do not need the solution to appear from a specific IP address.
- The target site does not perform strict IP matching between CAPTCHA solving and form submission.
- You want the fastest, most reliable results.
HardCaptchaTask
This variant routes the solving process through your proxy. Use this when:
- The target site checks that the IP solving the CAPTCHA matches the IP submitting the form.
- You are working with sites that implement strict session-IP binding.
The proxy parameters follow the standard format: proxyType, proxyAddress, proxyPort, and optionally proxyLogin and proxyPassword.
A Note on Task Type Aliases
Some CAPTCHA solving providers have renamed hCaptcha task types due to DMCA-related concerns. You may encounter HardCaptchaTaskProxyless and HardCaptchaTask as alternative names. uCaptcha accepts both the standard names and these aliases, so HardCaptchaTaskProxyless and HardCaptchaTaskProxyless are interchangeable in your API calls.
Solving hCaptcha: Step by Step
The solving flow has two stages:
- Create the task — Send the site key and URL to the API.
- Poll for the result — Check periodically until the solution is ready.
Python Example
import requests
import time
API_KEY = "YOUR_UCAPTCHA_API_KEY"
BASE_URL = "https://api.ucaptcha.net"
# Step 1: Create the task
create_response = requests.post(f"{BASE_URL}/createTask", json={
"clientKey": API_KEY,
"task": {
"type": "HardCaptchaTaskProxyless",
"websiteURL": "https://example.com/login",
"websiteKey": "a5f74b19-9e45-40e0-b45d-47ff91b7a6c2"
}
})
result = create_response.json()
if result.get("errorId") != 0:
raise Exception(f"Task creation failed: {result.get('errorDescription')}")
task_id = result["taskId"]
print(f"Task created: {task_id}")
# Step 2: Poll for the result
while True:
time.sleep(5)
status_response = requests.post(f"{BASE_URL}/getTaskResult", json={
"clientKey": API_KEY,
"taskId": task_id
})
status = status_response.json()
if status.get("status") == "ready":
token = status["solution"]["gRecaptchaResponse"]
print(f"Solved! Token: {token[:60]}...")
break
elif status.get("status") == "processing":
print("Still solving...")
else:
raise Exception(f"Error: {status.get('errorDescription')}")
JavaScript Example
const API_KEY = "YOUR_UCAPTCHA_API_KEY";
const BASE_URL = "https://api.ucaptcha.net";
async function solveHardCaptcha(websiteURL, websiteKey) {
// Step 1: Create the task
const createRes = await fetch(`${BASE_URL}/createTask`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
clientKey: API_KEY,
task: {
type: "HardCaptchaTaskProxyless",
websiteURL,
websiteKey,
},
}),
});
const createData = await createRes.json();
if (createData.errorId !== 0) {
throw new Error(`Task creation failed: ${createData.errorDescription}`);
}
const taskId = createData.taskId;
console.log(`Task created: ${taskId}`);
// Step 2: Poll for the result
while (true) {
await new Promise((resolve) => setTimeout(resolve, 5000));
const resultRes = await fetch(`${BASE_URL}/getTaskResult`, {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
clientKey: API_KEY,
taskId,
}),
});
const resultData = await resultRes.json();
if (resultData.status === "ready") {
console.log(`Solved! Token: ${resultData.solution.gRecaptchaResponse.slice(0, 60)}...`);
return resultData.solution.gRecaptchaResponse;
} else if (resultData.status === "processing") {
console.log("Still solving...");
} else {
throw new Error(`Error: ${resultData.errorDescription}`);
}
}
}
// Usage
solveHardCaptcha(
"https://example.com/login",
"a5f74b19-9e45-40e0-b45d-47ff91b7a6c2"
).then((token) => {
console.log("Use this token in your form submission");
});
Using Proxies with HardCaptchaTask
When the target site performs IP verification, switch to HardCaptchaTask and include your proxy details:
create_response = requests.post(f"{BASE_URL}/createTask", json={
"clientKey": API_KEY,
"task": {
"type": "HardCaptchaTask",
"websiteURL": "https://example.com/login",
"websiteKey": "a5f74b19-9e45-40e0-b45d-47ff91b7a6c2",
"proxyType": "http",
"proxyAddress": "proxy.example.com",
"proxyPort": 8080,
"proxyLogin": "user",
"proxyPassword": "pass"
}
})
Proxy-based tasks take slightly longer because the solver must route its traffic through your proxy, but they produce tokens that are valid for the same IP your scraper uses.
Injecting the h-captcha-response Token
Once you receive the solution token, you need to inject it into the target page’s form. The token goes into a hidden textarea with the name h-captcha-response:
# Using requests — include the token in your form POST
form_data = {
"username": "myuser",
"password": "mypass",
"h-captcha-response": token,
"g-recaptcha-response": token # Some sites check this field too
}
response = requests.post("https://example.com/login", data=form_data)
If you are using a browser automation tool like Playwright or Puppeteer, set the token directly:
// Playwright example
await page.evaluate((token) => {
document.querySelector('[name="h-captcha-response"]').value = token;
document.querySelector('[name="g-recaptcha-response"]').value = token;
}, token);
await page.click('button[type="submit"]');
Handling hCaptcha Enterprise
Standard hCaptcha is only half the story. Many high-value targets use hCaptcha Enterprise, which adds advanced risk scoring and custom difficulty levels. Enterprise challenges may require you to pass an enterprisePayload parameter containing site-specific configuration data.
The task structure for enterprise challenges looks like this:
create_response = requests.post(f"{BASE_URL}/createTask", json={
"clientKey": API_KEY,
"task": {
"type": "HardCaptchaTaskProxyless",
"websiteURL": "https://enterprise-site.com/signup",
"websiteKey": "enterprise-site-key-here",
"isEnterprise": True,
"enterprisePayload": {
"rqdata": "additional-data-from-site"
}
}
})
The rqdata value is typically found in the page’s JavaScript or in network requests to hCaptcha’s API. Check out the full hCaptcha Enterprise guide for detailed instructions on extracting these parameters.
Common Parameters Reference
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | HardCaptchaTaskProxyless or HardCaptchaTask |
websiteURL | string | Yes | URL of the page with hCaptcha |
websiteKey | string | Yes | The hCaptcha site key |
isEnterprise | boolean | No | Set to true for Enterprise challenges |
enterprisePayload | object | No | Enterprise-specific data (e.g., rqdata) |
userAgent | string | No | Custom User-Agent string |
proxyType | string | Proxy only | http, https, or socks5 |
proxyAddress | string | Proxy only | Proxy hostname or IP |
proxyPort | integer | Proxy only | Proxy port number |
proxyLogin | string | No | Proxy username |
proxyPassword | string | No | Proxy password |
Troubleshooting Common Issues
Token Expired
hCaptcha tokens are valid for approximately 120 seconds. If your workflow has delays between solving and submitting, the token may expire. Solve this by minimizing the time between receiving the token and using it. Request the solution just before you need it rather than in advance.
Incorrect Site Key
If the API returns an error about an invalid site key, double-check that you extracted the correct key. Some sites use different keys for different pages or load them dynamically. Always verify the key from the actual page where the CAPTCHA appears.
Challenge Type Mismatch
If you are getting low success rates, the site may be using hCaptcha Enterprise with custom parameters. Try adding the isEnterprise flag and any required enterprisePayload data.
IP Mismatch Rejection
When the target site rejects your submission despite a valid token, it likely checks that the CAPTCHA-solving IP matches the form-submitting IP. Switch from HardCaptchaTaskProxyless to HardCaptchaTask and provide the same proxy your scraper uses.
hCaptcha vs reCAPTCHA: A Quick Comparison
If you are deciding which CAPTCHA type your automation needs to handle, understanding the differences matters. hCaptcha relies heavily on image classification challenges, while reCAPTCHA uses a mix of behavioral analysis and image tasks. Solve rates, speed, and cost vary between the two. Read the full hCaptcha vs reCAPTCHA comparison for a detailed breakdown.
Understanding the Response Object
When the task completes successfully, the response includes a solution object with these fields:
{
"errorId": 0,
"status": "ready",
"solution": {
"gRecaptchaResponse": "P0_eyJ0eXAiOiJKV1Qi...",
"respKey": "E0_eyJ0eXAiOiJKV1Qi...",
"userAgent": "Mozilla/5.0 ..."
}
}
- gRecaptchaResponse — The main token. Despite the name referencing reCAPTCHA, this is the standard field name used across CAPTCHA solving APIs for compatibility. Inject this into the
h-captcha-responseform field. - respKey — A secondary response key that some sites verify. Include it as
g-recaptcha-responseif the target site checks for it. - userAgent — The User-Agent string used during solving. If the target site validates User-Agent consistency, use this same string in your subsequent requests.
Best Practices
- Use proxyless when possible. It is faster and more reliable. Only use proxy-based tasks when the target site requires IP consistency.
- Cache site keys. Site keys rarely change. Extract them once and reuse them across requests.
- Handle errors gracefully. Implement retry logic with exponential backoff for transient failures.
- Respect rate limits. Sending too many concurrent tasks can trigger rate limiting on both the solver API and the target site.
- Monitor solve times. If solve times spike, it may indicate the target site has switched to Enterprise mode or changed its configuration.
- Use the returned User-Agent. When the solution includes a
userAgentfield, use that exact string for your form submission to avoid User-Agent mismatch detection.
Conclusion
hCaptcha is one of the most widely deployed bot-detection systems, but it is also one of the most straightforward to solve through a CAPTCHA API. The key is having the right site key, choosing the correct task type, and injecting the response token properly.
uCaptcha routes your hCaptcha tasks across multiple solving providers — including CapSolver, 2Captcha, AntiCaptcha, CapMonster, and others — automatically selecting the fastest or cheapest option based on your routing preferences. This means higher solve rates, lower latency, and built-in redundancy without any extra configuration on your end.
Frequently Asked Questions
How do I solve hCaptcha with an API?
Submit the website URL and hCaptcha site key using the HardCaptchaTaskProxyless task type to a CAPTCHA solver API. Poll for the result, which returns an h-captcha-response token to inject into the form.
Is hCaptcha harder to solve than reCAPTCHA?
hCaptcha can be harder for automated solvers because it uses image classification challenges that require visual recognition. However, CAPTCHA solving APIs handle both equally well since the solving is done by specialized workers or AI models.
What does hCaptcha Enterprise add?
hCaptcha Enterprise includes advanced risk scoring, customizable difficulty, bot behavior analytics, and enterprise-grade SLAs. Solving Enterprise challenges may require additional parameters like the enterprise payload.
Related Articles
hCaptcha Enterprise: Solving Advanced Challenges
How to solve hCaptcha Enterprise challenges — understanding enterprise payloads, custom difficulty levels, and the differences from standard hCaptcha.
hCaptcha vs reCAPTCHA: Which Is Harder to Solve?
Comparing hCaptcha and reCAPTCHA from a developer's perspective — solving difficulty, cost, detection methods, privacy, and which CAPTCHA type is more automation-friendly.