Skip to content

x402 Payments (Agentic API)

uCaptcha exposes a parallel payment rail built on the x402 protocol. Agents pay per call in USDC on Base — no account, no API key, no balance to top up. Each solve is settled on-chain only when it succeeds; failed or timed-out solves cost nothing.

This rail is additive. The standard clientKey API on /createTask continues to work exactly as before for users with a uCaptcha account.

  • No signup. An agent that hits the endpoint without authentication gets a 402 Payment Required response describing what to pay. It signs and retries. That’s the entire onboarding.
  • Pay only on success. The server verifies your payment up front but only settles it on-chain after the captcha is actually solved. If the task fails or times out, no funds move.
  • Deterministic pricing. The price for each task type is published at /x402/pricing and only changes when we change the table — no per-request quoting.
  • Same solver network. x402 calls go through the same routing engine as standard calls. You get the same provider failover, the same task types, the same latency profile.

Each task type has a flat USDC price computed from the worst-case internal cost across all enabled providers, plus a 50% margin. We use worst-case so the price never depends on which provider routes the request.

The full price table is available at:

GET https://api.ucaptcha.net/x402/pricing
{
"network": "base",
"payTo": "0xADBA492fb2e41912d82161C7E5bFE4195E4c6637",
"asset": "USDC",
"pricesUsd": {
"ReCaptchaV2TokenProxyLess": 0.0045,
"HardCaptchaTokenProxyLess": 0.012,
"TurnstileTokenProxyLess": 0.003,
"ImageToTextTask": 0.001
}
}

Prices are quoted to four decimal places of USD (a single atomic unit of USDC is 0.000001 USD; we round up to 0.0001 USD for clean settlement).

Synchronous. Returns the solution in the same response (typical solves complete in 5–30s, with a 60-second hard cap).

The body is identical to the standard createTask body, without clientKey:

{
"task": {
"type": "ReCaptchaV2TaskProxyless",
"websiteURL": "https://example.com",
"websiteKey": "6Le-wvkSAAAAAPBMRTvw0Q4Muexq9bi0DJwx_mJ-"
},
"selectionMode": "autoFastest",
"provider": "capsolver"
}

selectionMode and provider work the same as on the standard endpoint. appId / softId / devId are not accepted on this rail.

Without an X-PAYMENT header you get a 402 with the requirements:

HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"x402Version": 1,
"error": "X-PAYMENT header is required",
"accepts": [
{
"scheme": "exact",
"network": "base",
"maxAmountRequired": "12000",
"resource": "https://api.ucaptcha.net/x402/createTask",
"description": "uCaptcha solve: HardCaptchaTokenProxyLess",
"payTo": "0xADBA492fb2e41912d82161C7E5bFE4195E4c6637",
"maxTimeoutSeconds": 90,
"asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
"extra": { "name": "USD Coin", "version": "2" }
}
]
}

maxAmountRequired is in atomic USDC units (6 decimals). 12000 = 0.012 USDC = $0.012.

Sign an EIP-3009 transferWithAuthorization for the exact amount and asset, base64-encode the payload, and send it back as X-PAYMENT:

POST /x402/createTask HTTP/1.1
Host: api.ucaptcha.net
Content-Type: application/json
X-PAYMENT: eyJ4NDAyVmVyc2lvbiI6MSwic2NoZW1lIjoiZXhhY3QiLCJuZXR3b3JrIjoiYmFzZSIsInBheWxvYWQiOnsiYXV0aG9yaXphdGlvbiI6eyJmcm9tIjoiMHguLi4iLCJ0byI6IjB4QURCQTQ5MmZiMmU0MTkxMmQ4MjE2MUM3RTViRkU0MTk1RTRjNjYzNyIsInZhbHVlIjoiMTIwMDAiLCJ2YWxpZEFmdGVyIjoiMCIsInZhbGlkQmVmb3JlIjoiOTk5OTk5OTk5OSIsIm5vbmNlIjoiMHguLi4ifSwic2lnbmF0dXJlIjoiMHguLi4ifX0=
{ "task": { "type": "HardCaptchaTokenProxyLess", "...": "..." } }

If the payment is valid the server runs the solve and (only on success) settles it. The response includes the solution and a resultToken you can use to re-fetch the result for free:

HTTP/1.1 200 OK
X-PAYMENT-RESPONSE: eyJ0cmFuc2FjdGlvbiI6IjB4Li4uIiwic3VjY2VzcyI6dHJ1ZX0=
{
"taskId": "550e8400-e29b-41d4-a716-446655440000",
"status": "ready",
"solution": { "gRecaptchaResponse": "03AGdBq25..." },
"cost": 0.0028,
"solveTimeMs": 11420,
"resultToken": "k4Tq...base64url"
}

X-PAYMENT-RESPONSE is a base64-encoded settlement receipt including the on-chain transaction hash. cost is uCaptcha’s internal provider cost for transparency — you paid the flat x402 price, not this.

If something goes wrong, the response status is ≥400 and the payment is not settled. You can retry without re-signing only if you keep the same authorization unspent (most wallets do).

StatusMeaning
400 Bad RequestUnsupported task type, malformed body
402 Payment RequiredMissing, invalid, or unsettled payment
422 Unprocessable EntityCaptcha could not be solved by any provider
429 Too Many RequestsPer-IP rate limit exceeded (60 req/minute on x402 endpoints)
503 Service UnavailableNo provider available for this task type
504 Gateway TimeoutSolve did not complete within 60 seconds

Re-fetch a result you already paid for. Free — gated by the resultToken returned from createTask.

POST https://api.ucaptcha.net/x402/getTaskResult
Content-Type: application/json
{
"taskId": "550e8400-e29b-41d4-a716-446655440000",
"resultToken": "k4Tq...base64url"
}

Or pass the token as the X-Result-Token header. Response shape mirrors the standard getTaskResult.

Public, cacheable. Returns the full per-task-type price table plus the receiving address and network. Useful for agents that want to discover supported task types and prices without provoking a 402.

Anything that speaks x402 will work. The protocol is one HTTP request, one signature, one retry — no SDK strictly required. For convenience:

  • TypeScript / Nodex402-fetch wraps fetch so retries with payment happen automatically. Compatible with viem-style wallets.
  • Pythonx402-requests does the same for requests.
  • Roll your own — sign an EIP-3009 TransferWithAuthorization over the published asset, base64-encode the payload, send as X-PAYMENT. The wire format is documented at x402.org/spec.
  • Base mainnet USDC only. No testnet, no other chains, no other assets at this time.
  • No App ID / referral commissions. App IDs require an account; x402 callers don’t have one.
  • No callback URLs. Since createTask is synchronous, there’s no need.
  • No Lightning mode. x402 calls always solve fresh.
  • Rate limit. 60 requests/minute per IP across /x402/*, in addition to whatever your wallet’s RPC tolerates.