Authentication
Every API request requires your api_key. Retrieve it from your Dashboard after signing in.
Pass your key as the key field in JSON request bodies, or as a ?key= query parameter for GET requests.
Both the Request Processing (headless API) and Browser Extension (browser) share the same API key and balance.
"9cap-xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx"
Create Task
Submit a visual payload to the 9Captcha network. Returns a task_id you can poll for the processed result.
Request Body
Your 9Captcha secret API key.
hcaptcha_basic or hcaptcha_enterprise (our internal API mapping for standard or enterprise visual processing)
The public site key of the target website.
The domain of the target website, e.g. example.com. Defaults to example.com if omitted.
Your proxy in username:password@host:port format. Highly recommended.
Enterprise rqdata string, if applicable.
User-Agent to fingerprint the solve session.
curl -X POST https://9captcha-api.pridesmp.fun/api/create_task \
-H "Content-Type: application/json" \
-d '{
"key": "9cap-your-api-key-here",
"type": "hcaptcha_basic",
"data": {
"sitekey": "4c672d35-0701-42b2-88c3-78380b0db560",
"siteurl": "https://example.com",
"proxy": "user:pass@1.2.3.4:8080"
}
}'
{
"status": "success",
"task_id": "abc123-def456-..."
}
Get Result
Poll this endpoint every 1.5–2 seconds using the task_id returned by create_task until the status is solved (processed).
Zero-Waste Policy: You are only charged when status is solved. Failures and timeouts cost nothing.
{
"status": "solving"
}
{
"status": "solved",
"solution": "P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1..."
}
// Possible error values:
// "rate-limit-exceeded"
// "ip-rejected: Target server rejected your IP/proxy..."
// "Insufficient balance"
// "Failed to solve"
// "Solver timeout - task took too long"
{
"status": "error",
"error": "rate-limit-exceeded"
}
Browser Extension
The Browser Extension runs inside a real Chromium browser. It loads a Chrome extension that intercepts visual challenges and processes them automatically. The response is injected directly into the page DOM.
Best for: Browser-based automation (Puppeteer, Playwright, Selenium, nodriver), or any workflow where you control a browser instance.
Setup
Download the 9Captcha extension from your Dashboard.
Create a config.json inside the extension folder with your API key.
Load the extension into Chromium using the --load-extension flag.
Navigate to any page with visual challenges — the extension auto-processes and injects the response.
Key Activation: On first launch the extension calls /api/activate to validate your key. Ensure config.json exists before starting.
{
"api_key": "9cap-your-api-key-here"
}
Python — nodriver
Recommended for Python automation. Uses truedriver (or nodriver) to launch Chromium with the extension loaded.
import asyncio
import json, os, time
import truedriver as td
API_KEY = "9cap-your-api-key-here"
EXT_DIR = os.path.abspath("./extension")
async def solve():
# 1. Write config
with open(os.path.join(EXT_DIR, "config.json"), "w") as f:
json.dump({"api_key": API_KEY}, f)
# 2. Launch browser
browser = await td.start(
browser_args=[
f"--disable-extensions-except={EXT_DIR}",
f"--load-extension={EXT_DIR}",
],
headless=False
)
# 3. Activate key
await browser.get(f"https://9captcha-api.pridesmp.fun/setup#key={API_KEY}")
await asyncio.sleep(4)
# 4. Navigate & wait for result
page = await browser.get("https://example.com")
for _ in range(60):
try:
token = await asyncio.wait_for(
page.evaluate("hcaptcha.getResponse()"), timeout=2
)
if token and len(token) > 30:
print(f"[✓] Token: {token[:60]}...")
return token
except Exception:
pass
await asyncio.sleep(1)
asyncio.run(solve())
Python — Selenium
If you prefer Selenium (or undetected-chromedriver), load the extension via ChromeOptions.
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import json, os, time
EXT_DIR = os.path.abspath("./extension")
# Write config (omitted for brevity)
options = Options()
options.add_argument(f"--load-extension={EXT_DIR}")
options.add_argument(f"--disable-extensions-except={EXT_DIR}")
driver = webdriver.Chrome(options=options)
# Setup & Activate
driver.get(f"https://9captcha-api.pridesmp.fun/setup#key=...")
time.sleep(4)
# Target
driver.get("https://example.com")
for _ in range(60):
try:
token = driver.execute_script("return hcaptcha.getResponse()")
if token and len(token) > 30:
print(token)
break
except Exception:
pass
time.sleep(1)
Node.js — Puppeteer
Load the extension via launch arguments in Puppeteer.
const puppeteer = require('puppeteer-extra');
// Setup config.json...
(async () => {
const browser = await puppeteer.launch({
headless: false,
args: [
`--disable-extensions-except=./extension`,
`--load-extension=./extension`
],
});
// Activate key
const setupPage = await browser.newPage();
await setupPage.goto(`https://9captcha-api.pridesmp.fun/setup#key=...`);
await new Promise(r => setTimeout(r, 4000));
await setupPage.close();
// Navigate to target
const page = await browser.newPage();
await page.goto('https://example.com');
// Wait for token
const token = await page.evaluate(() => {
return new Promise(r => {
setInterval(() => {
try {
const t = hcaptcha.getResponse();
if (t) r(t);
} catch(e) {}
}, 1000);
});
});
console.log(token);
})();
Errors & Limits
Common error strings returned in the error field of the JSON response.
rate-limit-exceeded— Target server is rate-limiting your proxy IP. Rotate proxies.ip-rejected— Target server rejected your IP/proxy. Use a residential proxy or switch to Browser Extension mode.Invalid API key— Your key doesn't exist or has been deactivated.Insufficient balance— Top up your balance from the Dashboard.Failed to solve— The engine couldn't process the challenge. Retry with a different proxy.Solver timeout - task took too long— Task exceeded the 120-second time limit.Server busy— Max concurrent requests reached. Retry in 10–15 seconds.
Best Practices
Maximize your accuracy rate and minimize blocks:
- Always pass a proxy — Processing on your server's IP without a proxy will get it flagged quickly.
- Match your IPs — Use the same proxy IP for processing and for the final target request. Target servers tie tokens to the processing IP.
- Don't reuse tokens — Each token is single-use. Generate a fresh one per action.
- Extension cleanup — Close tabs after each request. Old tabs cause the extension to lose track of the widget.
- Poll responsibly — 1.5–2s interval is optimal. Faster polling doesn't speed up processing.