Référence de l'API
Points d'accès, champs de réponse, codes de statut, limites de débit et nos engagements de stabilité.
Sur cette page
Référence de l'API (V2)
URL de base : https://api.captchacore.eu — tous les points d'accès répondent en JSON. Si vous utilisez le widget fourni, vous n'appelez jamais /challenge vous-même : le widget s'en charge. Pour votre propre extension, seul /verify est obligatoire.
Authentification
| Point d'accès | Clé | Utilisée où |
|---|---|---|
| GET /api/v2/challenge | cc_pub_… | dans le navigateur — peut être publique |
| POST /api/v2/verify | cc_sec_… | côté serveur uniquement — ne jamais la diffuser |
| GET /api/v2/status | cc_sec_… | côté serveur uniquement |
La clé va toujours dans l'en-tête X-CaptchaCore-Key, jamais dans l'URL.
GET /api/v2/challenge
Demande un calcul accompagné de sa politique. Paramètre de requête facultatif : form_type (voir les politiques de formulaire). Répond avec HTTP 200.
{
"challenge_id": "ch_a45cd15b0d6d2dc6",
"nonce": "a45cd15b…1d50", // einmalig, 5 Minuten gültig
"expires_at": 1788860066,
"policy": {
"mode": "adaptive",
"challenge_type": "sha256_pow", // oder argon2id_pow, interaction_step_up
"challenge_types": ["sha256_pow"],
"difficulty": 4, // führende Nullen im Hash
"algorithm": "sha256",
"time_budget_ms": 500,
"requires_interaction": false,
"requires_stepup_on_submit": false,
"memory_hard_enabled": false,
"form_type": "contact",
"site_profile": "balanced",
"uam_level": 0 // 0–3, Under-Attack-Stufe
},
"bindings": { // bindet den Token an Site, Origin und Formular
"site_id": 2,
"origin": "https://example.com",
"form_type": "contact",
"issued_at": 1788859766,
"expires_at": 1788860066,
"token_ttl_sec": 300
},
"bindings_signature": "CBkATjVc…RDg==", // Ed25519, unveränderlich mitschicken
"signing_key_id": "k_397d99d39156c5f5",
"widget": { /* im Admin gepflegtes Erscheinungsbild */ },
"widget_version": "3.0.0"
}
Important pour vos propres clients : bindings et bindings_signature doivent revenir inchangés dans le jeton. S'ils manquent ou sont modifiés, /verify répond block.
POST /api/v2/verify
Vérifie le jeton du formulaire. En règle générale, la réponse est HTTP 200, y compris en cas de refus. Analysez le corps, pas le code de statut.
// Request { "token": "<Wert des Feldes captchacore_token>", "form_type": "contact", // optional, steuert die Policy "page_url": "https://…" // optional, nur für Auswertungen } // Response { "valid": true, // false bei block UND bei step_up "decision": "allow", // allow | challenge | step_up | block "action": "allow", // identisch zu decision, für V1-Kompatibilität "request_id": "…", // für Rückfragen an den Support "risk_score": 8, // 0–100, höher = riskanter "confidence": 0.94, // 0.0–1.0 Signalabdeckung "reasons": ["pow_valid", "behavior_human_like"], "step_up": null // bei decision=step_up: Daten für die Zusatzprüfung }
Comment traiter decision
| decision | valid | Comportement recommandé |
|---|---|---|
| allow | true | Traitez le formulaire normalement. |
| challenge | true | Laissez passer mais journalisez. Ajoutez éventuellement une vérification à vous, par exemple un e-mail de confirmation. |
| step_up | false | Ne refusez PAS d'emblée. Le widget effectue lui-même la vérification supplémentaire ; rendez le formulaire à l'utilisateur avec un message aimable. |
| block | false | Refusez. Affichez une erreur sans détail afin que les attaquants n'apprennent rien. |
GET /api/v2/status
Disponibilité et niveau d'attaque actuel du site. Convient à un contrôle de santé dans votre extension.
{ "status": "ok", "under_attack": false, "version": "2.x" }
Codes de statut HTTP
| Code | Corps | Cause et réaction |
|---|---|---|
| 200 | {"valid": …} | Cas normal, y compris en cas de refus. Analysez le corps. |
| 401 | {"error":"Missing API key"} | L'en-tête X-CaptchaCore-Key est absent. |
| 401 | {"error":"Invalid API key"} | Clé erronée, révoquée ou d'un autre site. C'est aussi le cas lorsque la clé publique est utilisée sur /verify. |
| 403 | {"error": …} | L'origine ne figure pas parmi les domaines autorisés du site. |
| 422 | {"message": …} | Un champ obligatoire manque, généralement token. |
| 429 | — | Limite de débit atteinte. Traitez-la comme une panne, voir la gestion des erreurs. |
| 5xx | — | Un incident de notre côté. Votre règle fail-open ou fail-closed s'applique. |
Limites de débit
| Point d'accès | Limite | Compté par |
|---|---|---|
| GET /api/v2/challenge | 60 / min | IP du visiteur |
| POST /api/v2/verify | 600 / min | clé de site du client |
Verify est compté par site, pas par IP. Votre serveur peut donc vérifier autant de formulaires que votre trafic l'exige, sans se bloquer lui-même.
Webhooks
CaptchaCore prévient vos propres systèmes lorsqu’il se passe quelque chose qui mérite une réaction : quota atteint, mode under-attack déclenché, compte bloqué ou débloqué. Cela se configure dans l’espace client sous Sites → Webhooks (à partir de l’offre Professional).
Événements
| Événement | Quand |
|---|---|
| usage.warning | Quota mensuel utilisé à 80 % ou 90 % |
| usage.limit_reached | Quota mensuel atteint — les vérifications suivantes sont refusées |
| site.under_attack.activated | Mode under-attack d’un site activé (manuellement ou automatiquement) |
| site.under_attack.deactivated | Mode under-attack d’un site terminé |
| organisation.blocked | Compte bloqué (p. ex. facture impayée) — les appels API sont refusés |
| organisation.unblocked | Compte de nouveau débloqué |
| webhook.test | Événement de test depuis l’espace client |
Ce qui arrive
Un POST avec un corps JSON. Trois en-têtes aident à l’identifier et à le vérifier :
POST /ihr-endpunkt HTTP/1.1
Content-Type: application/json
X-CaptchaCore-Event: usage.limit_reached
X-CaptchaCore-Delivery: 5f1c2c1e-… // eindeutig je Zustellung, gleich bei Wiederholungen
X-CaptchaCore-Timestamp: 1758196800
X-CaptchaCore-Signature: sha256=3b2a…
{
"event": "usage.limit_reached",
"occurred_at": "2026-09-18T14:00:00+02:00",
"organisation_id": 42,
"data": { "threshold_percent": 100, "used": 10000, "limit": 10000, "plan": "pro", "period": "2026-09" }
}Vérifier la signature
La signature est un HMAC-SHA256 sur « timestamp.body » avec la clé de l’espace client. Comparez en temps constant et refusez les horodatages de plus de cinq minutes — cela empêche le rejeu de requêtes interceptées.
$secret = getenv('CAPTCHACORE_WEBHOOK_SECRET'); $body = file_get_contents('php://input'); $timestamp = $_SERVER['HTTP_X_CAPTCHACORE_TIMESTAMP'] ?? ''; $expected = 'sha256=' . hash_hmac('sha256', $timestamp . '.' . $body, $secret); if (abs(time() - (int) $timestamp) > 300 || ! hash_equals($expected, $_SERVER['HTTP_X_CAPTCHACORE_SIGNATURE'] ?? '')) { http_response_code(401); exit; } $event = json_decode($body, true); // … verarbeiten, dann schnell mit 2xx antworten http_response_code(204);
Livraison et nouvelles tentatives
- Répondez avec un statut 2xx en moins de 5 secondes — traitez le reste de façon asynchrone.
- En cas d’erreur ou de délai dépassé, la livraison est retentée jusqu’à trois fois (après 30 secondes puis 5 minutes) avec le même ID de livraison — rendez votre traitement idempotent grâce à lui.
- Après dix échecs consécutifs, le webhook est désactivé ; l’espace client indique la raison et permet de le réactiver.
- Chaque livraison, avec code de réponse, durée et extrait de réponse, figure sous « Livraisons » — utile aussi pour le dépannage de votre côté.
Versionnement et stabilité
Qui maintient une extension doit savoir sur quoi compter. Voici nos engagements.
La version dans le chemin reste stable
Au sein de /api/v2, nous ne supprimons ni ne renommons de champs de réponse. De nouveaux champs peuvent apparaître à tout moment : lisez les réponses avec tolérance et n'échouez pas sur des clés inconnues.
V1 reste disponible pour l'instant
L'ancienne interface sous /api/v1 reste servie mais ne reçoit plus de nouveaux signaux. Les nouvelles intégrations doivent utiliser exclusivement V2.
Le widget se met à jour tout seul
Via le chemin CDN captchacore-v2.min.js, vous obtenez toujours la version maintenue. N'embarquez pas votre propre copie, sinon vous manquerez les améliorations de la détection des robots.
Nous annonçons les changements
Tout ce qui pourrait affecter des intégrations existantes est annoncé à l'avance sur l'état public du système et par e-mail à l'adresse technique enregistrée.