---
type: tutorial
title: Verifizierung selbst treiben mit dem manuellen Modus
summary: Der manuelle Modus lässt deinen eigenen Code den Verifizierungs-Lebenszyklus treiben. Er existiert auf zwei Elementen (dem Checkbox-Widget und dem Spiel-Host) mit verschiedenen Aufgaben; diese Seite baut beide und zeigt, wann man welches nutzt.
---

Am Ende dieses Tutorials hast du den Caputchin-Verifizierungs-Lebenszyklus aus deinem eigenen Code getrieben statt aus der eingebauten UI, auf demjenigen der zwei Elemente, das zu deinem Fall passt. **Manueller Modus** (`trigger="manual"`) existiert auf zwei verschiedenen Elementen, und sie tun wirklich verschiedene Aufgaben:

| Element | Was der manuelle Modus dir gibt | Du treibst |
|---|---|---|
| `<caputchin-widget>` | Die eingebaute Checkbox ist verborgen; du feuerst die Proof-of-Work-Lösung aus deinem **eigenen Auslöser** (ein Formular-Submit, ein eigener Button). Kein Spiel. | `start()` (dann löst sich die Lösung meist selbst) |
| `<caputchin-game>` | Kein Iframe; du slotst **dein eigenes Spiel-Markup** in die Layout-Hülle des Widgets und entscheidest das Ergebnis aus dem Gameplay. | `pass()` / `fail()` (kein `start()`; die Runde ist beim Mount live) |

Wähl nach der Frage, die du beantwortest:

- *"Ich will die normale unsichtbare/Checkbox-Verifizierung, aber ausgelöst durch meine eigene Geste und ohne die Standard-Checkbox."* → das **Checkbox-Widget**, unten.
- *"Ich will meine eigene interaktive Aufgabe in meinem eigenen DOM gerendert, kein Iframe-Spiel, und ich entscheide bestanden/nicht."* → der **Spiel-Host**, unten.

Lies [dein eigenes Spiel betreiben](/docs/custom-game-development/overview) dafür, wo der Spiel-Weg hineinpasst. Du brauchst das Widget schon auf deiner Seite; wenn nicht, mach zuerst [das Widget hinzufügen](/docs/getting-started/add-the-widget).

Eine von beiden geteilte Grenze: eine Runde im manuellen Modus **kann kein [Spiel-Gate](/docs/site-keys/games) erfüllen**. Das Checkbox-Element gatet einen Key nie überhaupt (nur `<caputchin-game>` kann), und eine manuelle `<caputchin-game>`-Runde hat keinen abspielbaren Trace, also weist ein gegateter Key sie ab. Der manuelle Modus ist für ungegatete Keys (Proof-of-Work-Verifizierung) oder nur-Spiel-Nutzung.

## Weg A: das Checkbox-Widget, dein eigener Auslöser

Nimm das, wenn du die Standard-Verifizierung willst, sie aber selbst feuern willst, zum Beispiel um die Lösung nur zu laufen, wenn der Besucher ein Formular absendet, oder hinter deinem eigenen Button statt der eingebauten Checkbox.

### 1. Das Element manuell markieren

```html
<caputchin-widget id="cap" sitekey="cpt_pub_..." trigger="manual"></caputchin-widget>
<button id="go" type="button">Verify and continue</button>
```

Mit `trigger="manual"` ist die eingebaute Checkbox-UI verborgen; das Element wartet darauf, dass du die Lösung startest.

### 2. Die Lösung aus deiner Geste starten

Das Checkbox-Element im manuellen Modus stellt eine einzelne Methode bereit, `start()`:

- `start()` stößt die Proof-of-Work-Lösung an und ersetzt den Checkbox-Klick. Gültig mit `trigger="manual"`.

Das Checkbox-Widget hat kein `pass()` / `fail()`; sobald du `start()` aufrufst, löst sich die Lösung von selbst und emittiert das `pass`-Event. (Die Release-/Abort-Handles leben auf dem Spiel-Host, behandelt in Weg B.)

```js
const widget = document.getElementById("cap");

document.getElementById("go").addEventListener("click", () => {
  widget.start(); // begin verification now
});

widget.addEventListener("pass", () => {
  // token issued; submit your form / continue
});
```

Wenn die Lösung sich auflöst, schließt das Element die Verifizierung ab und (in einem Formular) fügt das `caputchin-token`-Feld wie jedes andere Widget ein. Dein Backend [verifiziert dieses Token](/docs/integration-guides/verify-on-your-backend) genau wie üblich; der manuelle Modus ändert serverseitig nichts.

## Weg B: der Spiel-Host, dein eigenes DOM

