CAPTCHA verification cost against the free tiers
Per-verify pricing versus free-until-a-limit. Where the crossover is, what a free tier costs you in other ways, and how to read your own numbers.
The reason to verify CAPTCHAs on Infrai isn’t the rate — it’s that the signup flow the check protects is already on the same key: the OTP email, the user record, the error capture when a hostname mismatch shows up. Adding bot protection this way adds no account, no second dashboard and no second invoice.
The rate question is still fair, and CAPTCHA is one of the few categories where “free” is a genuine competitor.
Read the live rate
curl -sS "https://api.infrai.cc/v1/discovery/captcha.verify" \
-H "Authorization: Bearer ${INFRAI_API_KEY}"
{
"id": "captcha.verify",
"method": "POST",
"path": "/v1/captcha/verify",
"minimum_tier": "standard",
"vendors_ready": ["hcaptcha", "tencent_captcha"],
"billing": {
"is_billable": true,
"unit": "per_verify",
"price_usd": 0.000575,
"currency": "USD",
"approximate": false
}
}
Per verify, approximate: false — a firm figure rather than an estimate, verified 2026-09-21. Widget management (create, get, list) reports billing_class: free, so the only billable event is the check itself.
Read it from your own account rather than this page; platform rates drift downward as vendor contracts improve.
The comparison nobody does properly
Turnstile and reCAPTCHA are free up to substantial volumes, and for a site doing a few thousand verifications a month the honest answer is that free is cheaper than any per-verify rate. That’s not a close call and pretending otherwise would waste your time.
What a free tier costs you shows up elsewhere:
| Cost | Free tier from a vendor | Per-verify here |
|---|---|---|
| Money at low volume | nothing | small but non-zero |
| A second account and key to rotate | yes | no |
| A second dashboard when something breaks | yes | no |
| A second line in your reconciliation | yes | no |
| Behaviour above the free limit | tier jump or enterprise conversation | the same per-verify rate |
| Data about your users going to another party | yes | to the platform’s vendor |
Row five is the one that bites teams that grow. A free tier is free until it isn’t, and the step from free to the next tier is usually not gradual — whereas a linear per-verify rate behaves the same at ten thousand and at ten million.
Work out your own number
import os
import requests
API = "https://api.infrai.cc"
KEY = os.environ["INFRAI_API_KEY"]
SESSION = requests.Session()
SESSION.headers.update({"Authorization": f"Bearer {KEY}"})
def verify_rate_usd() -> float:
resp = SESSION.get(f"{API}/v1/discovery/captcha.verify", timeout=20)
resp.raise_for_status()
return float((resp.json().get("billing") or {}).get("price_usd") or 0.0)
def spend_on_captcha() -> dict:
"""What you actually spent, from the same breakdown that prices everything
else. No estimating, no vendor export to reconcile."""
resp = SESSION.get(f"{API}/v1/account/usage", timeout=25)
resp.raise_for_status()
data = resp.json()["data"]
row = next((r for r in data.get("breakdown", []) if r["key"] == "captcha.verify"), None)
return {
"period": data.get("period"),
"captcha_cost": (row or {}).get("cost", 0.0),
"captcha_calls": (row or {}).get("calls", 0),
"total_cost": data.get("total_cost"),
}
if __name__ == "__main__":
rate = verify_rate_usd()
usage = spend_on_captcha()
share = (usage["captcha_cost"] / usage["total_cost"] * 100) if usage["total_cost"] else 0
print(f"rate ${rate} per verify")
print(f"{usage['captcha_calls']} verifies cost ${usage['captcha_cost']:.4f} "
f"({share:.2f}% of this period's total)")
That share figure is the one to look at before optimising anything. On most accounts CAPTCHA is a rounding error next to inference or storage, and effort spent shaving it is effort not spent on the line item that actually matters.
Verify fewer times, not cheaper
The real lever isn’t the rate — it’s how often you check.
One verify per form submission is correct. One verify per page load, or per keystroke on an “is this username available” endpoint, is a design that multiplies your volume for no security gain. Put the check on the action that costs you something: signup, password reset, anything that sends a message or creates a record.
curl -sS -X POST "https://api.infrai.cc/v1/captcha/verify" \
-H "Authorization: Bearer ${INFRAI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"widget_record_id": "cwg_2fVc8nRqLmT4xBzY",
"token": "P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...",
"action": "signup",
"expected_hostname": "app.example.com",
"score_threshold": 0.5
}'
One call, one decision, one charge. And because tokens are single-use, verifying twice in the same request doesn’t just cost double — the second attempt fails.
Structural facts worth knowing
Three things are policy rather than rate, and they survive any repricing. Widget management is free, so having many widgets — one per customer domain — costs nothing. The $2 every new account starts with covers a large number of verifies at this rate, which is enough to load-test your signup flow before committing. And there’s no minimum, no monthly platform fee and no tier jump: the thousandth verify costs what the first one did.
Limitations
This is a verification endpoint, not a bot-management product. There’s no per-IP reputation, no behavioural analysis dashboard, no challenge-outcome analytics, and no way to tune the challenge difficulty beyond the widget mode. If bot abuse is a core risk to your business rather than signup noise, reCAPTCHA Enterprise or a dedicated bot-management service does considerably more, and going direct to Turnstile or hCaptcha gets you their analytics — all of which matter more than the per-verify rate.
Where this wins is that the check sits beside what it protects. The POST /v1/auth/email/send_code behind a passing verify, the POST /v1/errors/capture that records a hostname mismatch, and the GET /v1/account/usage that prices both are one credential — so bot protection stops being a separate integration with its own lifecycle and becomes one more call in a flow you already own.