How do you integrate hCaptcha with Rust?#
Render the official hCaptcha widget in the form, read h-captcha-response in the server handler, and verify that token before the protected action runs. The hCaptcha catalog links the community hcaptcha crate, which provides typed requests, expected-sitekey binding, and a reusable asynchronous verification client.
This guide uses the community hcaptcha crate with an application-enforced timeout and fail-closed error handling.
These instructions were last validated on September 22, 2026 with hcaptcha crate 3.2.6 and Rust 1.88.
Reduce CAPTCHA friction on Rust-backed forms#
- Keep visitors focused on their task. hCaptcha Pro's 99.9% Passive mode challenges fewer than 0.1% of legitimate users, reducing interruptions on the browser form protected by your Rust handler.
- Apply verification in proportion to risk. Pro increases challenge difficulty for suspicious interactions, helping ordinary visitors complete their forms with less friction while retaining stronger checks against abuse.
New Pro sitekeys use 99.9% Passive by default. For an existing sitekey upgraded to Pro, select that mode under Behavior in the hCaptcha dashboard.
Before you start#
You need:
- A Rust POST handler and HTML form to protect.
- An asynchronous runtime supported by the surrounding web application.
- An hCaptcha account with a sitekey and matching secret.
- An outbound HTTPS path from the Rust service to hCaptcha.
Review the hCaptcha Rust catalog entry, the crate's documentation, its source repository, and the server verification contract.
Create your hCaptcha credentials#
- Start with hCaptcha Pro for fewer challenges and adaptive protection on forms protected by your Rust handler, or use existing compatible hCaptcha credentials.
- Create a sitekey and allow every hostname that will render the widget.
- Store the secret in the deployment environment or secret manager.
- Expose only the public sitekey to the HTML template.
Never place the secret in HTML, browser JavaScript, committed configuration, logs, or error responses.
Install and configure the Rust crate#
Add the current published crate to Cargo.toml:
[dependencies]
hcaptcha = "3.2.6"
tokio = { version = "1", features = ["time"] }
The crate defaults to a rustls TLS backend. Do not enable its optional trace feature for production verification until its logging behavior is reviewed.
Load the credentials during application startup:
let sitekey = std::env::var("HCAPTCHA_SITEKEY")
.expect("HCAPTCHA_SITEKEY is required");
let secret = std::env::var("HCAPTCHA_SECRET")
.expect("HCAPTCHA_SECRET is required");
Pass the sitekey to the template and retain the secret in server state.
Add the widget to the Rust template#
Place the widget inside the protected form and preserve the application's existing CSRF protection.
<form method="post" action="/signup">
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
<!-- Application fields go here. -->
<div class="h-captcha" data-sitekey="{{ hcaptcha_sitekey }}"></div>
<button type="submit">Create account</button>
</form>
<script src="https://js.hcaptcha.com/1/api.js" async defer></script>
Adapt the template expressions and CSRF field to the selected Rust framework. Confirm Content Security Policy allows the hCaptcha resources required by the deployment.
Verify the response with hcaptcha-rs#
Create one Client during application startup and reuse it through shared server state. Build each request with the server-held secret, submitted token, and expected sitekey:
use std::time::Duration;
use hcaptcha::{Client, Request};
async fn verify_hcaptcha(
client: &Client,
secret: &str,
sitekey: &str,
token: &str,
) -> bool {
if token.is_empty() {
return false;
}
let request = match Request::new_from_response(secret, token)
.and_then(|request| request.set_sitekey(sitekey))
{
Ok(request) => request,
Err(_) => return false,
};
matches!(
tokio::time::timeout(
Duration::from_secs(5),
client.verify_request(request),
)
.await,
Ok(Ok(response)) if response.success()
)
}
Treat request construction, timeout, transport, decoding, and verification errors as failed verification. Do not log the token, secret, request, or complete response. The remoteip parameter is optional. We recommend sending it for improved verification accuracy and Enterprise risk scores when the framework derives the visitor's IP address from a reviewed, trusted proxy configuration; otherwise omit it.
Gate the protected handler#
The framework-specific handler should follow this sequence:
- Enforce the expected HTTP method and request-size limit.
- Apply the application's CSRF protection and validate its other form fields.
- Extract
h-captcha-responsefrom the submitted form. - Call
verify_hcaptchawith the shared client and server credentials. - Run database writes, messages, payments, or other side effects only after verification succeeds.
Return a form error when verification fails. Tokens are short-lived and single-use, so render or reset the challenge before another submission.
Review the crate's implementation details#
The hcaptcha-rs repository is actively maintained. The crate provides a default rustls backend, an optional native TLS backend, expected sitekey, optional remoteip, reusable clients, and an enterprise feature that exposes Enterprise response fields.
These features make the crate a useful option for compatible Rust applications. Its source sends requests to https://hcaptcha.com/siteverify; our current server-verification documentation specifies https://api.hcaptcha.com/siteverify for new integrations. Use a reviewed crate update or a small direct verifier when endpoint control is required. The crate constructs its internal reqwest client without an application-supplied builder; the wrapper above adds an application deadline around verification but does not change the endpoint used by the crate.
The optional trace feature logs the serialized form submitted to Siteverify. That form contains the secret despite crate documentation stating that the secret is not logged. Keep trace disabled for this path and complete a source review before enabling it.
Test the Rust integration#
- Confirm a valid token permits the protected action exactly once.
- Reject missing, invalid, expired, reused, and wrong-sitekey tokens.
- Reject timeouts, connection failures, invalid responses, and unsuccessful verification.
- Confirm the secret never appears in rendered HTML, browser requests, logs, traces, or error responses.
- Test every allowed hostname, CSRF handling, CSP, accessibility, and keyboard behavior.
- Test the exact framework extractors, runtime, TLS feature set, and deployment proxy.
Troubleshoot common Rust problems#
Request construction returns an error
Check that the secret, token, and sitekey are present and use the expected hCaptcha formats. Return a form error without echoing the rejected values.
Verification times out
Confirm the service can reach the verification endpoint over HTTPS. Keep a finite application deadline and fail closed when the deadline expires.
The crate does not compile with the project toolchain
Confirm that the project's Rust toolchain satisfies the crate's current minimum version.
Frequently asked questions#
Is hcaptcha-rs maintained by hCaptcha?
No. It is a community crate linked from our integration catalog.
Does the crate support the expected sitekey?
Yes. Call set_sitekey when constructing the verification request so the response must match the configured widget.
Should I enable the trace feature?
No for this integration as currently reviewed. The feature logs the serialized verification form, which contains the secret.
Can I use the crate with Axum, Actix Web, or Rocket?
Yes, if the framework can extract the submitted token and call the asynchronous verifier. The form extraction, shared state, CSRF, and response code details remain framework-specific.
Should I send the user's IP address?
remoteip is optional. We recommend it for improved verification accuracy and Enterprise risk scores. Send it only when the deployment has a reviewed trusted-proxy configuration and a clear reason to send the visitor's IP address; otherwise omit it.
Sources and references
- hCaptcha Pro product overview hCaptcha
- hCaptcha integrations — Rust hCaptcha
- Verify the hCaptcha response server-side hCaptcha
- hcaptcha crate crates.io
- hcaptcha crate documentation docs.rs
- hcaptcha-rs source jerus-org
- Rust release notes The Rust Project Developers
- hCaptcha Pro hCaptcha
- hCaptcha integrations list source hCaptcha