Nimm das, wenn du deine eigene interaktive Aufgabe in deinem eigenen Markup rendern willst, statt ein Iframe-Spiel zu laden, und das Ergebnis selbst entscheidest.

### 1. Das Element manuell markieren und dein Markup slotten

Setz `trigger="manual"` auf `<caputchin-game>` und platzier dein eigenes Markup darin. In jedem anderen Modus ignoriert das Widget Light-DOM-Kinder; der manuelle Modus ist der eine Modus, in dem es sie durch einen `<slot>` in seine Layout-Hülle projiziert.

```html
<caputchin-game id="cap" sitekey="cpt_pub_..." trigger="manual">
  <!-- Your own markup. The widget renders it inside its shell. -->
  <div id="my-game">
    <p>Tap the banana three times.</p>
    <button id="banana" type="button">🍌</button>
  </div>
</caputchin-game>
```

Mit vorhandenem Sitekey und nicht-gegatetem Key läuft das Widget seine Proof-of-Work-Prüfung im Hintergrund; deine Interaktion ist der sichtbare Teil. Ohne Sitekey (oder mit `no-verify`) ist es nur-Spiel: deine Interaktion läuft, ohne dass etwas zu verifizieren ist.

### 2. Das Ergebnis aus deinem Code treiben

Der Spiel-Host im manuellen Modus stellt `pass()` und `fail()` bereit. Es gibt **kein `start()`**: die Runde ist live, sobald das Element mountet (dass die Factory gemountet wird, ist das Startsignal).

- `pass(payload?)` gibt die Verifizierung frei: der Besucher war erfolgreich. Ruf es einmal; spätere Aufrufe werden ignoriert (das Urteil ist gesperrt).
- `fail(payload?)` bricht die Runde ab. Optional; eine unfertige Runde wird ohnehin als Nicht-Pass behandelt.

Die Payloads:

- `pass({ trace })`: `trace` ist der opake Runden-Datensatz, den deine Interaktion produziert. Auf einer gegateten Runde spielt der Server ihn fürs Urteil ab; auf einem ungegateten oder nur-Spiel-Key wird er wie er ist akzeptiert, also übergib einen leeren String (oder einen einfachen Marker), wenn es nichts abzuspielen gibt. Es gibt hier keine vom Client gelieferte Punktzahl.
- `fail({ code?, message? })`: ein optionaler Diagnose-`code` und eine `message`, beide Client-Metadaten, nie ein Vertrauenssignal.

```js
const widget = document.getElementById("cap");
let taps = 0;

document.getElementById("banana").addEventListener("click", () => {
  taps += 1;
  if (taps >= 3) {
    widget.pass({ trace: `banana:${taps}` }); // visitor won
  }
});

// Optional: give up explicitly.
// widget.fail({ code: "gave-up", message: "closed the prompt" });
```

Wie beim Checkbox-Weg schließt `pass()` die Verifizierung ab und fügt das Token ein; dein Backend verifiziert es auf dieselbe Weise.

## Auf das Ergebnis reagieren (beide Wege)

Lausch auf die Events des Widgets, um deine eigene UI zu aktualisieren:

```js
widget.addEventListener("pass", () => {
  // verification released
});
widget.addEventListener("error", (e) => {
  console.warn("verification error", e.detail);
});
```

Die Vertrauensentscheidung ist immer, dass dein Backend das Token bestätigt, nicht das Event; das Event ist für UX.

## Was der manuelle Modus nicht kann

- **Einen Site-Key gaten.** Ein Key mit eingeschaltetem [ein Spiel verlangen](/docs/site-keys/games) kann vom Checkbox-Element überhaupt nicht erfüllt werden und weist eine manuelle `<caputchin-game>` ab (sie wirft beim Setup einen Konfigurationsfehler), weil es keinen abspielbaren Trace gibt. Der manuelle Modus ist für ungegatete oder nur-Spiel-Keys.
- **Die Runde eines Custom-Spiels abspielen.** Brauchst du ein Spiel, das gatet, render es als [selbst gehostetes Iframe-Spiel](/docs/custom-game-development/self-hosted-game) und produzier einen Trace, nicht den manuellen Modus.

## Siehe auch

- [Widget-Methoden und -Events](/docs/references/widget-methods-and-events): die vollständige Referenz für `start()` / `pass()` / `fail()` und jedes Event, das sie emittieren.
- [Selbst gehostetes Iframe-Spiel](/docs/custom-game-development/self-hosted-game): ein gesandboxtes, abspielbares Spiel, das gaten kann.
- [Dein eigenes Spiel betreiben](/docs/custom-game-development/overview): die zwei Auslieferungs-Modi verglichen.
- [Auf deinem Backend verifizieren](/docs/integration-guides/verify-on-your-backend): das Token bestätigen, das ein Pass produziert.
