---
type: how-to
title: Serverseitige Integration
summary: Nimm das caputchin-token aus einer Einsendung und bestätige es mit /siteverify, bevor du der Anfrage traust.
---

Das Widget reicht dem Browser ein Einmal-Token. Dieses Token beweist nichts, bis dein Server es mit Caputchin bestätigt. Das ist der Schritt, der aus einer sichtbaren Aufgabe echten Schutz macht, und es ist ein einziger HTTPS-Aufruf.

Du brauchst ein Backend, das eine ausgehende Anfrage stellen kann, und das Secret deines Site-Keys (`cpt_sec_...`) dort verfügbar, nie im Browser.

## 1. Das Token lesen

Wenn das Formular postet, empfängt dein Handler ein zusätzliches Feld neben deinen eigenen: `caputchin-token`. Das Widget hat es ins Formular eingefügt, als der Besucher die Aufgabe gelöst hat.

## 2. Mit /siteverify bestätigen

POSTe das Token und dein Secret. Anfrage und Antwort sind wie reCAPTCHAs `siteverify` geformt, sodass sich eine bestehende Integration mit wenig Änderung übertragen lässt:

```http
POST https://verify.caputchin.com/v1/siteverify
Content-Type: application/json

{ "secret": "cpt_sec_...", "response": "<caputchin-token>" }
```

```js
// Node 18+
const verdict = await fetch("https://verify.caputchin.com/v1/siteverify", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    secret: process.env.CAPUTCHIN_SECRET,
    response: token,
  }),
}).then((r) => r.json());

if (!verdict.success) {
  // reject the submission
}
```

Denselben Aufruf in anderen Sprachen findest du unter [Backend-Integrationsbeispiele](/docs/integration-guides/backend-examples).

## 3. Die Antwort lesen

```json
{
  "success": true,
  "error-codes": [],
  "platform": { "game_id": "caputchin/games/leaf-memory", "score": 847, "duration_ms": 4200 }
}
```

- **`success`** ist das Einzige, worauf du verzweigst. `true` heißt, ein echter Besucher hat die Aufgabe gelöst; trau der Anfrage. `false` heißt, verwirf sie.
- **`error-codes`** erscheint, wenn `success` `false` ist, und benennt, was schiefging (ein fehlendes, abgelaufenes oder bereits genutztes Token und so weiter).
- **`platform`** sind vom Client behauptete Metadaten (welches Spiel, die Punktzahl, die Dauer). Es ist nullable und **kein Sicherheitssignal**. Erfasse es für Analysen, wenn du willst, aber gate Vertrauen nie an der Punktzahl.

## Die Regeln, die dich schützen

- **Einmalig.** Ein Token verifiziert einmal. Dasselbe noch einmal einzureichen gibt `success: false` zurück, sodass du Replays nicht selbst verfolgen musst.
- **Kurzlebig.** Ein Token läuft zehn Minuten nach seiner Ausgabe ab, also verifizier es während der Bearbeitung der Einsendung, nicht in einem verzögerten Job.
- **Das Secret bleibt auf dem Server.** Es geht nie an den Browser, und es ist das, was den Aufruf authentifiziert.

## Häufige Fehler

- **Clientseitig verifizieren.** Das `pass`-Event und die Anwesenheit des Tokens sind nur UX. Jede Vertrauensentscheidung passiert hier, serverseitig, mit deinem Secret.
- **An `score` gaten.** Es sind Metadaten, kein Vertrauenswert.

## Häufige Fragen

### Wie lange ist ein Token gültig?

Zehn Minuten nach seiner Ausgabe. Verifizier es, während du die Einsendung bearbeitest, nicht aus einem verzögerten Job oder einer Queue, die später laufen könnte.

### Kann ich dasselbe Token zweimal verifizieren?

Nein. Ein Token ist einmalig. Dasselbe noch einmal einzureichen gibt `success: false` zurück, sodass du Replays nicht selbst verfolgen musst.

### Soll ich dem `score` oder der `game_id` trauen?

Nein. Der `platform`-Block (Spiel, Punktzahl, Dauer) sind vom Client behauptete Metadaten und nullable. Verzweig nur auf `success`, und gate Vertrauen nie an der Punktzahl.

### Brauche ich dafür ein SDK?

Nein. Die Prüfung ist ein einzelnes HTTPS-POST an `/v1/siteverify`. Derselbe Aufruf in Node, Python, PHP, Go, Ruby, .NET und curl findet sich unter [Backend-Integrationsbeispiele](/docs/integration-guides/backend-examples).

## Siehe auch

- [Backend-Integrationsbeispiele](/docs/integration-guides/backend-examples) für diesen Aufruf in deiner Sprache.
- [Gehostete Verifizierung](/docs/hosted-verification/overview), um das Backend ganz zu überspringen.
