Aller au contenu

Scoring des leads

Le scoring attribue un score numérique (de 0 à 100) à chaque lead, selon des règles configurables. Les scores sont stockés et interrogeables.

  1. Créez une ou plusieurs règles de scoring : chaque règle est une expression évaluée sur le lead.
  2. Chaque règle produit une valeur ; toutes les valeurs sont additionnées et le total est ramené dans l’intervalle 0 à 100. Sans aucune règle, le score vaut rating * 20.
  3. Déclenchez un recalcul pour un lead ou pour tous les leads.
Fenêtre de terminal
curl -X POST https://api.klozeo.com/api/v1/scoring-rules \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"name": "Partner in Lyon",
"expression": "city == \"Lyon\" && has_tag(\"partenaire\") && attr(\"effectif\") >= 50 ? 20 : 0",
"priority": 1
}'

Une règle qui nomme un champ ou une fonction inconnus est refusée avec 400 invalid_scoring_expression et un message qui dit ce qui ne va pas et où, par exemple unknown field "effectif" … custom attributes: attr("effectif").

Quoi Syntaxe Exemple
Champs numériques rating (0 s’il est absent), review_count, tags (nombre de tags) rating * 20
Champs texte email, phone, website, city, country, category, source, status city == "Lyon"
Identifiant d’entreprise siren : le SIREN normalisé à 9 chiffres, absent quand il n’est pas défini (un SIRET est stocké sous son SIREN) siren != nil ? 10 : 0
Champs de date created_at, last_interaction_at created_at >= date("2026-01-01")
Tag has_tag("name"), insensible à la casse has_tag("vip") ? 15 : 0
Attribut personnalisé attr("name"), typé par l’attribut : nombre, texte, booléen ou date attr("effectif") >= 50
Littéral de date date("YYYY-MM-DD") ou RFC 3339 ; date(attr("x")) lit une date stockée en texte date(attr("signed_on")) < date("2026-07-01")
Arithmétique +, -, *, / (une division par zéro donne 0) rating * 10 + tags
Comparaison ==, !=, <, <=, >, >= review_count > 100
Appartenance à une liste value in ["a", "b"] status in ["qualified", "demo"]
Logique &&, ||, ! !has_tag("lost")
Ternaire condition ? if_true : if_false rating > 4 ? 30 : 0
Repli a ?? b : b quand a est vide, zéro, faux ou absent attr("budget") ?? 0
Variables let name = value; avant la valeur finale let q = rating * 15; q + tags
Mathématiques min, max, abs, floor, ceil, round min(review_count, 200) / 4
  • Les comparaisons de texte ignorent la casse : city == "lyon" correspond à Lyon. Le texte ne prend en charge que ==, != et in.
  • Sauf face à nil (point suivant), une valeur absente (attribut absent ou null, mauvais type, champ texte vide, date non définie) ne satisfait jamais ==, <, <=, >, >= ni in, même face à une autre valeur absente : attr("effectif") >= 50 et attr("effectif") <= 50 sont tous deux faux, alors que != est vrai. En arithmétique, elle compte pour 0.
  • x == nil teste le vide comme ?? : vrai quand x est absent, vaut 0 ou faux, ou est un texte vide ; x != nil est son contraire (attr("absent") == nil est vrai, attr("absent") != nil est faux).
  • En arithmétique ou comme condition, un champ texte compte pour 1 quand il est rempli : email * 30 et email != nil ? 30 : 0 donnent le même résultat.
  • Les expressions sont limitées à 1 000 octets et 64 niveaux d’imbrication.

Une règle enregistrée avant l’existence de cette validation est validée de nouveau quand vous modifiez son expression ; d’ici là, si elle ne compile plus, elle n’ajoute rien au score. Voir la référence API pour les détails.

rating * 20
(email != nil ? 30 : 0) + (phone != nil ? 30 : 0) + (website != nil ? 20 : 0)
city == "Lyon" && has_tag("partenaire") && attr("effectif") >= 50 ? 20 : 0
category in ["bakery", "restaurant"] ? 25 : 0
attr("client") ? 0 : 15
let recent = created_at >= date("2026-09-01"); recent && source == "google_maps" ? 10 : 0

Une fois que le compte a au moins une règle, le score d’un lead est recalculé automatiquement, avant que l’API réponde, quand le lead est créé, fusionné (doublon à la création ou en lot), mis à jour (REST ou MCP), enrichi avec des données d’entreprise, ou quand l’un de ses attributs personnalisés change. Un compte peut avoir jusqu’à 100 règles.

Après la création, la suppression ou la modification de l’expression d’une règle, tous les leads du compte sont recalculés en arrière-plan : quelques secondes pour un petit compte, quelques minutes pour un très gros. Pendant ce temps, les scores mélangent anciennes et nouvelles règles ; chaque lot de scores modifiés envoie un webhook leads.scored. Supprimer la dernière règle laisse les scores inchangés.

Le recalcul explicite reste disponible :

Fenêtre de terminal
# Single lead
curl -X POST https://api.klozeo.com/api/v1/leads/cl_.../score \
-H "X-API-Key: sk_live_your_key"
# All leads
curl -X POST https://api.klozeo.com/api/v1/leads/score/batch \
-H "X-API-Key: sk_live_your_key"
Fenêtre de terminal
# Leads with score >= 70
?filter=and.gte.score.70
# High-value leads (score >= 80, has email)
?filter=and.gte.score.80&filter=and.is_not_empty.email

Le tableau de bord utilise les seuils suivants pour colorer le score des leads :

Score Couleur
≥ 70 Vert
≥ 40 Orange
< 40 Rouge