Switching from NopeCHA to NoneCap.
NopeCHA discontinued its hCaptcha endpoint on October 2, 2026, so hCaptcha calls to NopeCHA now fail with HTTP 410. This guide moves an API integration over to NoneCap field by field. If you used the NopeCHA browser extension instead, skip to the extension section.
What NopeCHA announced
Users reported on NopeCHA’s GitHub that hCaptcha solving had stopped, with the error “This API endpoint has been discontinued”. A NopeCHA collaborator replied:
“This is working as intended, the hCaptcha API endpoint has been discontinued and support will be removed in a future extension release.”
Source: NopeCHA’s extension repository on GitHub, October 2, 2026. NopeCHA’s API reference no longer lists the hCaptcha token endpoint, and its error list now includes “Endpoint Discontinued” (HTTP 410, code 19).
Before you start
- Create an account and an API key on the NoneCap dashboard. New accounts get 1,300 free credits, no card. Sign up through this link and your first top-up also gets +25% extra credits.
- Pick how you’ll call it: plain HTTP, the Node SDK (
npm install nonecap) or the Python SDK (pip install nonecap). - Billing is prepaid credits that never expire, from 1 credit per hCaptcha challenge round. Failed solves are never charged. Details are on the pricing page.
Request fields, NopeCHA to NoneCap
| NopeCHA (hCaptcha token API) | NoneCap | Notes |
|---|---|---|
POST https://api.nopecha.com/v1/token/hcaptcha(or POST /token with "type": "hcaptcha") | POST https://api.nonecap.com/v1/solves | One endpoint for every hCaptcha solve. The captcha kind goes in type. |
key in the body or query, or Authorization: Basic <key> | Authorization: Bearer <key> | Header only. Create a key on the dashboard. |
implied by the endpoint path; enterprise: true for enterprise sitekeys | type: "hcaptcha" or "hcaptcha_enterprise" | Required. Where you sent enterprise: true, use hcaptcha_enterprise. |
sitekey | sitekey | Same value: the UUID in the widget’s data-sitekey. |
url | url | Same value: the page the widget is on. |
data.rqdata | rqdata | Moves to the top level of the body. Optional; send it fresh for each challenge when the site provides one. |
proxy object: scheme, host, port, username, password | proxy: the same object, or a URL string | Schemes http, https, socks5, socks5h, socks4. |
useragent | user_agent is accepted but ignored; read user_agent from the solved solve | Every solve presents its own browser identity. Submit the token with the user_agent it returns. |
cookie | no equivalent | Leave it out. |
Responses and polling
NopeCHA hands back a job id and you poll until it stops answering 409. NoneCap returns
a solve object straight away. Add ?wait=N and the request holds until the
solve finishes or the wait runs out, which often saves the poll loop entirely; a 202
means it is still running and you poll GET /v1/solves/{id}.
| NopeCHA | NoneCap | |
|---|---|---|
| Submit returns | {"data": "<job id>"} | A solve object: id, status, and token once solved |
| Polling | GET /v1/token/hcaptcha?id=<job id>; HTTP 409, code 14 while the job is incomplete | GET /v1/solves/{id}; HTTP 202 while pending or solving, 200 once finished |
| Waiting without a loop | none | ?wait=N (1 to 90 seconds) on the submit or the poll holds the request until the solve finishes or the wait runs out |
| The token | data | token (a P1_… string) |
| Extras | none | resp_key, user_agent, credits_charged |
| A solve that fails | an error body with a numeric code | status: "failed" with error.code, error.message and error.retryable. Never charged. |
Before and after
A NopeCHA hCaptcha call looked like this:
curl https://api.nopecha.com/v1/token/hcaptcha \
-H "Authorization: Basic $NOPECHA_KEY" \
-H "Content-Type: application/json" \
-d '{
"sitekey": "f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8",
"url": "https://target.example/login",
"data": { "rqdata": "..." }
}'
# -> {"data": "<job id>"}, then GET ?id=<job id> until it stops answering 409 The same solve on NoneCap:
curl "https://api.nonecap.com/v1/solves?wait=90" \
-H "Authorization: Bearer $NONECAP_KEY" \
-H "Content-Type: application/json" \
-d '{
"type": "hcaptcha_enterprise",
"sitekey": "f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8",
"url": "https://target.example/login",
"rqdata": "..."
}'
# 200: the solve finished inside the wait window; read "token".
# 202: still running; poll until it finishes:
curl "https://api.nonecap.com/v1/solves/solve_01HQF7K3JKWZX?wait=60" \
-H "Authorization: Bearer $NONECAP_KEY" {
"id": "solve_01HQF7K3JKWZX",
"object": "solve",
"type": "hcaptcha_enterprise",
"status": "solved",
"token": "P1_eyJ0eXAi...UV8w",
"resp_key": "E0_eyJ0eXAi...9kQw",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/152.0.0.0 Safari/537.36",
"error": null,
"credits_charged": 1
}
Submit token as the form’s h-captcha-response, the same place
NopeCHA’s data went. Some sites check the browser version, so send the
request that carries the token with the solve’s user_agent.
Node (the nonecap package)
nc.solve() submits, waits and polls for you, and throws a typed error if
the solve fails.
// npm install nonecap
import { NoneCap, SolveFailedError } from "nonecap";
const nc = new NoneCap({ apiKey: process.env.NONECAP_KEY! });
try {
const solve = await nc.solve({
type: "hcaptcha",
sitekey: "f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8",
url: "https://target.example/login",
// rqdata: "...", // with type "hcaptcha_enterprise", when the site provides one
// proxy: { scheme: "http", host: "1.2.3.4", port: 8080, username: "u", password: "p" },
});
console.log(solve.token); // was token.data on NopeCHA
console.log(solve.user_agent); // submit the token with this User-Agent
} catch (err) {
if (err instanceof SolveFailedError) console.error(err.solve.error?.message); // not charged
else throw err;
} Python (the nonecap package)
Same shape, sync or async (AsyncNoneCap).
# pip install nonecap
import os
from nonecap import NoneCap, SolveFailedError
nc = NoneCap(api_key=os.environ["NONECAP_KEY"])
try:
solve = nc.solve(
type="hcaptcha",
sitekey="f5ab1c2d-7e8f-4a9b-b1c2-d3e4f5a6b7c8",
url="https://target.example/login",
# rqdata="...", # with type="hcaptcha_enterprise", when the site provides one
# proxy={"scheme": "http", "host": "1.2.3.4", "port": 8080, "username": "u", "password": "p"},
)
print(solve.token) # was token["data"] on NopeCHA
print(solve.user_agent) # submit the token with this User-Agent
except SolveFailedError as err:
print(err.solve.error.message) # not charged
Both SDKs also have solves.start(), which returns a handle you can cancel.
The SDK page and the API reference
cover the rest.
Error codes
NoneCap errors carry a string code instead of a number. The closest match
for each NopeCHA error:
| NopeCHA error | NoneCap equivalent |
|---|---|
| 400, code 10: Invalid request | 400 invalid_request (body is not JSON) or 422 validation_error (param names the field) |
| 401, code 15: Invalid key | 401 unauthorized |
| 403, code 16: Out of credit | 402 insufficient_credits, or 402 key_credit_limit_exceeded when one key hit its own limit |
| 403, code 12: Free tier ineligible | 403 forbidden; the message says why |
| 409, code 14: Incomplete job | not an error: the poll answers 202 with status: "pending" or "solving" |
| 410, code 19: Endpoint discontinued | does not apply |
| 429, code 11: Rate limited | 429 concurrency_limit_exceeded, sitekey_rate_limited, proxy_unavailable or rate_capped, each with Retry-After |
| 500, code 9: Unknown error | 500 internal_error, with a request id to quote to support |
A solve that runs and then fails is not an HTTP error. It finishes with
status: "failed" and an error object whose
retryable flag says whether resending the same request can succeed. Failed
solves are never charged. The full list is in the
error reference.
If you used the NopeCHA extension
NopeCHA says hCaptcha support will be removed in a future extension release. The NoneCap Chrome extension does the same job for hCaptcha: it spots the challenge and clicks through it while you browse.
- Install it from the Chrome Web Store. It takes one click and no signup.
- Use the free tier first: 100 free solves a day, no account. For more, add a NoneCap API key in the extension’s options and it solves on your account balance.
- Pause it on any site, or blocklist the sites where you never want it to run.
- It captures only the challenge area, and only while a challenge is open. The extension privacy page has the full policy.
More on the extension page.
What stays the same
Your sitekeys, target URLs and proxies carry over unchanged, and so does the code that
submits the token. The parts to rewrite are the solver call, where the key goes, and
reading token instead of data.
Last updated October 2026.
Frequently asked
Why did NopeCHA stop solving hCaptcha?
Can I keep my NopeCHA client and only change the key?
h-captcha-response, stays the same.I used the NopeCHA browser extension for hCaptcha. What replaces it?
Does NoneCap handle enterprise hCaptcha with rqdata?
type: "hcaptcha_enterprise", and pass rqdata at the top level of the body when the site provides one. On NopeCHA it lived under data.rqdata.