HumanGate(1) CAPTCHA-as-a-service HumanGate(1)
NAME
HumanGate - CAPTCHA verification gateway for Telegram bots and apps.
You bring your own CAPTCHA provider keys (Cloudflare Turnstile, Google
reCAPTCHA, Yandex SmartCaptcha) or use a HumanGate-native captcha. We host
the verification page, validate the answer, check Telegram initData, score
risk, and hand the result back via webhook, redirect code, or polling.
API base (local): http://localhost:8090
Pages: /example (live demo) /docs (Swagger) /openapi.yaml
AUTH
Authorization: Bearer hg_live_... (or hg_test_... for test mode)
Keys are issued via the admin CLI; every response carries "livemode".
QUICKSTART
# 1. Save your CAPTCHA keys once (secret_key is encrypted, never returned).
# The first config for a (provider, mode) pair becomes the default.
curl http://localhost:8090/v1/provider-configs \
-H "Authorization: Bearer hg_live_..." \
-d '{
"name": "main",
"provider": "cloudflare_turnstile",
"config": {"site_key": "0x4AAAA...", "secret_key": "0x4AAAA..."}
}'
# 2. Create a challenge per user. The response has "url" - send it to them.
curl http://localhost:8090/v1/challenges \
-H "Authorization: Bearer hg_live_..." \
-d '{
"provider": "cloudflare_turnstile",
"action": "telegram_registration",
"subject": {"type": "telegram_user", "id": "123456789"},
"redirect": {"success_url": "https://t.me/your_bot?start=verify_{code}"}
}'
# -> {"id":"ch_...","status":"pending","url":"https://.../c/hgc_..."}
# 3. User passes the CAPTCHA and returns to your bot with /start verify_.
# Verify the code (single-use).
curl http://localhost:8090/v1/verifications/verify \
-H "Authorization: Bearer hg_live_..." \
-d '{"code": "A7F2K9XW4M", "expected_action": "telegram_registration"}'
# -> {"valid":true,"subject":{...},"risk_score":14}
PROVIDERS
cloudflare_turnstile external, needs provider-config keys
google_recaptcha_v2 external, checkbox widget
google_recaptcha_v3 external, invisible/score-based (config.min_score)
yandex_smartcaptcha external, normal or invisible (config.invisible)
text_image native, server-rendered distorted text, no keys
proof_of_work native, SHA-256 leading-zero-bits, no keys
browser_fingerprint native, anti-headless heuristics, no keys
Native captchas need no keys: the task is returned by /start (field "task")
and verified server-side against per-session state. The browser never learns
the expected answer.
WEBHOOK
Events: challenge.passed | challenge.failed | challenge.blocked | challenge.expired
Signature: HumanGate-Signature: v1=HMAC_SHA256(secret, "." + body)
Any 2xx response means delivered; retries use exponential backoff.
LIVE DEMO (test mode, no API key)
# Returns a challenge url you can open in a browser.
curl -X POST http://localhost:8090/public/v1/demo -d '{"provider":"text_image"}'
# Available demo providers:
curl http://localhost:8090/public/v1/demo
SEE ALSO
/example - live demo links (click a provider to try a captcha)
/docs - Swagger UI (interactive API explorer)
/openapi.yaml - machine-readable OpenAPI 3 spec