---
type: reference
title: Widget-Methoden und -Events
summary: Jede Methode, die du auf den Caputchin-Widget-Elementen aufrufen kannst, und jedes Event, das sie emittieren, mit der genauen Payload von jedem, welches Element es bereitstellt und wann es gültig ist.
---

Das Caputchin-Widget liefert zwei Custom Elements, und deine Seite interagiert mit ihnen in zwei Richtungen: du **rufst Methoden** auf dem Element auf, um es zu treiben, und du **lauschst auf Events**, die es emittiert, um zu reagieren. Diese Seite ist die erschöpfende Referenz für beide Flächen.

Jedes Event ist ein `CustomEvent`, dispatcht mit `bubbles: true` und `composed: true`, sodass es dem Shadow DOM des Widgets entkommt und du direkt auf dem Element (oder auf jedem Vorfahren) darauf lauschen kannst. Die Daten sind immer auf `event.detail`.

## Die zwei Elemente auf einen Blick

| Element | Zweck | Methoden |
|---|---|---|
| `<caputchin-widget>` | Nur Verifizierung (Proof-of-Work / Checkbox). | `start()` |
| `<caputchin-game>` | Spiel-Host, mit optionaler Verifizierung. | `pass()`, `fail()` |

Das Checkbox-Widget hat nur `start()`; es stellt `pass()` / `fail()` **nicht** bereit. Der Spiel-Host hat kein `start()` (seine Runde wird beim Mount für Inline live, oder beim ersten Dialog-Öffnen für Modal / Fullscreen). Beide Elemente emittieren `start`, `pass`, `error` und `degraded`; der Spiel-Host emittiert zusätzlich `dialog-shown` und `dialog-hidden`. Die Abdeckung ist in der [Events-Tabelle](#events) unten.

## Methoden

### `start()` (nur `<caputchin-widget>`)

Beginnt die Verifizierung sofort. Sein Zweck ist der **manuelle Auslöser**: wenn das Element `trigger="manual"` hat, rufst du `start()` auf, um die Proof-of-Work-Lösung aus deiner eigenen Geste zu feuern (zum Beispiel beim Submit deines Formulars) statt der eingebauten Checkbox. Mit den Standard-`auto` / `click`-Auslösern verdrahtet das Element seine eigene Aktivierung, also rufst du dies nicht auf.

```js
const widget = document.querySelector("caputchin-widget");
widget.start();
```

Der Spiel-Host hat kein `start()`. Sieh dir [manueller Modus](/docs/custom-game-development/manual-mode) für die vollständige Treib-es-selbst-Anleitung an.

### `pass(payload)` (nur `<caputchin-game>`)

Gibt das Verifizierungs-Gate frei: der Besucher war erfolgreich. **Nur gültig, wenn `trigger="manual"`**; es auf einem nicht-manuellen Spiel aufzurufen emittiert ein `error` mit Code `invalid-call`. Das erste `pass()` löst ein und **sperrt** das Urteil; spätere Aufrufe werden still ignoriert (eine Runde pro Session).

```js
const widget = document.querySelector("caputchin-game");
widget.pass({ trace: roundRecord });
```

| `payload`-Feld | Typ | Bedeutung |
|---|---|---|
| `trace` | `string` | Der opake Runden-Datensatz, den dein Spiel produziert. Auf einer gegateten Runde spielt der Server ihn ab, um das maßgebliche Urteil abzuleiten; auf einem ungegateten oder nur-Spiel-Key wird er wie er ist akzeptiert. Übergib einen leeren String, wenn deine Interaktion keinen Datensatz zum Abspielen hat. |

Es gibt kein `score`-Feld auf dieser Methode, das Gate ist das Replay des `trace` durch den Server, keine vom Client behauptete Punktzahl. (Ein `score` erscheint auf dem [`pass`-Event](#the-pass-event-and-the-token), das das Widget ist, das an dich zurückmeldet, nicht du an das Widget.)

`pass()` aufzurufen, bevor die Runde begonnen hat (Modal / Fullscreen, Dialog noch nicht geöffnet), emittiert ein `error` mit Code `invalid-call`. Auf einem nur-Spiel-Key (kein `sitekey`) gibt es kein Gate freizugeben, also emittiert `pass()` einfach das `pass`-Event mit `token: null`.

### `fail(payload?)` (nur `<caputchin-game>`)

Bricht die Runde ab: ein endgültiger Verlust. **Nur gültig, wenn `trigger="manual"`** (sonst `invalid-call`). Optional, eine unfertige Runde wird ohnehin als Nicht-Pass behandelt. Es bricht die laufende Verifizierung ab (die Proof-of-Work- und Instrumentierungs-Prüfungen) und bringt ein `error`-Event mit Code `game-error-relayed` zum Vorschein.

```js
widget.fail({ code: "out-of-moves", message: "no moves left" });
```

| `payload`-Feld | Typ | Bedeutung |
|---|---|---|
| `code` | `string` (optional) | Dein Diagnose-Code; als `originalCode` des `error`-Events zum Vorschein gebracht. Standard ist `game-failed`. |
| `message` | `string` (optional) | Menschenlesbarer Grund. |

## Events [#events]

Lausch mit `addEventListener(type, handler)`. Jede Payload lebt auf `event.detail`.

| Event | Emittiert von | `event.detail` | Feuert wenn |
|---|---|---|---|
| `start` | beide | `{ gameId: string \| null }` | Verifizierung beginnt (auto beim Mount, bei Aktivierung oder per `start()`). `gameId` ist für eine Spiel-Runde gesetzt, `null` für das schlichte Widget. |
| `pass` | beide | `{ token: string \| null, score: number \| null, durationMs: number \| null }` | Verifizierung wird freigegeben. `token` ist das umhüllte Token, das du an dein Backend sendest; `null` auf einem nur-Spiel-Key (kein `sitekey`). |
| `error` | beide | `{ code, message, severity, originalCode? }` | Alles von einer harmlosen Config-Warnung bis zu einem harten Versagen. Sieh dir [das error-Event](#the-error-event) an. |
| `degraded` | beide | `{ reason: "timeout" \| "network" \| "http" \| "malformed" }` | Das Widget konnte deine konfigurierte Größe / Skin / Locale nicht rechtzeitig auflösen, also rendert es mit seinen gebündelten Standardwerten. Kein Fehler. Sieh dir [das degraded-Event](#the-degraded-event) an. |
| `dialog-shown` | `<caputchin-game>` | `{ layout: "modal" \| "fullscreen" }` | Ein Overlay-Spiel-Dialog öffnet sich (programmatisch oder erster Klick). |
| `dialog-hidden` | `<caputchin-game>` | `{ layout: "modal" \| "fullscreen" }` | Ein Overlay-Spiel-Dialog schließt sich (programmatisch, Escape oder Backdrop-Klick). |

### Das `pass`-Event und das Token [#the-pass-event-and-the-token]

Das `pass`-Event ist dein Stichwort, dass die Verifizierung gelang, aber es ist **nicht** die Vertrauensentscheidung. Die Vertrauensentscheidung ist, dass dein Backend `detail.token` bestätigt. [Verifizier das Token immer auf deinem Backend](/docs/integration-guides/verify-on-your-backend); gewähr nie Zugriff allein aus dem Frontend-Event. In einem Formular fügt das Widget das Token auch als `caputchin-token`-Feld ein, sodass ein normaler Formular-POST es trägt. Das `score` und `durationMs` auf diesem Event sind vom Client gemeldete Analysen und können `null` sein; behandle sie nie als Vertrauenssignal.

### Das `error`-Event [#the-error-event]

Das `error`-Event trägt einen stabilen `code`, eine menschliche `message`, eine `severity` und manchmal einen `originalCode`. Jeder Code hat eine feste Standard-Severity, sodass du "lief weiter"-Warnungen von "ist wirklich kaputtgegangen"-Versagen filtern kannst, **ohne** eine Code-zu-Severity-Tabelle hartzucoden, lies einfach `detail.severity`. Der vollständige Satz Codes:

| `code` | `severity` | Bedeutung |
|---|---|---|
| `invalid-config` | `warn` | Ein Attribut oder eine Kombination, die das Widget ablehnte; es degradiert sanft und läuft weiter. |
| `invalid-call` | `warn` | Eine Methode aufgerufen, als sie nicht gültig war (z. B. `pass()` auf einem nicht-manuellen Spiel, oder bevor die Runde begann). |
| `verification-failed` | `error` | Die Proof-of-Work- oder Instrumentierungs-Prüfung (oder das Token-Einlösen) schlug fehl; kein Token ausgegeben. |
| `game-load-failed` | `error` | Das Spiel-Bundle konnte nicht aufgelöst, geladen oder registriert werden. |
| `gate-unavailable` | `error` | Der Server gab beim Bootstrap eine maßgebliche Ablehnung zurück (ein gegateter Key konnte kein gültiges Spiel liefern). |
| `game-error-relayed` | `error` | Ein Fehler kam aus dem Inneren des Spiels zum Vorschein (vom Iframe weitergereicht, oder von einem manuellen `fail()`). |

`detail.originalCode` ist vorhanden, wenn der öffentliche `code` eine Verallgemeinerung eines spezifischeren internen Grundes ist (zum Beispiel trägt ein als `game-load-failed` weitergereichtes Iframe-Lade-Versagen das rohe `iframe-load-failed` / `iframe-script-blocked` / `game-not-registered` in `originalCode`). Nutz `code` zum Verzweigen und `originalCode` nur zur Diagnose.

### Das `degraded`-Event [#the-degraded-event]

Beim Mount macht das Widget einen kurzen Aufruf an Caputchin, um die von dir konfigurierte Größe, Skin und Locale aufzulösen (und, bei einem Marketplace-Spiel, dessen bevorzugten Footprint). Falls dieser Aufruf fehlschlägt oder zu langsam ist, blockiert oder bricht das Widget nicht: es rendert mit den ins Bundle eingebackenen Werten und emittiert `degraded`, sodass der Rückfall nie stumm ist. Das Widget bleibt nach einem `degraded`-Event voll funktionsfähig, nur die aufgelöste Darstellung kann sich von dem unterscheiden, was du konfiguriert hast (ein Spiel erscheint vielleicht in seiner Standardgröße, oder die Checkbox in ihrem Standard-Theme). Das Widget versucht eine langsame Auflösung erneut, bevor es zurückfällt, also bedeutet `degraded`, dass die Versuche erschöpft waren, nicht dass ein einzelner Versuch langsam war.

`detail.reason` sagt dir, warum die Auflösung zurückfiel, sodass du es in deiner eigenen Telemetrie sichtbar machen kannst:

| `reason` | Bedeutung |
|---|---|
| `timeout` | Die Auflösung antwortete nicht innerhalb ihres Zeitbudgets (Dienst langsam oder nicht erreichbar). |
| `network` | Die Anfrage selbst scheiterte (offline, DNS, blockiert oder Verbindung zurückgesetzt). |
| `http` | Der Dienst antwortete mit einem Fehlerstatus. |
| `malformed` | Der Dienst antwortete, aber der Body war nicht gültig. |

`degraded` ist ein Hinweis, kein Versagen, also ist es absichtlich **kein** `error`-Event: eine langsame Auflösung sollte nicht die Handler auslösen, die du für echte Fehler verdrahtest. Lausch nur darauf, wenn du degradierte Renders beobachten willst, zum Beispiel um zu alarmieren, wenn deine Besucher die Fallback-Darstellung sehen.

## Lauschen, in der Praxis

```js
const widget = document.querySelector("caputchin-game");

const onPass = (e) => {
  // send e.detail.token to your backend to verify
};
const onError = (e) => {
  if (e.detail.severity === "error") {
    console.error(e.detail.code, e.detail.message);
  }
};

widget.addEventListener("pass", onPass);
widget.addEventListener("error", onError);

// Clean up when you tear down your view:
widget.removeEventListener("pass", onPass);
widget.removeEventListener("error", onError);
```

Das sind native DOM-`CustomEvent`s, also hängst du sie in React mit einem `ref` und `addEventListener` an (keine JSX-`onPass`-Props); die [Frontend-Beispiele](/docs/integration-guides/frontend-examples) zeigen die framework-spezifische Verdrahtung. Weil jedes Event bubblet und composed ist, kannst du auch von einem Container-Element delegieren, statt jedes Widget einzeln zu binden.

## Siehe auch

- [Das Widget hinzufügen](/docs/getting-started/add-the-widget): die Konfigurations-Attribute, die du im Markup setzt (die Eingabeseite zu dieser Ausgabeseite).
- [Verifizierung selbst treiben mit dem manuellen Modus](/docs/custom-game-development/manual-mode): das Tutorial, das `start()` / `pass()` / `fail()` nutzt.
- [Auf deinem Backend verifizieren](/docs/integration-guides/verify-on-your-backend): was mit dem Token des `pass`-Events zu tun ist.
- [Frontend-Beispiele](/docs/integration-guides/frontend-examples): diese Events in React, Vue und reinem JS verdrahten.
