Votre serveur sait des choses que Bot Protection ne peut pas savoir : qu'une personne a vérifié son e-mail, a payé sans litige, ou qu'une carte a fait l'objet d'un chargeback. L'envoyer fixe la confiance que Bot Protection accorde à ce navigateur dans ses décisions suivantes. Cela ne change aucune règle ni aucun poids : ce qu'un navigateur a fait ne change jamais les décisions d'un autre.
Désignez le visiteur par le request_id qu'a répondu /v1/decide : gardez-le avec la commande, et envoyez-le quand vous connaissez l'issue, des semaines ou des mois plus tard. Une décision prise avec le token du tag désigne la session de ce navigateur ; une décision prise sans token n'en désigne aucune, et le feedback qui la vise est refusé. Le token du visiteur (le cookie _kz) convient aussi : envoyez token à la place de request_id.
curl -s -X POST https://korzen.dev/v1/feedback \ -H "Authorization: Bearer $KORZEN_API_KEY" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: $(uuidgen)" \ -d '{"feedback":[{"request_id":"<the decision request_id>","outcome":"good_customer"}]}'
| Issue | Quand |
|---|---|
verified_human | la personne a prouvé qui elle est : un lien par e-mail, un code par téléphone, une passkey |
good_customer | une commande payée, un abonnement renouvelé, sans litige |
chargeback | un paiement contesté ou annulé |
fraud | vous avez découvert que le compte était faux ou abusif |
// Node: the SDK sends a UUID v7 as the Idempotency-Key, and again with each retry. await korzen.feedback([{ request_id: order.korzenRequestId, outcome: "chargeback" }]);
// Go: the same, with your own key (an order's id makes a later resend safe too). _, err := bot.Feedback(ctx, []korzen.Feedback{{RequestID: order.KorzenRequestID, Outcome: "chargeback"}}, korzen.Batch{IdempotencyKey: "chargeback-" + order.ID})
Chaque élément nomme sa session par exactement l'un de request_id et token ; un lot en contient 1 à 1 000. La réponse dit ce qui a été enregistré : {"accepted": 1, "duplicates": 0, "rejected": 0, "errors": []}, où chaque élément rejeté est {"index", "code", "detail"}, comme forged pour un request_id qui n'est pas le vôtre, ou no_session pour celui d'une décision prise sans token. Un corps invalide est un problem 400, comme les erreurs de decide.
Envoyez un Idempotency-Key avec chaque appel, de 1 à 255 caractères ASCII visibles, comme le font les SDK avec un UUID v7. La même clé avec le même corps dans l'heure reçoit à nouveau la première réponse, avec Idempotent-Replayed: true, et rien n'est enregistré deux fois ; avec un autre corps, c'est 422 idempotency_key_reused, et tant que le premier appel tourne encore, 409 idempotency_key_in_use. Un appel resté sans réponse, ou qui a reçu 409, 429 ou 5xx, peut donc être renvoyé sans risque sous sa clé, et les SDK le font, quelques fois en 5 secondes.
Le feedback est facultatif et gratuit, et ne compte jamais comme une décision. Les bonnes issues peuvent élever une décision ultérieure du même navigateur à human ou human_high, des mois plus tard aussi, tant qu'il revient ; les mauvaises l'annulent.