Skip to content

Captcha

Captcha token verification and widget issuance.

Overview

Base path: https://api.infrai.cc/v1/captcha
Auth header: Authorization: Bearer $INFRAI_API_KEY
bash
# 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

POST /v1/captcha/verify

Verify a captcha token from the browser.

Parameters

NameTypeRequiredDescription
tokenstring
Required
Token returned by the captcha widget.
vendor"hcaptcha" | "recaptcha" | "turnstile" | "infrai"OptionalPin a specific vendor instead of auto-routing.
remote_ipstringOptionalClient IP for risk scoring.
min_scorenumberOptionalMinimum acceptable score (score-based vendors).

Returns

CaptchaVerifyResult { valid, score?, vendor, hostname?, action? }

Example

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
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

POST /v1/captcha/widget/create

Issue a captcha widget snippet and script URL.

Parameters

NameTypeRequiredDescription
vendorstringOptionalPin a specific vendor instead of auto-routing.
site_key_idstringOptionalConfigured site-key id.

Returns

{ html, script_url }

Example

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
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

GET /v1/captcha/widget/get/{widget_record_id}

按记录 ID 获取单个验证码组件,返回 sitekey、secret 句柄、域名与 provisioning 状态。

Parameters

NameTypeRequiredDescription
widget_record_idstring
Required
WidgetStore 主键。

Returns

WidgetSetup { widget_record_id, name, vendor, status, sitekey?, domains, created_at }

Example

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
curl -X GET https://api.infrai.cc/v1/captcha/widget/get/WIDGET_RECORD_ID \
  -H "Authorization: Bearer $INFRAI_API_KEY"

captcha.widget.list

GET /v1/captcha/widget/list

游标分页列出账户下的验证码组件,可选按 vendor 过滤。

Parameters

NameTypeRequiredDescription
vendorstringOptional可选,按 vendor 过滤。
cursorstringOptional上一页返回的不透明游标;null 表示第一页。
limitnumberOptional每页条数,1–1000,默认 50。

Returns

WidgetListResult { items: WidgetSetup[], total_count?, next_cursor? }

Example

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
curl -X GET https://api.infrai.cc/v1/captcha/widget/list \
  -H "Authorization: Bearer $INFRAI_API_KEY"

captcha.widget.update

PATCH /v1/captcha/widget/update/{widget_record_id}

更新组件的域名白名单或渲染模式。仅 Cloudflare 支持 PATCH,其它 vendor 返回 status=manual_setup_required。

Parameters

NameTypeRequiredDescription
widget_record_idstring
Required
WidgetStore 主键。
domainsstring[]Optional替换后的域名白名单。
widget_mode"managed" | "non-interactive" | "invisible"Optionalvendor 渲染轴(managed/non-interactive/invisible);不传表示不变。
idempotency_keystringOptional标准写幂等键;重复请求返回 IDEMPOTENCY_KEY_CONFLICT。

Returns

WidgetSetup { widget_record_id, name, vendor, status, domains, created_at }

Example

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
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

POST /v1/captcha/widget/rotate/{widget_record_id}

轮换组件密钥:通过 vendor 管理 API 重新置备并切换 secret。无通用 vendor 轮换 API(recaptcha 始终手动),不支持时返回 status=manual_setup_required。

Parameters

NameTypeRequiredDescription
widget_record_idstring
Required
WidgetStore 主键。
idempotency_keystringOptional标准写幂等键;重复请求返回 IDEMPOTENCY_KEY_CONFLICT。

Returns

WidgetSetup { widget_record_id, name, vendor, status, secret_handle?, created_at }

Example

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
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

DELETE /v1/captcha/widget/delete/{widget_record_id}

退役一个 sitekey 组件。仅 Cloudflare 支持 DELETE,其它 vendor 仅从存储移除并返回 status=manual_setup_required。

Parameters

NameTypeRequiredDescription
widget_record_idstring
Required
WidgetStore 主键。
idempotency_keystringOptional标准写幂等键;重复请求返回 IDEMPOTENCY_KEY_CONFLICT。

Returns

WidgetDeleteResult { widget_record_id, status, message? }

Example

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
curl -X DELETE https://api.infrai.cc/v1/captcha/widget/delete/WIDGET_RECORD_ID \
  -H "Authorization: Bearer $INFRAI_API_KEY"

captcha.stats.get

GET /v1/captcha/stats/get

获取一段窗口内的验证码聚合统计(总数/通过/失败/机器人信号数/平均分)。为近实时进程内计数,since/until 为非权威建议值。

Parameters

NameTypeRequiredDescription
sitekey_labelstringOptional限定到单个 sitekey;null 表示跨全部聚合。
sincestringOptional建议的窗口起点(date-time)。
untilstringOptional建议的窗口终点(date-time)。

Returns

CaptchaStats { since, until, total, pass, fail, bot_signal_count, avg_score? }

Example

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
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.

CapabilityEndpointDescription
captcha.stats.getGET /v1/captcha/stats/getGet near-real-time aggregate CAPTCHA stats over a window (total, passed, failed, average score).
captcha.verifyPOST /v1/captcha/verifyVerify a client-submitted CAPTCHA token against the vendor and return the success result; idempotent.
captcha.widget.createPOST /v1/captcha/widget/createCreate a CAPTCHA widget (sitekey) for a vendor with allowed domains and render mode; idempotent.
captcha.widget.deleteDELETE /v1/captcha/widget/delete/{widget_record_id}Retire a sitekey widget (DELETE supported on Cloudflare only; other vendors return manual_setup_required).
captcha.widget.getGET /v1/captcha/widget/get/{widget_record_id}Get one CAPTCHA widget by record ID (sitekey, secret handle, provisioning status).
captcha.widget.listGET /v1/captcha/widget/listList the account's CAPTCHA widgets with cursor pagination, optionally filtered by vendor.
captcha.widget.rotatePOST /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.updatePATCH /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.

一次性前置(每个范例都假定已完成):

bash
# 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_..."
bash
# 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"