Skip to content

API de données de prévention de la fraude ​

L’API de données est le pendant côté serveur du SDK Web. Utilisez-la pour récupérer les verdicts, agréger des statistiques et exporter des données pour le reporting et le rapprochement — en obtenant les chiffres sur lesquels vos propres systèmes s’accordent.

URL de base ​

https://verify.captcha.la

Authentification ​

Toutes les requêtes de l’API de données sont authentifiées avec les identifiants de votre application de prévention de la fraude, envoyés dans les en-têtes :

X-App-Key:    YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET

WARNING

X-App-Secret est réservé au côté serveur. Ne l’exposez jamais aux navigateurs, aux applications mobiles ni aux dépôts publics. Le SDK de page n’utilise que la clé publique appKey.

Points de terminaison ​

Récupérer un verdict ​

Récupérez le verdict d’une visite unique (par ex. pour rapprocher une visite précise). Passez exactement un identifiant : verdict_id (issu du verdict reçu par la page) ou cid (l’identifiant de clic, pour le trafic avec jeton de clic).

bash
GET /v1/bot/verdict?verdict_id=VERDICT_ID
GET /v1/bot/verdict?cid=CID_OF_THE_VISIT
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET

found indique si un verdict a été trouvé. Lorsqu’il vaut true, data contient les champs du verdict décrits dans la Référence du verdict :

json
{
  "found": true,
  "data": {
    "cid": null,
    "verdict_id": "vd_3f9c0a7e5b1d4c2a9e8f7b6a",
    "is_bot": true,
    "score": 87,
    "level": "high",
    "action": "flag",
    "reasons": ["automation", "network"],
    "consistency": { "ok": false },
    "degraded": false,
    "created_at": "2026-06-25 00:00:00"
  }
}

Si rien ne correspond, la réponse est {"found": false}. Une requête sans verdict_id ni cid est rejetée avec HTTP 400.

TIP

Les verdicts sont enregistrés quelques secondes après leur production ; une recherche faite juste après la visite peut donc renvoyer found: false. Pour vérifier une visite en temps réel, utilisez plutôt Vérifier un jeton de verdict.

Vérifier un jeton de verdict ​

Vérifiez un verdict_token que votre page a reçu du SDK Web. Utilisez-le pour protéger du contenu sur votre serveur (voir Vérification côté serveur). La vérification répond immédiatement et ne dépend pas des données enregistrées.

bash
POST /v1/bot/verdict/verify
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
Content-Type: application/json

{ "token": "vt1.eyJ2Ijoi...", "ip": "203.0.113.7", "consume": false }
ParamètreRequisDescription
tokenouiLe verdict_token du verdict.
ipnonL’adresse IP du visiteur telle que votre serveur la voit. Si elle est fournie, le jeton doit provenir du même réseau que la visite. Recommandé.
consumenontrue = le jeton n’est utilisable qu’une fois ; une seconde vérification renvoie already_used. Par défaut false : le jeton peut être revérifié jusqu’à son expiration.
json
{
  "valid": true,
  "error": null,
  "verdict_id": "vd_3f9c0a7e5b1d4c2a9e8f7b6a",
  "expired": false,
  "expires_at": 1767225600,
  "ip_match": true,
  "verdict": {
    "is_bot": false,
    "level": "low",
    "action": "record_only",
    "score": 12,
    "degraded": false,
    "reasons": [],
    "issued_at": 1767225000
  }
}
ChampDescription
validtrue lorsque le jeton est authentique, appartient à votre application, n’a pas expiré, correspond à ip (si fournie) et, avec consume, n’a pas déjà été utilisé. valid indique seulement que le jeton est authentique. Il ne dit pas que le visiteur est humain : vérifiez donc aussi verdict.
errornull, ou la raison pour laquelle le jeton n’est pas valide : malformed, bad_signature, expired, ip_mismatch, already_used, unavailable (la vérification à usage unique n’a pas pu aboutir ; réessayez).
expired / expires_atÉtat d’expiration et heure d’expiration (secondes Unix).
ip_matchtrue / false lorsque ip a été fournie, sinon null.
verdictLe verdict signé : is_bot, level, action, score, degraded, reasons, issued_at. null lorsque le jeton n’a pas pu être lu.

