hCaptcha
hCaptcha is a CAPTCHA service that can be used to bypass rate limiting when legitimate users are affected.
Schema Integration
hCaptcha uses the same GraphQL schema integration as other CAPTCHA providers:
enum CaptchaType { HCAPTCHA # hCaptcha TURNSTILE # Cloudflare Turnstile V2_VISIBLE # reCAPTCHA v2 with visible checkbox V2_INVISIBLE # reCAPTCHA v2 without visible elements}
type CaptchaConfiguration { type: CaptchaType! siteKey: String!}
Implementation Examples
Successful Registration with hCaptcha
When users complete hCaptcha verification, the token can bypass rate limiting:
mutation CreateAccount($input: CreateAccountInput!) { createAccount(input: $input) { success account { id email firstName lastName } error fieldErrors { fieldName validators requiredButNotProvided invalidOption } }}
Request Headers:
X-Captcha-Type: HCAPTCHAX-Captcha-Response: P1_eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9...Content-Type: application/json
Rate Limited Response with hCaptcha Configuration
When rate limits are exceeded, hCaptcha configuration is provided:
{ "data": { "createAccount": null }, "errors": [ { "message": "Too many registration attempts", "path": ["createAccount"], "extensions": { "classification": "CAPTCHA_REQUIRED", "rateLimited": true, "rateLimitingBucket": "REGISTRATION" } } ], "extensions": { "rateLimitersFiring": [ { "captchaBypassAvailable": [ { "type": "HCAPTCHA", "siteKey": "12345678-1234-1234-1234-123456789012" } ], "rateLimitingBucket": "REGISTRATION" } ] }}
Error Handling
Common hCaptcha error responses:
Error Code | Description |
---|---|
missing-input-response | No token provided |
invalid-input-response | Invalid token |
missing-input-secret | Server configuration issue |
invalid-input-secret | Invalid secret key |
expired-input-response | Token has expired |
sitekey-secret-mismatch | Key configuration mismatch |
API Usage
Both web and mobile APIs support hCaptcha using the same header pattern:
// Web APIfetch('https://horizon-api.www.myprotein.com/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Captcha-Type': 'HCAPTCHA', 'X-Captcha-Response': hcaptchaToken }, credentials: 'include', body: JSON.stringify({ query, variables })});
// Mobile APIfetch('https://api.thehut.net/myprotein/en/graphql', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Captcha-Type': 'HCAPTCHA', 'X-Captcha-Response': hcaptchaToken, 'Authorization': 'Opaque ' + userToken }, body: JSON.stringify({ query, variables })});