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.
Why use this
Section titled “Why use this”- No signup. An agent that hits the endpoint without authentication gets a
402 Payment Requiredresponse 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/pricingand 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.
Pricing
Section titled “Pricing”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).
Endpoints
Section titled “Endpoints”POST /x402/createTask
Section titled “POST /x402/createTask”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.
First request — no payment
Section titled “First request — no payment”Without an X-PAYMENT header you get a 402 with the requirements:
HTTP/1.1 402 Payment RequiredContent-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.
Second request — with payment
Section titled “Second request — with payment”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.1Host: api.ucaptcha.netContent-Type: application/jsonX-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 OKX-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.
Failure modes
Section titled “Failure modes”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).
| Status | Meaning |
|---|---|
400 Bad Request | Unsupported task type, malformed body |
402 Payment Required | Missing, invalid, or unsettled payment |
422 Unprocessable Entity | Captcha could not be solved by any provider |
429 Too Many Requests | Per-IP rate limit exceeded (60 req/minute on x402 endpoints) |
503 Service Unavailable | No provider available for this task type |
504 Gateway Timeout | Solve did not complete within 60 seconds |
POST /x402/getTaskResult
Section titled “POST /x402/getTaskResult”Re-fetch a result you already paid for. Free — gated by the resultToken returned from createTask.
POST https://api.ucaptcha.net/x402/getTaskResultContent-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.
GET /x402/pricing
Section titled “GET /x402/pricing”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.
Client libraries
Section titled “Client libraries”Anything that speaks x402 will work. The protocol is one HTTP request, one signature, one retry — no SDK strictly required. For convenience:
- TypeScript / Node —
x402-fetchwrapsfetchso retries with payment happen automatically. Compatible with viem-style wallets. - Python —
x402-requestsdoes the same forrequests. - Roll your own — sign an EIP-3009
TransferWithAuthorizationover the published asset, base64-encode the payload, send asX-PAYMENT. The wire format is documented at x402.org/spec.
Constraints
Section titled “Constraints”- 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.