Une protection typique sert le contenu lorsque valid vaut true et verdict.is_bot vaut false. Décidez vous-même comment traiter verdict.degraded et les requêtes sans aucun jeton. Si vous laissez passer en cas d’échec, les vrais visiteurs passent toujours pendant une panne. Si vous bloquez en cas d’échec, rien ne passe sans jeton valide.

Les jetons expirent par défaut après 10 minutes. Relancez le SDK (par exemple au chargement de page suivant) pour en obtenir un nouveau.

Statistiques agrégées ​

Récupérez des comptages sur une plage de temps (totaux, bots et répartition par level et par jour) pour les tableaux de bord et les rapports de qualité.

bash
GET /v1/bot/stats?from=2026-06-01&to=2026-06-30
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
json
{
  "from": "2026-06-01",
  "to": "2026-06-30",
  "cleaned": true,
  "total": 124500,
  "bots": 18230,
  "by_level": { "low": 100300, "medium": 16900, "high": 6200, "critical": 1100 },
  "by_day": [
    { "date": "2026-06-01", "total": 4100, "bots": 590 }
  ]
}

Par défaut, from / to couvrent les 7 derniers jours.

Export ​

Exportez les lignes de verdict par visite sur une plage de temps, pour un rapprochement hors ligne. Les lignes sont renvoyées de la plus récente à la plus ancienne, par pages.

bash
GET /v1/bot/export?from=2026-06-01&to=2026-06-30&limit=1000
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET
ParamètreDescription
from / toPlage de dates (YYYY-MM-DD). Facultatif.
limitLignes par page, 1–5000 (1000 par défaut).
cursorPassez le next_cursor de la page précédente pour obtenir la page suivante.
json
{
  "rows": [
    {
      "id": 1042, "cid": null, "verdict_id": "vd_3f9c0a7e5b1d4c2a9e8f7b6a",
      "is_bot": false, "score": 12, "level": "low", "action": "record_only",
      "reasons": [], "consistency": { "ok": true }, "degraded": false,
      "created_at": "2026-06-25 00:00:00", "rescored": false
    }
  ],
  "next_cursor": 1042
}

Chaque ligne porte les identifiants de la visite, l’horodatage et les champs du verdict, afin que vous puissiez la rapprocher de vos propres journaux. next_cursor vaut null sur la dernière page.

Chiffres nettoyés

Les statistiques et les exports sont fournis par défaut sur une base nettoyée : le trafic identifié ultérieurement comme invalide est réévalué en continu et retiré des chiffres. Cela se fait de manière asynchrone, si bien que les chiffres des fenêtres très récentes peuvent encore se stabiliser légèrement. Passez ?raw=1 pour voir les chiffres non nettoyés ; dans export, chaque ligne porte aussi un indicateur rescored.

Rapprochement par clic

Pour les scénarios de trafic payant, une seule visite peut être reliée à un clic livré précis afin que deux parties puissent se régler dessus. Cela s’appuie sur un jeton de clic et est traité dans le guide Fraude publicitaire.

Référence du jeton de clic (pour les fournisseurs de trafic) ​

Un fournisseur de trafic signe un jeton de clic sur son propre serveur et l’ajoute à l’URL de destination, afin que le verdict de la visite résultante lui soit attribué. La signature se fait hors ligne — aucun appel d’API.

Obtenir vos identifiants de signature ​

Dans le tableau de bord, ouvrez votre application → Fraud Prevention → Émettre une clé de signature. Vous recevez :

  • bot_kid — l’identifiant de votre clé publique (placé dans le jeton sous pkid).
  • bot_hmac_secret — votre secret de signature, affiché une seule fois. Conservez-le côté serveur.

Format du jeton ​

ct.<base64url(payload)>.<base64url(HMAC_SHA256(body, bot_hmac_secret))>

body est le base64url de la charge utile JSON ; la signature est calculée sur cette chaîne body.

Champs de la charge utile ​

champrequisdescription
pkidouivotre bot_kid ; le backend l’utilise pour retrouver votre secret et vérifier la signature
cidouiidentifiant unique de ce clic ; la clé de réconciliation. Générez une valeur nouvelle et unique pour chaque clic
audnonl’app_key de l’annonceur ciblé. Lorsqu’il est défini, le jeton n’est honoré que sur la page de cet annonceur. Omettez-le pour qu’une page de n’importe quel annonceur l’accepte
click_tsnonsecondes unix correspondant au moment du clic
expnonsecondes unix d’expiration ; les jetons expirés sont rejetés

