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