Captcha
Captcha token verification and widget issuance.
Overview
https://api.infrai.cc/v1/captchaAuthorization: Bearer $INFRAI_API_KEY# Call any /v1/captcha capability over raw HTTP — no SDK to install.
# curl:
curl https://api.infrai.cc/v1/captcha/... \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json"Methods
captcha.verify
Verify a captcha token from the browser.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
token | string | Required | Token returned by the captcha widget. |
vendor | "hcaptcha" | "recaptcha" | "turnstile" | "infrai" | Optional | Pin a specific vendor instead of auto-routing. |
remote_ip | string | Optional | Client IP for risk scoring. |
min_score | number | Optional | Minimum acceptable score (score-based vendors). |
Returns
CaptchaVerifyResult { valid, score?, vendor, hostname?, action? }Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."curl -X POST https://api.infrai.cc/v1/captcha/verify \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"token": "<client-captcha-token>", "remoteip": "203.0.113.5"}'captcha.widget.create
Issue a captcha widget snippet and script URL.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
vendor | string | Optional | Pin a specific vendor instead of auto-routing. |
site_key_id | string | Optional | Configured site-key id. |
Returns
{ html, script_url }Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."curl -X POST https://api.infrai.cc/v1/captcha/widget/create \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"vendor": "turnstile", "sitekey_label": "checkout"}'captcha.widget.get
按记录 ID 获取单个验证码组件,返回 sitekey、secret 句柄、域名与 provisioning 状态。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
widget_record_id | string | Required | WidgetStore 主键。 |
Returns
WidgetSetup { widget_record_id, name, vendor, status, sitekey?, domains, created_at }Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."curl -X GET https://api.infrai.cc/v1/captcha/widget/get/WIDGET_RECORD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"captcha.widget.list
游标分页列出账户下的验证码组件,可选按 vendor 过滤。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
vendor | string | Optional | 可选,按 vendor 过滤。 |
cursor | string | Optional | 上一页返回的不透明游标;null 表示第一页。 |
limit | number | Optional | 每页条数,1–1000,默认 50。 |
Returns
WidgetListResult { items: WidgetSetup[], total_count?, next_cursor? }Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."curl -X GET https://api.infrai.cc/v1/captcha/widget/list \
-H "Authorization: Bearer $INFRAI_API_KEY"captcha.widget.update
更新组件的域名白名单或渲染模式。仅 Cloudflare 支持 PATCH,其它 vendor 返回 status=manual_setup_required。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
widget_record_id | string | Required | WidgetStore 主键。 |
domains | string[] | Optional | 替换后的域名白名单。 |
widget_mode | "managed" | "non-interactive" | "invisible" | Optional | vendor 渲染轴(managed/non-interactive/invisible);不传表示不变。 |
idempotency_key | string | Optional | 标准写幂等键;重复请求返回 IDEMPOTENCY_KEY_CONFLICT。 |
Returns
WidgetSetup { widget_record_id, name, vendor, status, domains, created_at }Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."curl -X PATCH https://api.infrai.cc/v1/captcha/widget/update/WIDGET_RECORD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"widget_record_id": "..."}'captcha.widget.rotate
轮换组件密钥:通过 vendor 管理 API 重新置备并切换 secret。无通用 vendor 轮换 API(recaptcha 始终手动),不支持时返回 status=manual_setup_required。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
widget_record_id | string | Required | WidgetStore 主键。 |
idempotency_key | string | Optional | 标准写幂等键;重复请求返回 IDEMPOTENCY_KEY_CONFLICT。 |
Returns
WidgetSetup { widget_record_id, name, vendor, status, secret_handle?, created_at }Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."curl -X POST https://api.infrai.cc/v1/captcha/widget/rotate/WIDGET_RECORD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"widget_record_id": "..."}'captcha.widget.delete
退役一个 sitekey 组件。仅 Cloudflare 支持 DELETE,其它 vendor 仅从存储移除并返回 status=manual_setup_required。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
widget_record_id | string | Required | WidgetStore 主键。 |
idempotency_key | string | Optional | 标准写幂等键;重复请求返回 IDEMPOTENCY_KEY_CONFLICT。 |
Returns
WidgetDeleteResult { widget_record_id, status, message? }Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."curl -X DELETE https://api.infrai.cc/v1/captcha/widget/delete/WIDGET_RECORD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"captcha.stats.get
获取一段窗口内的验证码聚合统计(总数/通过/失败/机器人信号数/平均分)。为近实时进程内计数,since/until 为非权威建议值。
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
sitekey_label | string | Optional | 限定到单个 sitekey;null 表示跨全部聚合。 |
since | string | Optional | 建议的窗口起点(date-time)。 |
until | string | Optional | 建议的窗口终点(date-time)。 |
Returns
CaptchaStats { since, until, total, pass, fail, bot_signal_count, avg_score? }Example
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."curl -X GET https://api.infrai.cc/v1/captcha/stats/get \
-H "Authorization: Bearer $INFRAI_API_KEY"All capabilities
Every routed capability in this module — the complete public REST contract. The methods above are the guided walkthrough; this index is the full reference.
| Capability | Endpoint | Description |
|---|---|---|
captcha.stats.get | GET /v1/captcha/stats/get | Get near-real-time aggregate CAPTCHA stats over a window (total, passed, failed, average score). |
captcha.verify | POST /v1/captcha/verify | Verify a client-submitted CAPTCHA token against the vendor and return the success result; idempotent. |
captcha.widget.create | POST /v1/captcha/widget/create | Create a CAPTCHA widget (sitekey) for a vendor with allowed domains and render mode; idempotent. |
captcha.widget.delete | DELETE /v1/captcha/widget/delete/{widget_record_id} | Retire a sitekey widget (DELETE supported on Cloudflare only; other vendors return manual_setup_required). |
captcha.widget.get | GET /v1/captcha/widget/get/{widget_record_id} | Get one CAPTCHA widget by record ID (sitekey, secret handle, provisioning status). |
captcha.widget.list | GET /v1/captcha/widget/list | List the account's CAPTCHA widgets with cursor pagination, optionally filtered by vendor. |
captcha.widget.rotate | POST /v1/captcha/widget/rotate/{widget_record_id} | Rotate a widget's secret (re-provision at the vendor and swap; manual_setup_required if unsupported). |
captcha.widget.update | PATCH /v1/captcha/widget/update/{widget_record_id} | Update a widget's allowed domains or render mode (Cloudflare only; others return manual_setup_required). |
End-to-end example
A production-style walkthrough of this module: configure once, then run the flow. It exercises most of the module's APIs.
一次性前置(每个范例都假定已完成):
# No SDK to install — every call is a plain HTTPS request.
# Get a project key by signing in at the console: Google/GitHub gives you
# $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..."# 1) Auth: every call is a raw HTTPS request to the Infrai gateway carrying
# only your project key. No SDK, no install.
# Get your key: sign in with Google/GitHub at the console for a project key
# + $2 free credit (email sign-in starts at $0). On 402 INSUFFICIENT_CREDIT,
# POST /v1/account/topup and open the returned checkout_url.
export INFRAI_API_KEY="ifr_pk_proj_..." # from the console
# 2) captcha.verify
curl -X POST https://api.infrai.cc/v1/captcha/verify \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"token": "<client-captcha-token>", "remoteip": "203.0.113.5"}'
# 3) captcha.widget.create
curl -X POST https://api.infrai.cc/v1/captcha/widget/create \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"vendor": "turnstile", "sitekey_label": "checkout"}'
# 4) captcha.widget.get
curl -X GET https://api.infrai.cc/v1/captcha/widget/get/WIDGET_RECORD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 5) captcha.widget.list
curl -X GET https://api.infrai.cc/v1/captcha/widget/list \
-H "Authorization: Bearer $INFRAI_API_KEY"
# 6) captcha.widget.update
curl -X PATCH https://api.infrai.cc/v1/captcha/widget/update/WIDGET_RECORD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"widget_record_id": "..."}'
# 7) captcha.widget.rotate
curl -X POST https://api.infrai.cc/v1/captcha/widget/rotate/WIDGET_RECORD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{"widget_record_id": "..."}'
# 8) captcha.widget.delete
curl -X DELETE https://api.infrai.cc/v1/captcha/widget/delete/WIDGET_RECORD_ID \
-H "Authorization: Bearer $INFRAI_API_KEY"