### Full hCaptcha Protected Signup Form Example Source: https://docs.hcaptcha.com/ This example demonstrates a complete HTML signup form protected by hCaptcha. Upon successful challenge completion, a hidden token is automatically added to the form for server-side verification. ```html hCaptcha Demo

``` -------------------------------- ### hCaptcha Serverless on Fastly Compute@Edge (Rust) Source: https://docs.hcaptcha.com/integrations This example demonstrates hCaptcha serverless integration on Fastly Compute@Edge using Rust. ```rust use fastly::http::{Method, StatusCode}; use fastly::{handle_request, Request, Response}; #[handle_request] async fn handle_request(req: Request) -> Response { if req.get_method() == Method::POST { let token = match req.get_body_bytes() { Ok(bytes) => String::from_utf8_lossy(&bytes).to_string(), Err(_) => return Response::from_status(StatusCode::BAD_REQUEST) }; let secret = std::env::var("HCAPTCHA_SECRET").expect("HCAPTCHA_SECRET must be set"); let client = reqwest::Client::new(); let res = client.post("https://hcaptcha.com/siteverify") .form(&[ ("response", token), ("secret", secret) ]) .send() .await?; if res.status().is_success() { Response::from_status(StatusCode::OK) } else { Response::from_status(StatusCode::BAD_REQUEST) } } else { Response::from_status(StatusCode::METHOD_NOT_ALLOWED) } } ``` -------------------------------- ### Install hCaptcha TypeScript Types Source: https://docs.hcaptcha.com/ Install the TypeScript types for the hcaptcha global variable using either yarn or npm. ```bash yarn add -D @hcaptcha/types ``` ```bash npm install -D @hcaptcha/types ``` -------------------------------- ### Full Theme Schema Example Source: https://docs.hcaptcha.com/custom_themes This object defines the complete theme schema, including palette and component styles. A subset or single property can be provided for merging with default styles. ```javascript var theme = { palette: { mode: "light", grey: { 100 : "#FAFAFA", 200 : "#F5F5F5", 300 : "#E0E0E0", 400 : "#D7D7D7", 500 : "#BFBFBF", 600 : "#919191", 700 : "#555555", 800 : "#333333", 900 : "#222222", 1000: "#14191F" }, primary: { main: "#00838F" }, warn: { main: "#EB5757" }, text: { heading: "#555555", body : "#555555" } }, component: { checkbox: { main: { fill : "#FAFAFA", border: "#E0E0E0" }, hover: { fill: "#F5F5F5" } }, challenge: { main: { fill : "#FAFAFA", border: "#E0E0E0" }, hover: { fill: "#FAFAFA" } }, modal: { main: { fill : "#FFFFFF" }, hover: { fill: "#F5F5F5" }, focus: { outline: "#0074BF" } }, breadcrumb: { main: { fill: "#F5F5F5" }, active: { fill: "#00838F" } }, button: { main: { fill: "#FFFFFF", icon: "#555555", text: "#555555" }, hover: { fill: "#F5F5F5" }, focus: { icon : "#00838F", text : "#00838F", outline: "#0074BF" }, active: { fill: "#F5F5F5", icon: "#555555", text: "#555555" } }, link: { focus: { outline: "#0074BF" } }, list: { main: { fill : "#FFFFFF", border: "#D7D7D7" } }, listItem: { main: { fill: "#FFFFFF", line: "#F5F5F5", text: "#555555" }, hover: { fill: "#F5F5F5" }, selected: { fill: "#E0E0E0" }, focus: { outline: "#0074BF" } }, input: { main: { fill : "#FAFAFA", border: "#919191" }, focus: { fill : "#F5F5F5", border : "#333333", outline: "#0074BF" } }, field: { label: "#222222", input: { main: { border: "#D7D7D7", fill: "#FFFFFF", text: "#14191F" }, focus: { outline: "#00838F", fill: "#F5F5F5" }, error: { border: "#BF1722", text: "#BF1722" } } }, radio: { main: { file : "#F5F5F5", border: "#919191", check : "#F5F5F5" }, selected: { check: "#00838F" }, focus: { outline: "#0074BF" } }, task: { // Image shown in challenge to be answered main: { fill: "#F5F5F5" }, selected: { badge: "#00838F", outline: "#00838F" }, report: { badge: "#EB5757", outline: "#EB5757" }, details: { heading: '#222222', text: '#222222', }, focus: { badge: "#00838F", outline: "#00838F" } }, prompt: { main: { fill : "#00838F", border: "#00838F", text : "#FFFFFF" }, report: { fill : "#EB5757", border: "#EB5757", text : "#FFFFFF" } }, skipButton: { main: { fill : "#919191", border: "#919191", text : "#FFFFFF" }, hover: { fill : "#555555", border: "#919191", text : "#FFFFFF" }, focus: { outline: "#0074BF" } }, verifyButton: { main: { fill : "#00838F", border: "#00838F", text : "#FFFFFF" }, hover: { ``` -------------------------------- ### Local Development Hosts Entry Source: https://docs.hcaptcha.com/ Add a hosts entry to circumvent CORS/CORB issues and allow hCaptcha to function correctly during local development. This example uses 'test.mydomain.com'. ```bash 127.0.0.1 test.mydomain.com ``` -------------------------------- ### Enable and Render hCaptcha with Custom Theme Source: https://docs.hcaptcha.com/custom_themes Use this setup to enable custom themes for hCaptcha. Ensure the `custom=true` parameter is added to the script tag and provide a theme object to the `hcaptcha.render` function. ```html ``` -------------------------------- ### Load hCaptcha with French Localization Source: https://docs.hcaptcha.com/configuration Use query parameters to specify language. This example forces the hCaptcha widget to display in French. ```html ``` -------------------------------- ### Verify hCaptcha Token in Cloudflare Worker (Rust) Source: https://docs.hcaptcha.com/integrations Example of an hCaptcha verify endpoint using Cloudflare Workers written in Rust. ```rust use worker::*; #[event(fetch)] async fn main(req: Request, env: Env, _ctx: Context) -> Result { let token = req.json().await?["token"].as_str().unwrap().to_string(); let secret = env.secret("HCAPTCHA_SECRET")?.get(); let client = reqwest::Client::new(); let res = client.post("https://hcaptcha.com/siteverify") .form(&[ ("response", token), ("secret", secret) ]) .send() .await?; if res.status().is_success() { Response::ok("hCaptcha verified successfully!") } else { Response::error("hCaptcha verification failed.", 400) } } ``` -------------------------------- ### Configure hCaptcha Container with Attributes Source: https://docs.hcaptcha.com/configuration Set custom attributes on the hCaptcha container div for configuration. This example sets a dark theme and an error callback. ```html
``` -------------------------------- ### Render hCaptcha Widget Programmatically Source: https://docs.hcaptcha.com/configuration Use the hcaptcha.render() method to programmatically render the widget into a specified div. This example configures the sitekey, theme, and an error callback. ```javascript hcaptcha.render('your_div_id', // string: ID of target div to render into { sitekey: 'your_site_key', theme: 'dark', // (for example) 'error-callback': 'onError', // (for example) string: name of function }); ``` -------------------------------- ### Verify hCaptcha Token on Server Source: https://docs.hcaptcha.com/ This Python backend code demonstrates how to verify the hCaptcha token received from the frontend using the hCaptcha API. Ensure you have the 'requests' library installed. ```python import os import requests from flask import Flask, request, jsonify # URL for token verification HCAPTCHA_VERIFY_URL = "https://api.hcaptcha.com/siteverify" ``` -------------------------------- ### Test Key Set: Enterprise Account (Safe End User) Source: https://docs.hcaptcha.com/ For Enterprise customers, use this key set for testing. Ensure the `remoteip` field is sent to `siteverify` to enable all response fields. ```text Sitekey| `20000000-ffff-ffff-ffff-000000000002` Secret Key| `0x0000000000000000000000000000000000000000` Response Token| `20000000-aaaa-bbbb-cccc-000000000002` ``` -------------------------------- ### Test Key Set: Enterprise Account (Bot Detected) Source: https://docs.hcaptcha.com/ Use this Enterprise key set to test bot detection scenarios. Ensure the `remoteip` field is sent to `siteverify` to enable all response fields. ```text Sitekey| `30000000-ffff-ffff-ffff-000000000003` Secret Key| `0x0000000000000000000000000000000000000000` Response Token| `30000000-aaaa-bbbb-cccc-000000000003` ``` -------------------------------- ### Test Key Set: Publisher or Pro Account Source: https://docs.hcaptcha.com/ Use these test keys for automated integration tests. They always generate a passcode without a challenge and are verified with the provided test secret. ```text Sitekey| `10000000-ffff-ffff-ffff-000000000001` Secret Key| `0x0000000000000000000000000000000000000000` Response Token| `10000000-aaaa-bbbb-cccc-000000000001` ``` -------------------------------- ### Discover Doc Paths with Search Index Source: https://docs.hcaptcha.com/agent_skills This bash script, using Node.js for JSON parsing, retrieves relevant document paths from a local search index or by fetching it from a remote URL. It's designed for a fast path discovery of documentation relevant to a query. ```bash set -euo pipefail CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/hcaptcha-docs/public-search-index.json" INDEX="${HCAPTCHA_DOCS_SEARCH_INDEX:-}" QUERY="${1:-${HCAPTCHA_DOCS_QUERY:-siteverify}}" [ -s "${INDEX:-}" ] || INDEX="$(ls -1 ./search-index-*.json 2>/dev/null | head -n1 || true)" [ -s "${INDEX:-}" ] || INDEX="$CACHE" if [ ! -s "$INDEX" ]; then mkdir -p "$(dirname "$CACHE")" ID="$(curl -fsSL https://docs.hcaptcha.com/llm/search-cache-id.txt | tr -d '\r\n')" curl -fsSL "https://docs.hcaptcha.com/search-index-${ID}.json" > "$CACHE" INDEX="$CACHE" fi node - <<'NODE' "$INDEX" "$QUERY" const fs=require("fs"),[p,q]=process.argv.slice(2),needle=q.toLowerCase();let n=0,seen=new Set(); for(const b of JSON.parse(fs.readFileSync(p,"utf8"))){ for(const d of b.documents||[]){ const h=[d.t,d.s,d.u,...(d.b||[])].filter(Boolean).join(" ").toLowerCase(); if(h.includes(needle)&&!seen.has(d.u)){seen.add(d.u);console.log(`${d.t}\t${d.u}`);if(++n>=20)process.exit(0);} } } NODE ``` -------------------------------- ### Backend Testing: Rejected Tokens Source: https://docs.hcaptcha.com/ Test how your backend handles invalid or expired tokens by sending a nonsense string like 'FAKE-TOKEN' to the `siteverify` endpoint. ```text FAKE-TOKEN ``` -------------------------------- ### Customize hCaptcha Theme with Palette and Components Source: https://docs.hcaptcha.com/custom_themes Create a comprehensive custom theme by defining both palette colors and individual component styles. This allows for detailed control over the widget's appearance. ```javascript var subtleDarkTheme = { palette: { mode: "dark", grey: { 100: "#FAFAFA", 200: "#F5F5F5", 300: "#E0E0E0", 400: "#D7D7D7", 500: "#BFBFBF", 600: "#919191", 700: "#787878", 800: "#5E5E5E", 900: "#444444", 1000: "#2A2A2A" }, primary: { main: "#607D8B" }, warn: { main: "#FF5722" }, text: { heading: "#F5F5F5", body: "#E0E0E0" } }, component: { checkbox: { main: { fill: "#424242", border: "#616161" }, }, input: { main: { fill: "#424242", border: "#616161" }, focus: { fill: "#555555", border: "#6A6A6A", outline: "#607D8B" } }, challenge: { main: { fill: "#303030", border: "#424242" }, hover: { fill: "#383838" } }, button: { main: { fill: "#424242", icon: "#F5F5F5", text: "#F5F5F5" }, hover: { fill: "#555555" }, focus: { icon: "#607D8B", text: "#607D8B", outline: "#607D8B" }, active: { fill: "#555555", icon: "#F5F5F5", text: "#F5F5F5" } }, modal: { main: { fill: "#222222" }, hover: { fill: "#303030" }, focus: { outline: "#607D8B" } } } }; ``` -------------------------------- ### Load hCaptcha with Multiple Query Parameters Source: https://docs.hcaptcha.com/configuration Combine multiple query parameters to customize loading behavior, such as language, callback function, and rendering mode. ```html ``` -------------------------------- ### Customize hCaptcha Theme with Palette Source: https://docs.hcaptcha.com/custom_themes Define a custom theme by specifying palette colors. Use this for basic color adjustments. ```javascript var vibrantTheme = { palette: { mode: "light", grey: { 100: "#FAFAFA", 200: "#F5F5F5", 300: "#E0E0E0", 400: "#D7D7D7", 500: "#BFBFBF", 600: "#919191", 700: "#555555", 800: "#333333", 900: "#222222", 1000: "#14191F" }, primary: { main: "#FF5722" }, warn: { main: "#F44336" }, text: { heading: "#212121", body: "#212121" } }, }; ``` -------------------------------- ### Theme Color Definitions Source: https://docs.hcaptcha.com/custom_themes This JSON object defines the color palette for custom themes, including specific colors for fill, border, and text in various states such as main, hover, focus, and disabled. ```json { "widget": { "fill": "#00838F", "border": "#00838F", "text": "#FFFFFF" }, "focus": { "outline": "#0074BF" }, "disabled": { "fill": "#919191", "border": "#919191", "text": "#FFFFFF" } }, MFAButton: { main: { fill: "#00838F", border: "#00838F", text: "#FFFFFF" }, hover: { fill: "#00838F", border: "#00838F", text: "#FFFFFF" }, focus: { outline: "#0074BF" } }, slider: { main: { bar: "#C4C4C4", handle: "#0F8390" }, focus: { handle: "#0F8390" } }, textarea: { main: { fill: "#C4C4C4", border: "#919191" }, focus: { fill: "#C4C4C4", outline: "#0074BF" }, disabled: { fill: "#919191" } } } ``` -------------------------------- ### Asynchronous mode with hcaptcha.execute() Source: https://docs.hcaptcha.com/configuration Execute hCaptcha challenges asynchronously, returning a Promise that resolves with the token and response key upon success or rejects with an error code. ```APIDOC ## Asynchronous mode (Get a Promise) Optionally, you can pass `{ async: true }` to `hcaptcha.execute()` in order to get a promise back. ### Response - Upon successful completion of the challenge, it will resolve with an object containing the token and the response key. - In case of an error, it will reject with an appropriate error code. - It will not inform you about expired tokens, as the promise will have already resolved with the token in this scenario. To handle this case you will still need to specify the `expired-callback` callback. ### Request Example ```javascript hcaptcha.execute(widgetID, { async: true }) .then(({ response, key }) => { console.log(response, key); }) .catch(err => { console.error(err); }); ``` ``` -------------------------------- ### HTML and CSS for Floating hCaptcha Badge Source: https://docs.hcaptcha.com/invisible Use this HTML and CSS to create a floating badge that remains visible on the screen. It includes styles for the badge itself and a hidden popup that can be displayed on interaction. ```html hCaptcha Floating Overlay Image Example
hCaptcha Execute Example



``` -------------------------------- ### Load hCaptcha with Explicit Rendering Source: https://docs.hcaptcha.com/configuration Use this script tag to load the hCaptcha API with explicit rendering enabled. Specify your custom onload callback function and set render to explicit. ```html ``` -------------------------------- ### Render hCaptcha Widget Source: https://docs.hcaptcha.com/configuration Renders the hCaptcha widget into a specified DOM element. Use 'hl' to enforce a language. Defaults to auto-detection. ```javascript { "sitekey": "your_site_key", "theme": "dark", "size": "compact", "hl": "fr" } ``` -------------------------------- ### Verify hCaptcha Token with cURL Source: https://docs.hcaptcha.com/ Use this cURL command to send a POST request to the hCaptcha siteverify API endpoint. Include your secret key, the client's IP address, and the response token for verification. ```bash curl https://api.hcaptcha.com/siteverify \ -X POST \ -d "secret=YOUR-SECRET&remoteip=CLIENT-IP&response=CLIENT-RESPONSE" ``` -------------------------------- ### hCaptcha Public Docs Skill Configuration Source: https://docs.hcaptcha.com/agent_skills This YAML configuration defines the 'hcaptcha-public-docs' skill, specifying its purpose, invocation methods, URL mappings, scope limitations, and retrieval workflow for accessing public hCaptcha documentation. ```yaml --- name: hcaptcha-public-docs description: Reads and cites public hCaptcha docs from docs.hcaptcha.com LLM markdown endpoints with local search-index discovery. Use for non-Enterprise integration, configuration, API, SDK, migration, and troubleshooting requests. If a request is Enterprise-only, hand off to hcaptcha-enterprise-docs. --- # hCaptcha Public Docs Skill Use this workflow for any task that needs authoritative hCaptcha public docs context. ## Invocation - Codex explicit: `/skills` then select `$hcaptcha-public-docs` - Codex implicit: allow description matching - Claude Code install locations: - project: `.claude/skills/hcaptcha-public-docs/SKILL.md` - personal: `~/.claude/skills/hcaptcha-public-docs/SKILL.md` - Claude Code explicit: `/hcaptcha-public-docs` ## URL mapping - `https://docs.hcaptcha.com/` -> `https://docs.hcaptcha.com/llm/index.md` - `https://docs.hcaptcha.com/` -> `https://docs.hcaptcha.com/llm/.md` ## Scope guardrails - This skill is public-docs only. - Do not answer Enterprise-only topics from this skill. - Enterprise-only signals include: APT Mitigation, Reporting APIs, Private Learning, enterprise management APIs, or `/enterprise/...` docs. - If Enterprise-only, reply with handoff: - `Use $hcaptcha-enterprise-docs (https://docs.hcaptcha.com/enterprise/agent_skills).` ## Retrieval workflow Search cache ID endpoint: - `https://docs.hcaptcha.com/llm/search-cache-id.txt` 1. Discover relevant doc paths from the search index first (fast path): ```bash set -euo pipefail CACHE="${XDG_CACHE_HOME:-$HOME/.cache}/hcaptcha-docs/public-search-index.json" INDEX="${HCAPTCHA_DOCS_SEARCH_INDEX:-}" QUERY="${1:-${HCAPTCHA_DOCS_QUERY:-siteverify}}" [ -s "${INDEX:-}" ] || INDEX="$(ls -1 ./search-index-*.json 2>/dev/null | head -n1 || true)" [ -s "${INDEX:-}" ] || INDEX="$CACHE" if [ ! -s "$INDEX" ]; then mkdir -p "$(dirname "$CACHE")" ID="$(curl -fsSL https://docs.hcaptcha.com/llm/search-cache-id.txt | tr -d '\r\n')" curl -fsSL "https://docs.hcaptcha.com/search-index-${ID}.json" > "$CACHE" INDEX="$CACHE" fi node - <<'NODE' "$INDEX" "$QUERY" const fs=require("fs"),[p,q]=process.argv.slice(2),needle=q.toLowerCase();let n=0,seen=new Set(); for(const b of JSON.parse(fs.readFileSync(p,"utf8"))){ for(const d of b.documents||[]){ const h=[d.t,d.s,d.u,...(d.b||[])].filter(Boolean).join(" ").toLowerCase(); if(h.includes(needle)&&!seen.has(d.u)){seen.add(d.u);console.log(`${d.t}\t${d.u}`);if(++n>=20)process.exit(0);} } } NODE ``` 2. Fetch only the matching markdown pages under `https://docs.hcaptcha.com/llm/*.md`. 3. For broad requests, read `https://docs.hcaptcha.com/llm/index.md` first. 4. Cite source URLs used in the final answer. 5. Never cite local file paths as sources; cite only docs URLs. ## Enterprise handoff If the request needs Enterprise-only docs or features, switch to: `$hcaptcha-enterprise-docs` at `https://docs.hcaptcha.com/enterprise/agent_skills` (requires Enterprise API key setup) ## Fallback If search index discovery is unavailable, fetch the most relevant `/llm/...` markdown pages directly, cache them locally, and search that local cache with `rg` (or your preferred grep-like tool). ``` -------------------------------- ### Pseudo-code for Server-Side Verification Source: https://docs.hcaptcha.com/ This pseudo-code outlines the steps to verify an hCaptcha token on your server. It includes retrieving the token from POST data, constructing the payload, and making a POST request to the verification endpoint. ```pseudocode # PSEUDO CODE SECRET_KEY = "your_secret_key" # replace with your secret key VERIFY_URL = "https://api.hcaptcha.com/siteverify" # Retrieve token from post data with key 'h-captcha-response'. token = request.POST_DATA['h-captcha-response'] # Build payload with secret key and token. data = { 'secret': SECRET_KEY, 'response': token } # Make POST request with data payload to hCaptcha API endpoint. response = http.post(url=VERIFY_URL, data=data) ```