Crate hcaptcha

source ·
Expand description


§Build the request and verify

Build the request using the Hcaptcha builder.

Execute verify on the request once to execute.

Following a successful response the additional response in can be requested from the Hcaptcha struct.


Token needs to be supplied by the client. This example will fail as a client-provided token is not used.

    use hcaptcha::{HcaptchaClient, HcaptchaRequest};

    let request = HcaptchaRequest::new(&secret, captcha)?

    let client = HcaptchaClient::new();

    let response = client.verify_client_response(request).await?;

    let score = match &response.score() {
        Some(v) => *v,
        None => 0.0,
    let score_reasons = match &response.score_reason() {
        Some(v) => v.iter().join(", "),
        None => "".to_owned(),
    println!("\tScore: {:?}\n\tReasons: {:?}", score, score_reasons);

Lambda backend implementation. See examples for more detail.

mod handler {

    pub async fn my_handler(e: CustomEvent, _c: Context) -> Result<CustomOutput,  Error> {
        debug!("The event logged is: {:?}", e);

        let body_str = e.body.unwrap_or_else(|| "".to_owned());
        let captcha: HcaptchaCaptcha = serde_json::from_str(&body_str)?;

        let hcaptcha_secret = param::get_parameter(HCAPTCHA_SECRET).await?;

        let request = HcaptchaRequest::new(&hcaptcha_secret,
        let client = HcaptchaClient::new();
        let _response = client.verify_client_response(request).await?;

        let contact_form: ContactForm = serde_json::from_str(&body_str)?;

        let notify_office_fut = send::notify_office(&contact_form);
        let notify_contact_fut = send::notify_contact(&contact_form);
        let write_fut = record::write(&contact_form);

        let (notify_office, notify_contact, write) =
            join!(notify_office_fut, notify_contact_fut, write_fut);

        if let Err(e) = notify_contact {
            error!("Notification to the contact not sent: {}", e);
            return Err("Notification not sent".into());

        if let Err(e) = notify_office {
            error!("Notification to the office not sent: {}", e);
            return Err("Info not sent to office".into());

        if let Err(e) = write {
            error!("Contact information not written to database: {}", e);

            format!("{}, thank you for your contact request.",,

async fn main() -> Result<(), Error> {


§Feature Flags

The default library includes extended validation for the secret field and use of native TLS as the TLS backend Disable this validation by setting default-features = false and to enable rustls features=[“rustls”]

hcaptcha = { version = "2.3.1", default-features = false }

The following feature flags are available:

  • enterprise - Enable methods to access enterprise service fields in the HcaptchaResponse
  • ext - Enables extended validation of secret
  • trace - Enables tracing instrumentation on all functions. Traces are logged at the debug level. The value of the secret is not logged.
  • nativetls-backend - Enables native-tls backend in reqwests
  • rustls-backend - Enables rustls backend in reqwests

§Rust Version

This version of hcaptcha requires Rust v1.71 or later.



  • Error code mapping for the error responses from the hcaptcha API. Returned in the HcaptchaError type.
  • The error type for hcaptcha. Provides error types to capture error codes from the Hcaptcha API and errors output from crates used by the library.


  • Endpoint url for the Hcaptcha siteverify API.


Derive Macros§

  • Derive the Hcaptcha trait for a struct.