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.laAuthentification
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_SECRETWARNING
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).
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_SECRETfound 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 :
{
"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.
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ètre | Requis | Description |
|---|---|---|
token | oui | Le verdict_token du verdict. |
ip | non | L’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é. |
consume | non | true = 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. |
{
"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
}
}| Champ | Description |
|---|---|
valid | true 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. |
error | null, 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_match | true / false lorsque ip a été fournie, sinon null. |
verdict | Le 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é.
GET /v1/bot/stats?from=2026-06-01&to=2026-06-30
X-App-Key: YOUR_APP_KEY
X-App-Secret: YOUR_APP_SECRET{
"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.
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ètre | Description |
|---|---|
from / to | Plage de dates (YYYY-MM-DD). Facultatif. |
limit | Lignes par page, 1–5000 (1000 par défaut). |
cursor | Passez le next_cursor de la page précédente pour obtenir la page suivante. |
{
"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 souspkid).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
| champ | requis | description |
|---|---|---|
pkid | oui | votre bot_kid ; le backend l’utilise pour retrouver votre secret et vérifier la signature |
cid | oui | identifiant unique de ce clic ; la clé de réconciliation. Générez une valeur nouvelle et unique pour chaque clic |
aud | non | l’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_ts | non | secondes unix correspondant au moment du clic |
exp | non | secondes 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)
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) :
{
"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"
}| champ | description |
|---|---|
cid | clé de rapprochement de la visite (peut valoir null si aucun jeton de clic n’était présent) |
verdict_id | id du verdict ; même valeur que celle reçue par la page |
is_bot | 1 / 0 |
score | score de risque |
level | low / medium / high / critical |
action | action faisant autorité côté serveur (record_only / flag / challenge / deny) |
advertiser_app_id | id de l’application pour laquelle la vérification a été exécutée |
provider_app_id | id du fournisseur de trafic lorsque la visite est attribuée via un jeton de clic, sinon null |
created_at | heure 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.
// 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
- Référence du verdict — les champs renvoyés par ces points de terminaison
- SDK Web — collectez les verdicts sur votre page