Get Captcha Statistics
February 4, 2026 (October 3, 2026)
Table of contents
Query captcha solving statistics for your account. Returns detailed information about captcha token requests and their success/failure rates. Compare success rates across all configured providers to help decide which one works best for your use case.
Every response also carries provider_ranking, the live order the API uses to pick captcha providers automatically (see Automatic provider order), and summary.by_provider_and_type splits each provider’s results by image, video, audio and upload.
Use anonymized=true to get aggregated scores across all users and all captcha providers. This mode returns a summary only (no individual data rows) based on the last 10000 records across all accounts, giving you a broader picture of provider performance.
Note:
- Data latency is at least 5 minutes, but should not exceed 15 minutes.
- Data is retained for 3 months.
- Results are cached for 5 minutes.
https://api.useapi.net/v1/google-flow/accounts/captcha-stats
Request Headers
Authorization: Bearer {API token}
API tokenis required, see Setup useapi.net for details.
Query Parameters
| Parameter | Required | Description |
|---|---|---|
date | No | Date in YYYY-MM-DD format.Defaults to today if limit is not specified. |
limit | No | Number of records to return (max: 50000). If specified, date filter is ignored and returns last N records across all dates. |
provider | No | Filter by captcha provider. Supported: CapSolver, AntiCaptcha, YesCaptcha, CapMonster, SolveCaptcha, 2Captcha, EzCaptcha, UserProvided |
anonymized | No | Set to true to return aggregated scores across all users and all captcha providers.Returns summary only (no individual data rows). Uses last 10000 records across all accounts, ignores date/limit/provider filters. |
Responses
-
Returns captcha statistics for the specified filters.
{ "date": "2026-02-03", "total": 42, "summary": { "from": "2026-02-03T00:05:23.000Z", "to": "2026-02-03T23:58:47.000Z", "time_span": "23 hours 53 minutes", "sample_size_by_provider": { "CapSolver": 24, "AntiCaptcha": 10, "EzCaptcha": 8 }, "success_rate_by_provider": { "CapSolver": 73.20, "AntiCaptcha": 80.50, "EzCaptcha": 68.40 }, "sample_size_by_tier": { "PAYGATE_TIER_TWO": 30, "PAYGATE_TIER_ONE": 12 }, "success_rate_by_tier": { "PAYGATE_TIER_TWO": 81.00, "PAYGATE_TIER_ONE": 66.70 }, "sample_size_by_sku": { "WS_ULTRA": 22, "G1_TIER2": 8, "G1_TIER1": 12 }, "success_rate_by_sku": { "WS_ULTRA": 84.10, "G1_TIER2": 75.00, "G1_TIER1": 66.70 }, "by_status_code_images": { "200": 69.10, "403": 8.50, "429:PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC": 12.30, "429:PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHED": 4.10, "429:PUBLIC_ERROR_USER_REQUESTS_THROTTLED": 1.00, "429:PUBLIC_ERROR_USER_QUOTA_REACHED": 1.40, "503": 3.60 }, "by_status_code_videos": { "200": 67.50, "403": 17.60, "429:PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC": 8.70, "429:PUBLIC_ERROR_USER_REQUESTS_THROTTLED": 1.00, "429:PUBLIC_ERROR_USER_QUOTA_REACHED": 1.40, "503": 3.80 }, "avg_captcha_ms": 8500, "avg_api_ms": 1200, "avg_attempt": 1.2, "by_provider_and_type": { "AntiCaptcha": { "image": { "samples": 6, "success_rate": 83.33, "first_attempt_samples": 5, "first_attempt_success_rate": 80.00 }, "video": { "samples": 4, "success_rate": 75.00, "first_attempt_samples": 3, "first_attempt_success_rate": 66.67 } }, "CapSolver": { "image": { "samples": 16, "success_rate": 81.25, "first_attempt_samples": 12, "first_attempt_success_rate": 83.33 }, "video": { "samples": 8, "success_rate": 57.50, "first_attempt_samples": 6, "first_attempt_success_rate": 50.00 } }, "EzCaptcha": { "image": { "samples": 8, "success_rate": 68.40, "first_attempt_samples": 8, "first_attempt_success_rate": 68.40 } } }, "lookup": { "tiers": { "PAYGATE_TIER_TWO": "Ultra $199", "PAYGATE_TIER_ONE": "Pro" }, "skus": { "WS_ULTRA": "Workspace Ultra", "G1_TIER2": "Ultra $199", "G1_TIER1": "Pro" } } }, "provider_ranking": { "mode": "on", "order": ["AntiCaptcha", "EzCaptcha", "CapSolver", "YesCaptcha", "CapMonster", "SolveCaptcha", "2Captcha"], "leader": "AntiCaptcha", "leaderSince": "2026-10-02T03:15:30.000Z", "computedAt": "2026-10-02T18:40:00.000Z", "providers": { "AntiCaptcha": { "firstAttemptSuccessRate": 84.00, "samples": 100, "status": "leader" }, "EzCaptcha": { "firstAttemptSuccessRate": 71.00, "samples": 100, "status": "ranked" }, "CapSolver": { "firstAttemptSuccessRate": 43.00, "samples": 100, "status": "ranked" }, "YesCaptcha": { "firstAttemptSuccessRate": 78.00, "samples": 41, "status": "collecting" }, "CapMonster": { "status": "collecting" }, "SolveCaptcha": { "firstAttemptSuccessRate": 3.00, "samples": 33, "status": "hopeless" }, "2Captcha": { "firstAttemptSuccessRate": 7.00, "samples": 46, "status": "hopeless" } }, "rules": { "window": "newest 5-minute slots until 100 samples, up to 2 h", "minSamples": 100, "marginPoints": 10, "leaderHoldMinutes": 15, "explorePercent": 10, "exploreCollectingPercent": 30, "exploreHopelessPercent": 2 }, "hopelessUntil": { "SolveCaptcha": "2026-10-02T20:31:00.000Z", "2Captcha": "2026-10-02T20:12:00.000Z" } }, "data": [ { "timestamp": "2026-02-03T10:30:00.000Z", "jobId": "20260203103000123-user:123-bot:google-flow", "provider": "AntiCaptcha", "taskId": "abc123-task-id", "route": "post-videos", "statusText": "OK", "pageAction": "VIDEO_GENERATION", "error": "", "reason": "", "tier": "PAYGATE_TIER_TWO", "sku": "WS_ULTRA", "statusCode": 200, "captchaDurationMs": 8500, "apiDurationMs": 1200, "attemptNumber": 1, "sampleInterval": 1 } ] }The
summaryobject provides aggregated statistics (omitted if no data).On busy days the stats store keeps a sample of the rows from the busiest API tokens rather than every row. Each row’s
sampleIntervalsays how many captcha attempts it stands for. It is1for almost every customer and higher only for the busiest ones at peak hours.totaland every count, rate and average insummaryalready weight each row by itssampleInterval, so they reflect all of your captcha attempts. When you count rows indatayourself, add upsampleIntervalrather than counting rows.limitcounts stored rows, sototalcan be larger thanlimit.Understanding the 429 buckets
Google returns
HTTP 429 RESOURCE_EXHAUSTEDin at least four known distinct situations. Theby_status_code_images/by_status_code_videossummary splits 429s by their reason code so you can tell them apart — each needs a different strategy.Bucket key What it means Customer strategy 429:PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFICGoogle rejected the captcha on every try (we already retried with fresh ones, up to captchaRetry, default 5). Usually the Google account is distrusted, sometimes the provider is doing badly. Counts as a captcha failure insuccess_rate_by_provider.Find out whether it’s a few accounts or all of them — see When Google rejects captchas. Rest or replace distrusted accounts. If all accounts drop together, configure a second provider via POST /accounts/captcha-providers. 429:PUBLIC_ERROR_USER_REQUESTS_THROTTLEDGoogle is throttling this account. The captcha token was fine. Sending fewer parallel requests usually helps, but the limit is not purely a concurrency cap — Google can hold it on an account for far longer. Does NOT count as a captcha failure. Reduce parallel generations per account. With emailomitted, the load balancer quarantines this account for ~30 min and routes around it. TreatRetry-Afteras a minimum wait rather than the moment it clears.429:PUBLIC_ERROR_PER_MODEL_DAILY_QUOTA_REACHEDThis account hit Google’s per-model daily quota. Does NOT count as a captcha failure. Switch to a different model — only this model is capped, other models on the account still work, and it resets at UTC midnight. With emailomitted, the load balancer quarantines just this account+model and routes around it.429:PUBLIC_ERROR_USER_QUOTA_REACHEDThis account hit its overall Google Flow quota cap — separate from per-model limits, blocks all models on this account. Does NOT count as a captcha failure. Add more Google Flow accounts via POST /accounts so the load spreads. With emailomitted, the load balancer quarantines this account for ~30 min and routes around it — though Google’s underlying quota can take 1–2 hours to actually reset.The bottom three reasons automatically quarantine the account —
USER_REQUESTS_THROTTLEDandUSER_QUOTA_REACHEDfor ~30 min,PER_MODEL_DAILY_QUOTA_REACHEDuntil UTC midnight — and the load balancer routes around them whenemailis omitted (see GET /jobs › Load Balancing Algorithm).UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFICis per-request and does not quarantine. Per-reason scope and cooldown: 429 reference.How
success_rate_by_provideris calculatedThis is the end-to-end captcha effectiveness per provider — measured against Google’s reCAPTCHA Enterprise evaluation, not just whether the token was syntactically accepted. Use it to compare providers and decide which to prefer, drop, or rebalance.
A row counts as a captcha failure when:
- HTTP
403— token was rejected outright (PERMISSION_DENIED), except reasonPUBLIC_ERROR_MODEL_ACCESS_DENIED - HTTP
429with reasonPUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC— Google’s response literally says"reCAPTCHA evaluation failed". The token was valid but Google did not trust it enough. That depends on the Google account as much as on the provider — see When Google rejects captchas.
The other 429 reasons (
PER_MODEL_DAILY_QUOTA_REACHED,USER_REQUESTS_THROTTLED,USER_QUOTA_REACHED) are NOT counted as captcha failures because they are account-level limits independent of token quality. HTTP503is also excluded (Google-side outage, unrelated to the provider).A
403with reasonPUBLIC_ERROR_MODEL_ACCESS_DENIEDis NOT a captcha failure either. Google sends it after the token passed, when the account’s plan does not offer the requested model — since 2026-09-23 that includesveo-3.1-lite-low-priorityon invited members of an Ultra $199 family plan. Inby_status_code_images/by_status_code_videosit has its own bucket,403:PUBLIC_ERROR_MODEL_ACCESS_DENIED, so it does not read as a rejected token.If one provider has a noticeably lower
success_rate_by_providerthan the others over the same period, its captchas are scoring poorly with reCAPTCHA Enterprise. The API already moves that provider down your order for you (seeprovider_ranking). To stop using it, leave it out ofcaptchaOrderor remove its key. Topping up its balance can also help, since some providers give higher-balance accounts better proxies. Compare providers on the first-attempt figures inby_provider_and_type, and check the sample sizes before drawing conclusions.When Google rejects captchas
Nothing was created when this happens. Google checks the captcha before it starts generating, so no Google credits were used and you can resubmit straight away. Your captcha provider still bills each solve.
The usual cause is the Google account, not the captcha provider. Google gives each account its own trust level. On a trusted account it accepts about 9 in 10 captchas, on a distrusted one about 3 in 10, whichever provider solved them. Most customers have a few distrusted accounts among many good ones.
To see which accounts are affected, use GET /accounts/captcha-stats. Its
summary.by_accountshows, for each of your Google accounts, how many captchas were tried and what share Google accepted. GET account/stats withbot=google-flowalso shows how many requests each account finished with each response code.- If one or a few accounts are far below the others, the API already sends them less work: when you leave out
email, each captcha Google rejected on an account in the last 15 minutes lowers its chance of being picked, for generations and for image uploads. They still get some work, so an account that recovers gets its full share back. If you pin requests withemail, move them to your other accounts yourself. Replace an account that stays low for more than a day or two. - If all your accounts drop at the same time, it’s the captcha provider. Configure at least two providers with POST /accounts/captcha-providers, and the API will start with whichever one Google accepts best.
A higher
captchaRetrygets more requests through on a distrusted account, but every extra try is another paid solve.How
by_status_code_images/by_status_code_videosare aggregatedThe status distribution shows customer-facing final outcomes per
jobId, not per attempt. A request that internally retried 5 times before succeeding contributes a single"200"to the bucket, not five entries. This makes the distribution a true outcome map.A
429:<reason>bucket therefore counts only requests where our internal retry budget was exhausted before resolving the condition.Image vs video:
by_provider_and_typeA provider can do well on images and badly on video. For example, over the 72 hours to October 2, 2026, Google accepted CapSolver’s first try 46% of the time for images but only 26% for video. EzCaptcha did about the same on both.
by_provider_and_typeshows each provider’s results separately forimage,video,audio(voices) andupload(image upload):samplesandsuccess_ratecount all tries.first_attempt_samplesandfirst_attempt_success_ratecount first tries only. Use these to compare providers. Retries fail more often no matter which provider solves them, because Google has already rejected one captcha for that request. Counting them would make a provider look worse than it is.
A number based on only a few tries means little. In the Try It charts below, bars based on fewer than 100 tries are faded, every label shows how many tries (
n) it is based on, and the busiest providers come first.Automatic provider order:
provider_rankingIf you have two or more captcha providers, most requests start with the one Google is accepting best right now, and moves to the next one if the captcha is rejected.
captchaOrderonly picks which providers to use and how many tries to make, not the order. We recommend adding at least two providers, for example AntiCaptcha and CapSolver, and ideally EzCaptcha too, so fewer captchas are rejected and you pay for fewer of them. How it works: Provider order.provider_rankingshows the current order. It is based on all customers’ requests, not just yours, so you get it even when you have no data of your own.order: the providers, best first.leaderis the one in first place, andleaderSinceis since when.providers.<name>.firstAttemptSuccessRate: the provider’s score. Out of its lastsamplesfirst tries, the percentage Google accepted.status:leader(first place),ranked,collecting(fewer than 100 recent tries, not ranked yet) orhopeless(doing very badly, almost never tried first).hopelessUntilshows until when a provider stayshopeless.rules: the exact numbers the ranking uses.mode:onnormally.offmeans the fixed default order is used, and no other fields are returned.
Understanding
tierandskuEvery row carries the Google
userPaygateTier(tier) andskustrings captured at submission time. These come straight from Google’s/creditsresponse — the same wire-format strings, no translation. Aggregate breakdowns insummary(sample_size_by_tier,success_rate_by_tier,sample_size_by_sku,success_rate_by_sku) let you compare captcha effectiveness across plan levels, which is useful when one plan tier is being scored more aggressively by Google’s reCAPTCHA Enterprise than another.summary.lookup.tiersandsummary.lookup.skusare the canonical human-readable mapping — resolve enum values through these maps rather than hard-coding strings on your side. They cover only the enums present in this response; unknown values map to themselves so you can still see them.Current known values:
Field Enum value Label Plan tierPAYGATE_TIER_NOT_PAIDFree Free tier tierPAYGATE_TIER_ZEROPlus Google AI Plus tierPAYGATE_TIER_ONEPro Google AI Pro tierPAYGATE_TIER_TIER1P5Ultra $99 Google AI Ultra $99/mo tierPAYGATE_TIER_TWOUltra $199 Google AI Ultra $199/mo skuG1_FREEMIUMFree Google AI consumer Free skuG1_TIER0Plus Google AI consumer Plus skuG1_TIER1Pro Google AI consumer Pro skuG1_TIER1P5Ultra $99 Google AI consumer Ultra $99 skuG1_TIER2Ultra $199 Google AI consumer Ultra $199 skuWS_FREEMIUMWorkspace Free Google Workspace, no AI add-on skuWS_ULTRAWorkspace Ultra Google Workspace + AI Ultra add-on Rows written before 2026-05-21 lack
tierandsku(the columns didn’t exist yet) — they’re bucketed under"(empty)"in the per-tier and per-sku aggregates. - HTTP
-
Missing or invalid parameters.
{ "error": "<error message>" } -
Invalid API token.
{ "error": "Unauthorized" }
Model
// Response structure
{
date?: string // Date filter applied (YYYY-MM-DD)
limit?: number // Limit filter applied
provider?: string // Provider filter applied
total: number // Captcha attempts the returned rows stand for (sum of sampleInterval)
summary?: { // Aggregated statistics (omitted if no data)
from: string // Earliest timestamp (ISO 8601)
to: string // Latest timestamp (ISO 8601)
time_span: string // Human readable duration (e.g., "2 days 5 hours")
sample_size_by_provider: Record<string, number> // Attempts per provider across ALL attempts (excludes 503)
success_rate_by_provider: Record<string, number> // Captcha success rate % per provider. Failures: 403 (token rejected) AND 429:PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC (token scored too low by reCAPTCHA Enterprise). Other 429 reasons are NOT counted. (excludes 503)
sample_size_by_tier: Record<string, number> // Attempts per Google userPaygateTier across ALL attempts (excludes 503). Pre-2026-05-21 rows lack tier and bucket under "(empty)"
success_rate_by_tier: Record<string, number> // Captcha success rate % per tier (same failure definition as success_rate_by_provider)
sample_size_by_sku: Record<string, number> // Attempts per Google sku across ALL attempts (excludes 503). Pre-2026-05-21 rows lack sku and bucket under "(empty)"
success_rate_by_sku: Record<string, number> // Captcha success rate % per sku (same failure definition as success_rate_by_provider)
by_account?: Record<string, { // Your Google accounts, by email: captcha results on each. Not in anonymized responses
samples: number
success_rate: number
first_attempt_samples: number
first_attempt_success_rate?: number
}>
by_status_code_images: Record<string, number> // % per customer-facing final-attempt outcome for IMAGE. 429s split by reason — e.g. "429:PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC"
by_status_code_videos: Record<string, number> // Same as by_status_code_images but for VIDEO
avg_captcha_ms: number // Average captcha solve time in ms
avg_api_ms: number // Average API call time in ms
avg_attempt: number // Average attempt number
by_provider_and_type: Record<string, Record<string, { // provider → image | video | audio | upload
samples: number // attempts (excludes 503)
success_rate: number // % accepted, same failure definition as success_rate_by_provider
first_attempt_samples: number // attempt 1 only — the fair comparison between providers
first_attempt_success_rate?: number // omitted when first_attempt_samples is 0
}>>
lookup: { // Canonical enum → human-readable label map for tier/sku enum values present in this response. Resolve enums through this map rather than hard-coding strings.
tiers: Record<string, string> // e.g. { PAYGATE_TIER_TWO: "Ultra $199", PAYGATE_TIER_NOT_PAID: "Free" }. Unknown enums map to themselves.
skus: Record<string, string> // e.g. { WS_ULTRA: "Workspace Ultra", G1_TIER1: "Pro" }. Unknown enums map to themselves.
}
}
provider_ranking?: { // Live automatic provider order, all customers' first attempts (omitted if it can't be read)
mode: 'on' | 'shadow' | 'off' // 'off': only this field is present
order: string[] // Ranking, best first
leader: string // order[0]
leaderSince?: string // When the leader took first place (ISO 8601)
computedAt: string // When this ranking was computed (ISO 8601)
providers: Record<string, {
firstAttemptSuccessRate?: number // % of first-attempt tokens Google accepted (omitted with no samples)
samples?: number // first attempts behind the rate
status: 'leader' | 'ranked' | 'collecting' | 'hopeless'
}>
rules: Record<string, number | string> // thresholds in use (window, minSamples, marginPoints, leaderHoldMinutes, explore*Percent)
hopelessUntil?: Record<string, string> // provider → until when it stays hopeless (ISO 8601)
}
data: Array<{
timestamp: string // ISO 8601 timestamp
jobId: string // Job identifier
provider: string // Captcha provider used (CapSolver, AntiCaptcha, YesCaptcha, CapMonster, SolveCaptcha, 2Captcha, EzCaptcha, UserProvided)
taskId: string // Provider's task ID
route: string // API route (post-videos, post-images, etc.)
statusText: string // HTTP status text (OK, Forbidden, NetworkError)
pageAction: string // reCAPTCHA action (VIDEO_GENERATION, IMAGE_GENERATION)
error: string // Error message (empty on success)
reason: string // Google ErrorInfo.reason — e.g. PUBLIC_ERROR_UNUSUAL_ACTIVITY_TOO_MUCH_TRAFFIC (empty for non-Google errors or successful submits)
tier: string // Google userPaygateTier — PAYGATE_TIER_NOT_PAID / PAYGATE_TIER_ZERO / PAYGATE_TIER_ONE / PAYGATE_TIER_TIER1P5 / PAYGATE_TIER_TWO. Empty for rows pre-2026-05-21. Resolve to a label via summary.lookup.tiers.
sku: string // Google sku — G1_FREEMIUM / G1_TIER0 / G1_TIER1 / G1_TIER1P5 / G1_TIER2 / WS_FREEMIUM / WS_ULTRA. Empty for rows pre-2026-05-21. Resolve to a label via summary.lookup.skus.
statusCode: number // HTTP status code (200, 403, 429, 0 for network errors)
captchaDurationMs: number // Captcha solve duration in ms
apiDurationMs: number // API call duration in ms
attemptNumber: number // Attempt number (1 = first try, 2+ = retry)
sampleInterval: number // How many captcha attempts this row stands for, usually 1 (see above)
}>
}
Examples
-
# Today's stats curl -H "Authorization: Bearer YOUR_API_TOKEN" \ "https://api.useapi.net/v1/google-flow/accounts/captcha-stats" # Specific date curl -H "Authorization: Bearer YOUR_API_TOKEN" \ "https://api.useapi.net/v1/google-flow/accounts/captcha-stats?date=2026-02-01" # Last 1000 records curl -H "Authorization: Bearer YOUR_API_TOKEN" \ "https://api.useapi.net/v1/google-flow/accounts/captcha-stats?limit=1000" # Filter by provider curl -H "Authorization: Bearer YOUR_API_TOKEN" \ "https://api.useapi.net/v1/google-flow/accounts/captcha-stats?provider=AntiCaptcha" # Aggregated scores across all users and providers (summary only) curl -H "Authorization: Bearer YOUR_API_TOKEN" \ "https://api.useapi.net/v1/google-flow/accounts/captcha-stats?anonymized=true" -
const apiUrl = 'https://api.useapi.net/v1/google-flow/accounts/captcha-stats'; const token = 'YOUR_API_TOKEN'; const response = await fetch(apiUrl, { headers: { 'Authorization': `Bearer ${token}` } }); const stats = await response.json(); console.log(`Total captcha attempts: ${stats.total}`); console.log(`Success rates:`, stats.summary?.success_rate_by_provider); console.log('Data:', stats.data); -
import requests apiUrl = 'https://api.useapi.net/v1/google-flow/accounts/captcha-stats' token = 'YOUR_API_TOKEN' headers = { 'Authorization': f'Bearer {token}' } # Today's stats response = requests.get(apiUrl, headers=headers) stats = response.json() print(f"Total captcha attempts: {stats['total']}") print(f"Success rates: {stats.get('summary', {}).get('success_rate_by_provider')}") # Filter by provider response = requests.get( apiUrl, params={'provider': 'AntiCaptcha'}, headers=headers )