L’ajouter au lien ​

Ajoutez le jeton comme paramètre de requête _ctk à l’URL de destination de l’annonceur :

https://advertiser.example/lp?_ctk=ct.<...>.<...>

Le SDK de l’annonceur lit _ctk automatiquement (configurable via tokenParam). Chaque cid est protégé contre le rejeu : le même visiteur qui recharge la page ne pose pas de problème, mais un jeton réutilisé ailleurs est signalé. Voir le Modèle de sécurité.

Exemple (pseudo-code) ​

js
const payload = { pkid, cid, aud: advertiserAppKey, click_ts: now, exp: now + 900 }
const body  = base64url(JSON.stringify(payload))
const sig   = base64url(hmacSha256(body, botHmacSecret))
const token = `ct.${body}.${sig}`
const url   = `${destination}?_ctk=${encodeURIComponent(token)}`

Postback (serveur à serveur) ​

Au lieu d’interroger l’API de données, vous pouvez faire pousser les verdicts vers votre propre point de terminaison au fur et à mesure — pratique pour les trackers d’affiliation et les back-ends d’annonceurs qui veulent enregistrer ou rapprocher chaque visite en temps réel.

L’activer ​

Dans le tableau de bord, ouvrez votre application → Fraud Prevention → définissez Postback URL (bot_postback_url). Une fois défini, chaque verdict est envoyé en POST à cette URL peu après sa production. La livraison est asynchrone et isolée — un point de terminaison lent ou défaillant n’affecte jamais le verdict déjà renvoyé au SDK de la page.

Quand il se déclenche ​

À chaque vérification qui produit un verdict pour l’application. La livraison est au mieux (best-effort), avec quelques nouvelles tentatives automatiques ; considérez-la comme au moins une fois (at-least-once) et dédoublonnez sur verdict_id.

Requête ​

POST <your bot_postback_url>
Content-Type: application/json
X-Bot-Signature: t=<unix_ts>,v=<hex>

Corps (JSON) :

json
{
  "cid": "CID_OF_THE_VISIT",
  "verdict_id": "vd_3f9c0a7e5b1d4c2a9e8f7b6a",
  "is_bot": 1,
  "score": 87,
  "level": "high",
  "action": "flag",
  "advertiser_app_id": 12,
  "provider_app_id": 34,
  "created_at": "2026-06-25 00:00:00"
}
champdescription
cidclé de rapprochement de la visite (peut valoir null si aucun jeton de clic n’était présent)
verdict_idid du verdict ; même valeur que celle reçue par la page
is_bot1 / 0
scorescore de risque
levellow / medium / high / critical
actionaction faisant autorité côté serveur (record_only / flag / challenge / deny)
advertiser_app_idid de l’application pour laquelle la vérification a été exécutée
provider_app_idid du fournisseur de trafic lorsque la visite est attribuée via un jeton de clic, sinon null
created_atheure du verdict (UTC)

Vérifier la signature ​

L’en-tête X-Bot-Signature vous permet de confirmer que la requête provient bien de nous. Il vaut t=<unix_ts>,v=<hex> où :

hex = HMAC_SHA256( "<unix_ts>." + raw_request_body , bot_hmac_secret )

bot_hmac_secret est le même secret de signature que vous émettez sous Fraud Prevention → Issue signing key. Pour vérifier, recalculez le HMAC sur le corps brut reçu (ne re-sérialisez pas le JSON) et comparez en temps constant. Vous pouvez aussi rejeter les requêtes dont t est trop éloigné de votre horloge afin de limiter le rejeu.

js
// Express example
const [tsPart, vPart] = req.get('X-Bot-Signature').split(',')
const ts = tsPart.slice(2)             // "t=" prefix
const v  = vPart.slice(2)              // "v=" prefix
const expected = crypto
  .createHmac('sha256', BOT_HMAC_SECRET)
  .update(ts + '.' + rawBody)          // rawBody is the unparsed request body
  .digest('hex')
const ok = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v))

Étapes suivantes ​

MIT-licensed examples · CaptchaLa is operated independently