---
type: how-to
---

# Set up hosted verification

For customers without a backend. Caputchin verifies the form submission and forwards it to a webhook, an email address, or both. Paid tier only — see [hosted-verification](../hosted-verification.md) for the feature overview and [ADR-0007](../adr/0007-hosted-verification-paid-only.md) for why.

This guide assumes you already have a paid Caputchin account and a site key. For free-tier integration where you call `/siteverify` from your own backend, see [verify-server-side](verify-server-side.md) instead.

## 1. Enable hosted verification on the site key

In the [dashboard](../dashboard.md#paid-tier-surfaces), open the site key, find the **Hosted verification** section, and toggle it on.

## 2. Configure where submissions go

Add at least one destination. You can enable both at the same time.

- **Webhook.** Provide a URL on your side that accepts `POST` requests. The dashboard issues a webhook signing key — store it; you'll use it to verify incoming requests.
- **Email.** Provide an email address. Submissions arrive as plain emails with the form fields and a footer noting Caputchin verified them.

## 3. Point your form at the Caputchin URL

The dashboard shows a forwarder URL specific to the site key. Set it as your form's `action`.

```html
<form action="https://forward.caputchin.com/<your-forwarder-id>" method="POST">
  <input name="email">
  <input name="message">
  <caputchin-widget sitekey="cpt_pub_..." game="bubble-pop"></caputchin-widget>
  <button>Submit</button>
</form>
```

Nothing else changes. The `<caputchin-widget>` element still injects the hidden `caputchin-token` field on completion; the difference is where the form posts.

## 4. Handle the webhook (if you configured one)

Your handler receives a signed `POST` carrying the form payload plus verification metadata. Verify the signature using the signing key from step 2 before trusting the payload.

The exact signature scheme and payload shape are documented alongside the dashboard signing-key UI when you enable the destination.

## 5. Test it

Submit the form once. The widget completes a game, the form posts to the forwarder, and:

- Webhook destinations receive the signed request.
- Email destinations receive an email.

If the submission is rejected (verification failed, rate limit hit, destination unreachable), the forwarder responds with a non-2xx status the browser surfaces.

## What the forwarder does and doesn't do

See [hosted-verification — what is intentionally absent](../hosted-verification.md#what-is-intentionally-absent) for the full list. The shortest version: no submission storage, no analytics on submitters, no first-party adapters beyond webhook + email.

## Rate limits

Limits are set per pricing tier and not customer-configurable. If your traffic legitimately needs higher limits, contact support — we'd rather adjust your tier than have you fight defaults.
