REST API v1

Dokumentation

Drei Endpunkte, ein Skript. Das Widget übernimmt Aufgabe und Lösung im Browser, dein Server prüft am Ende nur noch den Token – wie bei gängigen Captcha-Diensten.

1. Widget einbinden

Skript laden, Platzhalter ins Formular setzen. Der Token landet automatisch im versteckten Feld sentinel-captcha-response.

<script src="https://DEINE-DOMAIN/v1/widget.js" defer></script>

<form method="post" action="/kontakt">
  <input name="email" type="email" required />
  <div data-sentinel-captcha data-sitekey="sc_site_xxxxxxxx" data-theme="dark"></div>
  <button type="submit">Absenden</button>
</form>

Optionen: data-theme (dark | light), data-field (Feldname), data-callback (globale JS-Funktion).

2. POST /api/public/v1/challenge

Fordert eine neue Aufgabe an. Nicht abrechnungsrelevant.

{ "site_key": "sc_site_xxxxxxxx", "hostname": "example.com" }

→ 200
{ "challenge_id": "uuid", "salt": "9f2c…", "difficulty": 13, "mode": "auto", "expires_in": 300 }

3. POST /api/public/v1/attempt

Reicht den Rechennachweis und Verhaltenssignale ein. Je nach Risiko antwortet der Dienst mit Token, Checkbox-Bestätigung oder Bild-Rätsel.

{
  "challenge_id": "uuid",
  "nonce": "48213",
  "signals": { "elapsedMs": 1840, "pointerEvents": 22, "webdriver": false }
}

→ { "status": "solved", "token": "a1b2….hmac", "score": 0.92 }
→ { "status": "checkbox_required", "stage": "checkbox" }
→ { "status": "puzzle_required", "puzzle": { "prompt": "Wähle das Symbol: 🔐", "tiles": ["🔑","🔐", …] } }

4. POST /api/public/v1/siteverify

Serverseitige Prüfung mit deinem Geheimschlüssel. Jeder erfolgreiche Aufruf ist ein abgerechneter Abruf (bei VIP-Websites kostenlos). Tokens sind einmalig und 5 Minuten gültig.

curl -X POST https://DEINE-DOMAIN/api/public/v1/siteverify \
  -H "content-type: application/json" \
  -d '{"secret":"sc_sec_…","response":"TOKEN_AUS_DEM_FORMULAR"}'

→ {
  "success": true,
  "score": 0.92,
  "challenge_ts": "2026-09-19T18:00:00.000Z",
  "billed": true,
  "plan": "pay-as-you-go"
}
// Node / TypeScript
const res = await fetch("https://DEINE-DOMAIN/api/public/v1/siteverify", {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({
    secret: process.env.SENTINEL_SECRET,
    response: formData.get("sentinel-captcha-response"),
  }),
});
const result = await res.json();
if (!result.success) return new Response("Captcha ungültig", { status: 400 });

5. GET /api/public/v1/status

Verfügbarkeits-Check für Monitoring.

{ "status": "ok", "service": "SentinelCaptcha", "version": "1.0.0" }

Fehlercodes

  • unknown-site-key – öffentlicher Schlüssel unbekannt
  • hostname-not-allowed – Domain nicht in der Freigabeliste
  • invalid-proof-of-work – Rechennachweis falsch
  • challenge-expired – Aufgabe älter als 5 Minuten
  • invalid-input-secret – Geheimschlüssel falsch
  • timeout-or-duplicate – Token abgelaufen oder bereits benutzt