How to Solve hCaptcha
The box above is a live hCaptcha checkbox. This page shows two ways to solve hCaptcha and get a valid h-captcha-response token: by calling the CapSkip HTTP API from your own code, or by routing the captcha service your tools already call to CapSkip. CapSkip is an unlimited hCaptcha solver that runs locally on your device, so there are no per solve fees and nothing leaves your machine.
Option 1: Solve hCaptcha with the CapSkip HTTP API
Building automation, a scraper or a bot? Send this page's site key and URL to the CapSkip app with one request, poll for the result, and CapSkip hands back a fresh hCaptcha token you can submit like a real one. The API uses the standard in.php / res.php endpoints, so it works from Python, Node.js, PHP, C# or any other language that can make an HTTP call.
10000000-ffff-ffff-ffff-000000000001
https://capskip.com/captcha-demo/hcaptcha/
Before you start
CapSkip solves locally. Download and run the CapSkip desktop app and keep it open in the background. Your code talks to it on 127.0.0.1:8080, so there are no cloud calls and no per solve fees.
Send the hCaptcha to CapSkip
Post this page's sitekey and pageurl to in.php with method=hcaptcha. CapSkip answers at once with a task ID.
import time
import requests
API = "http://127.0.0.1:8080" # the CapSkip app on your machine
KEY = "YOUR_API_KEY"
# 1. Submit the hCaptcha shown on this page
task = requests.post(f"{API}/in.php", data={
"key": KEY,
"method": "hcaptcha",
"sitekey": "10000000-ffff-ffff-ffff-000000000001",
"pageurl": "https://capskip.com/captcha-demo/hcaptcha/",
"json": 1,
}).json()["request"]
# 2. Poll until the token is ready
while True:
time.sleep(5)
res = requests.get(f"{API}/res.php", params={
"key": KEY, "action": "get", "id": task, "json": 1,
}).json()
if res["request"] != "CAPCHA_NOT_READY":
break
token = res["request"] # the h-captcha-response token
print(token)const API = 'http://127.0.0.1:8080'; // the CapSkip app on your machine
const KEY = 'YOUR_API_KEY';
const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
(async () => {
// 1. Submit the hCaptcha shown on this page
const submit = await fetch(`${API}/in.php`, {
method: 'POST',
body: new URLSearchParams({
key: KEY,
method: 'hcaptcha',
sitekey: '10000000-ffff-ffff-ffff-000000000001',
pageurl: 'https://capskip.com/captcha-demo/hcaptcha/',
json: '1',
}),
}).then((r) => r.json());
// 2. Poll until the token is ready
let res;
do {
await sleep(5000);
res = await fetch(`${API}/res.php?key=${KEY}&action=get&id=${submit.request}&json=1`)
.then((r) => r.json());
} while (res.request === 'CAPCHA_NOT_READY');
const token = res.request; // the h-captcha-response token
console.log(token);
})();<?php
$api = 'http://127.0.0.1:8080'; // the CapSkip app on your machine
$key = 'YOUR_API_KEY';
// 1. Submit the hCaptcha shown on this page
$ch = curl_init("$api/in.php");
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POSTFIELDS => http_build_query([
'key' => $key,
'method' => 'hcaptcha',
'sitekey' => '10000000-ffff-ffff-ffff-000000000001',
'pageurl' => 'https://capskip.com/captcha-demo/hcaptcha/',
'json' => 1,
]),
]);
$task = json_decode(curl_exec($ch), true)['request'];
// 2. Poll until the token is ready
do {
sleep(5);
$res = json_decode(file_get_contents(
"$api/res.php?key=$key&action=get&id=$task&json=1"
), true);
} while ($res['request'] === 'CAPCHA_NOT_READY');
$token = $res['request']; // the h-captcha-response token
echo $token;using System.Text.Json;
const string Api = "http://127.0.0.1:8080"; // the CapSkip app on your machine
const string Key = "YOUR_API_KEY";
var http = new HttpClient();
// 1. Submit the hCaptcha shown on this page
var submit = await http.PostAsync($"{Api}/in.php", new FormUrlEncodedContent(new Dictionary<string, string>
{
["key"] = Key,
["method"] = "hcaptcha",
["sitekey"] = "10000000-ffff-ffff-ffff-000000000001",
["pageurl"] = "https://capskip.com/captcha-demo/hcaptcha/",
["json"] = "1",
}));
string task = JsonDocument.Parse(await submit.Content.ReadAsStringAsync())
.RootElement.GetProperty("request").GetString()!;
// 2. Poll until the token is ready
string token;
do
{
await Task.Delay(5000);
var res = JsonDocument.Parse(await http.GetStringAsync(
$"{Api}/res.php?key={Key}&action=get&id={task}&json=1"));
token = res.RootElement.GetProperty("request").GetString()!;
} while (token == "CAPCHA_NOT_READY");
Console.WriteLine(token); // the h-captcha-response tokenYou get a long token, usually starting with P1_, that is valid for this site key, ready to submit. The same response also carries respKey and the useragent of the browser that solved it.
Use the token
Put the token into the widget's hidden h-captcha-response textarea. hCaptcha also fills a g-recaptcha-response textarea for sites that read that one, so set both. If the widget was rendered with a data-callback, run that function with the token. Then submit the form, and your server verifies it with hCaptcha siteverify. Note that this demo verifies through the widget's own callback, so it checks the token the widget produced rather than one you place in the field.
// 1. Drop the solved token into both response fields
document.querySelector('[name="h-captcha-response"]').value = token;
document.querySelector('[name="g-recaptcha-response"]').value = token;
// 2. If the widget has a data-callback, run it with the token
const cb = document.querySelector('.h-captcha')?.dataset.callback;
if (cb && window[cb]) window[cb](token);
// 3. ...then submit your form.Invisible hCaptcha and hCaptcha Enterprise
An invisible widget has no checkbox and opens only when the site calls hcaptcha.execute(); add invisible=1 to the request. Enterprise sites often pass an rqdata value to the widget; send it as data. When the site checks the browser, submit the token with the exact useragent that CapSkip returns.
POST http://127.0.0.1:8080/in.php
key=YOUR_API_KEY
method=hcaptcha
sitekey=SITEKEY_FROM_THE_PAGE
pageurl=https://the-protected-site.com/login
invisible=1
data=RQDATA_FROM_THE_PAGE
json=1
GET http://127.0.0.1:8080/res.php?key=YOUR_API_KEY&action=get&id=2122988149&json=1
{"status":1,"request":"P1_eyJ0eXAiOiJKV1Qi…","respKey":"E0_eyJ0eXAi…","useragent":"Mozilla/5.0 …"}The API also accepts a proxy and proxytype, which helps when the site checks that the token was earned from your own IP. Anti-Captcha style clients can send the same job as a createTask of type HCaptchaTaskProxyless, HCaptchaTask or HCaptchaEnterpriseTask.
The full list of request parameters, response fields and error codes lives in the CapSkip API docs.
Option 2: Send your existing solver-service code to CapSkip
Already solving hCaptcha through a pay-per-captcha service such as 2Captcha, Anti-Captcha or CapSolver? You do not have to rewrite a line. The CapSkip app includes a service emulator that speaks those services' own APIs locally: pick the service you use, click Add to hosts file, and every request your bot, scraper or off-the-shelf tool already sends to it is answered by CapSkip on your own machine, for a flat price instead of a per-solve bill.
Pick your service
Open the CapSkip app and choose the service your code already talks to: 2Captcha, RuCaptcha, Anti-Captcha, CapMonster Cloud, CapSolver, DeathByCaptcha, SolveCaptcha, NextCaptcha, EzCaptcha or Captchas.io.
Add to hosts file
One click in the app points that service's domain at CapSkip, so the calls your tool makes are answered on your own machine instead of going out to a paid API.
Run your tool unchanged
Same API key, same request, same polling loop. CapSkip replies in that service's own format and your code gets a valid h-captcha-response token back.
Nothing below changes when you switch. It is the same call your code makes today, except that hCaptcha is now solved locally and a valid h-captcha-response token comes back from CapSkip:
POST https://2captcha.com/in.php
key=YOUR_EXISTING_API_KEY
method=hcaptcha
sitekey=10000000-ffff-ffff-ffff-000000000001
pageurl=https://capskip.com/captcha-demo/hcaptcha/
GET https://2captcha.com/res.php?key=YOUR_EXISTING_API_KEY&action=get&id=2122988149
OK|P1_eyJ0eXAi… the h-captcha-response token, solved by CapSkipClient libraries work the same way: an Anti-Captcha style createTask / getTaskResult pair, or any wrapper built on one of these services, keeps working once the emulator is on. The full request and response reference lives in the CapSkip API docs.
More on solving hCaptcha
Guides for the tools and languages people usually pair with this demo.
About this hCaptcha demo
This page is a live hCaptcha demo where you can test how hCaptcha works and watch it get solved in real time. hCaptcha is a privacy-focused CAPTCHA that many sites use in place of reCAPTCHA: it shows an "I am human" checkbox and, when it is not sure about a visitor, an image challenge such as picking the matching pictures in a grid. Use it to explore hCaptcha token generation, the h-captcha-response value, and the verification flow that websites rely on to protect forms, logins and signups from spam, abuse and bots.
Developers, testers and automation engineers can use this hCaptcha test page to check integrations, validate a setup and benchmark how fast CapSkip solves hCaptcha. Whether you need to solve hCaptcha once or automate thousands of solves, CapSkip works two ways: a plain HTTP API you can call from any language, and drop-in emulation of the captcha services you may be paying per solve today, both with unlimited solving on one flat price. Both are driven by the same desktop AI captcha solver, installed once and running on your own machine, so nothing is queued on a remote server and nothing is billed per solve.
