Lead Scoring
Audience: Sales · Management · Support · QA · Engineering · Where in app: Settings → Lead Scoring (config); shown on Dashboard Hot Leads, Live Sessions, Recorded Sessions, Person Detail · Plan availability: All plans
Every visitor accumulates a lead score as they interact with the widget. Each meaningful action adds points; the more high-intent the action, the more it's worth. The score ranks visitors on the dashboard, drives hot-lead notifications, and can gate automation. It's a rule-based heuristic — a prioritization aid, not a guaranteed probability of conversion.
What it does
- Adds points to a visitor as they take scored actions (visit a key page, share contact info, return, book, etc.).
- Surfaces the highest scorers so teams act on the hottest visitors first.
- Fires hot-lead notifications (Slack / email / FCM / webhook) when a visitor crosses the threshold.
- Buckets scores into levels (Low / Medium / High / Very High) with badges and a fire icon for the hottest.
How it works
Two timelines run in parallel:
- Per session —
user_sessions.lead_scoreaccumulates as the visitor browses, chats, calls, and books. - Per visitor —
visitor_profilescarries a higher-levelengagement_scoreover time.
Each scored signal is individually toggleable and weighted in companies.lead_score. When a visitor's total crosses the company's hot threshold, the notification fan-out fires.
Score levels (customer-facing)
| Level | Score range | Meaning |
|---|---|---|
| Low | 0–20 | Minimal engagement; just arrived or casual browse |
| Medium | 21–50 | A few meaningful actions; showing interest |
| High | 51–99 | Actively engaged, multiple high-intent actions |
| Very High | 100+ | Many high-value actions; likely ready to convert (gets a 🔥 fire icon) |
Configuration & options
Per-signal weights
Configured under companies.lead_score. Each signal has a toggle (enabled: true/false), a numeric weight (typically 0–200), and a threshold where applicable.
| Signal | Default weight | Fires when |
|---|---|---|
visited_heigh_intent_page (spelling per schema) | configurable | Visitor lands on a page in high_value_pages[] |
user_initiated_call | configurable | Visitor clicked call (not the AI starting it) |
call_auto_connect_accepted | configurable | Visitor accepted the call auto-trigger |
chat_auto_connect_accepted | configurable | Visitor accepted the chat auto-trigger |
call_greater_than | configurable (+ seconds threshold) | Call lasted longer than the threshold |
chat_greater_than | configurable (+ seconds threshold) | Chat lasted longer than the threshold |
booked_meeting | high | A booking was created (any source) |
shared_email | medium | Visitor gave their email |
shared_phone | medium | Visitor gave their phone |
industry_match | configurable | Visitor's company/domain matches companies.knox.target_market |
product_searched | configurable | Visitor searched a product (ecommerce RAG) |
returned_visitor | 50 | At least the 2nd session (heavy on purpose) |
pages_visited_exceeded | 50 | Session pages > lead_score.pages_visited_threshold |
notification_sent | configurable | A notification has already fired for this visitor |
Exact non-50 defaults (booked_meeting / shared_email / shared_phone / the configurable signals) are tenant-tunable and the shipped numeric defaults should be confirmed against
CompanyModel'slead_scoreschema — verify before quoting precise numbers. The two firmly-documented defaults arereturned_visitor = 50andpages_visited_exceeded = 50.
Threshold & related settings
| Setting | Default | Effect |
|---|---|---|
companies.lead_score.threshold | configurable | The implicit hot-lead threshold; crossing it fires notifications |
lead_score.pages_visited_threshold | 3 | Pages-per-session above which pages_visited_exceeded (+50) fires |
call_greater_than / chat_greater_than seconds | configurable | Duration thresholds for those signals |
companies.knox.high_value_pages[] | — | Pages that trigger visited_heigh_intent_page |
companies.knox.target_market | — | Industry tag matched for industry_match |
Editing weights (QA/support)
Settings → Lead Scoring (admin-side). Each signal exposes a toggle, a numeric weight (typically 0–200), and a threshold where relevant. If a tenant says "scoring looks wrong," check which signals are enabled, their weights, and whether high_value_pages[] is polluted with low-intent pages.
Hot-lead notification channels
When the threshold is crossed, the system can: send a Slack message (if notifications.slack_hot_lead = true), send an email, push via FCM, and fire a webhook (hot_lead_identified; also lead_score_changed). Routed via SlackService, FcmService, EmailQueueService in backend.
Behaviors & edge cases
- Anonymous visitors accumulate score normally; the score moves to their
PersonProfileonce identified. returned_visitoronly fires across a session boundary (1+ hour gap) — multiple sessions same day are still separate for scoring, but the return bonus needs the gap. The +50 weight often pushes a known visitor over the line on visit 2.- AI-only conversations count — accepting an AI auto-trigger is an explicit engagement signal.
- Score is rule-based, not a learned conversion probability. A Low-score visitor can still be a great customer (early in research).
- Score can climb mid-session — a Medium → High jump while browsing is a real-time buying signal.
- Misconfigured
high_value_pages[]pollutes scoring — keep low-intent pages out of it.
Plan & limits
- Lead scoring is available on all plans; weights and thresholds are tenant-configurable.
- Defaults work out of the box but need tuning per business — one tenant's "hot" is not another's. Signals that depend on enrichment (
industry_match) or ecommerce search (product_searched) only fire if those features/integrations are active.
Technical implementation
- Config:
companies.lead_score(per-signal weights +threshold+pages_visited_threshold) onCompanyModel. - Accumulator:
user_sessions.lead_score(per-session rolling total) inms-sessions;visitor_profiles.engagement_score(lifetime) updated by the recording-analysis rollup. - Notifications:
backendSlackService/FcmService/EmailQueueService; webhook eventshot_lead_identified,lead_score_changed. - Score visibility surfaces: Dashboard → Hot Leads (top-N, server-paginated, sort by total), Live Sessions (badge per row), Recorded Sessions (detail), Identity → Person Detail (per session + lifetime), and webhook payloads.
- Nox tools:
knox-visitor-profile,knox-stats(metric=hot_leads),knox-aggregate(metric=hot_leads)— current score, which signals fired, hottest leads this week, and why a visitor isn't ranking (signal breakdown). - Subsystems: feeds Identity Graph and Session Recording signals.
Related
- Leads — Overview — sources, categories, lifecycle
- Lead Intelligence —
industry_matchdepends on enrichment - Per-Session Signals — the behaviors that feed scoring
- Booking Sources —
booked_meetingis a top-weight signal - ms-sessions · Identity Graph