caputchin
All docs
View raw .md

Quickstart

The fastest path from "I just made an account" to "my form is protected". You need a page with a <form> and a backend that can make an outbound HTTP call. No build step required.

By the end of this guide your form submission will only accept entries from a verified human.

1. Get a site key

Sign in to the dashboard and create a new site. You will receive two values:

Value Where it lives Shape
Public site key Embed in the page HTML cpt_pub_...
Secret Server-side only; never ship to the browser cpt_sec_...

Save the secret somewhere your backend can read it — environment variable, secrets manager, whatever you already use.

2. Drop the widget into your form

Paste these two lines into the page that hosts the form you want to protect:

<script src="https://cdn.jsdelivr.net/npm/@caputchin/widget@1/dist/widget.js"></script>

<form action="/submit" method="POST">
  <!-- your existing form fields -->
  <input name="email" type="email" required />

  <caputchin-widget sitekey="cpt_pub_..."></caputchin-widget>

  <button type="submit">Sign up</button>
</form>

On successful completion the widget injects a hidden <input name="caputchin-token"> into the enclosing <form>. Nothing else on your page needs to change.

If you want a game challenge instead of the invisible default, add the game attribute. See widget for the full attribute table.

3. Verify on your backend

When the form posts to /submit, your handler receives one extra field: caputchin-token. Pass it to /siteverify along with your secret:

// Node 18+
app.post("/submit", async (req, res) => {
  const verdict = await fetch("https://api.caputchin.com/api/v1/siteverify", {
    method: "POST",
    headers: { "content-type": "application/json" },
    body: JSON.stringify({
      secret: process.env.CAPUTCHIN_SECRET,
      response: req.body["caputchin-token"],
    }),
  }).then((r) => r.json());

  if (!verdict.success) {
    return res.status(400).json({ error: verdict["error-codes"] });
  }

  // Verified — continue your normal sign-up flow.
});

Snippets for Python, Go, PHP, and curl are in snippets.

4. Submit the form

Open the page, fill in the form, complete the widget challenge (or wait for the invisible flow), and hit submit. Your backend should log a successful verification.

If something is wrong, the response carries an error-codes array. The full mapping is in troubleshooting.

What just happened

Step Where What it does
Widget mounts Browser Loads the challenge surface inside a sandboxed iframe
User completes the challenge Browser Proof-of-work runs in the iframe, isolated from your page
Widget injects caputchin-token Browser One-time token, single-use, expires after 10 minutes
Your form posts Backend Token rides along with the rest of the form fields
/siteverify Server-to-server Caputchin checks the token, returns success: true or an error code

Next steps