Variants
Visible widget with text, checkbox, loading state, result label, and optional branding.
Small fixed-size protection indicator for forms that should solve in the background.
No visible UI. Use load, interaction, or programmatic solving before submit.
Triggers
| click | Default. The challenge starts when the visitor clicks the widget. |
|---|---|
| interaction | The challenge starts after the first meaningful form interaction such as focus, input, change, or blur. |
| load | The challenge starts once after render. Expiration re-arms interaction solving. |
| programmatic | Leave the trigger as click or interaction and call solve() directly from your JavaScript flow. |
Widget states
The element exposes its current lifecycle through data-state. Use it for styling, diagnostics, or tests, but keep server-side verification as the security decision.
| State | Meaning | Typical UI |
|---|---|---|
| idle | Ready to start or retry. | Initial label and enabled button. |
| solving | The challenge is running. | Spinner or compact pulse indicator. |
| solved | A token was issued and written to the hidden field. | Success label, checkmark, and disabled widget button. |
| error | The challenge could not complete or the request was blocked. | Error label and retryable widget button. |
Widget error responses
These errors can appear through the widget error event or as error values from the public challenge and redeem endpoints. They should be shown as retry or support states in the browser, while your server still relies on siteverify.
| Error | Status | Meaning |
|---|---|---|
| billing_past_due | 402 | The organization is outside the billing grace period. |
| plan_limit_exceeded | 402 | The monthly protected attempt limit has been reached. |
| widget_variant_not_allowed | 402 | The selected widget variant is not available on the current plan. |
| unbranded_widget_not_allowed | 402 | data-branding="none" is not available on the current plan. |
| domain_not_allowed | 403 | The browser origin is not configured as a production or testing domain. |
| risk_blocked | 403 | Risk enforcement blocked the request before the challenge backend was called. |
| challenge_unavailable | 502 | HumanProof could not reach the challenge service. |
| test_key_not_configured | 422 | Public test keys are not configured in this environment. |
Events
Listen for solve, error, reset, expired, and progress to control submit buttons and form labels.
Compatibility
The public custom element is human-proof. Use this element name for all new integrations.