Real-Time Intent Scoring & Hot Lead Alerts
Real-Time Intent Scoring & Hot Lead Alerts
NurtureHub continuously scores every contact's intent based on how they interact with your email sequences. When a contact's score crosses your configured threshold, agents and admins are alerted immediately — no manual review required.
How It Works
1. Score Calculation
A score is recalculated automatically after every engagement event (open, click, reply). Scores range from 0 to 100.
Each event type carries a fixed point value:
| Event | Points | Notes |
|---|---|---|
| Email opened (first time) | +5 | Per unique email |
| Email opened (repeat) | +2 | Subsequent opens of the same email |
| Email 2 opened | +8 | Recency bonus for sequence position 2 |
| Link clicked | +15 | First click of a given link |
| Email 3 clicked | +20 | Recency bonus for sequence position 3 |
| Booking link clicked | +30 | Strongest single engagement signal |
| Email replied | +25 | Direct reply to any sequence email |
All other tracked event types use their configured weight from the engagement events table.
2. Category Multipliers
The raw point total is multiplied based on the contact's assigned category, reflecting the relative urgency of each lead type:
| Category | Multiplier |
|---|---|
| Active Seller | ×1.5 |
| Seller | ×1.3 |
| Buy-to-Let Investor | ×1.2 |
| Buyer | ×1.0 |
Multipliers are configurable per tenant via the lead scoring settings.
3. Time Decay
Scores decay over time for inactive contacts to prevent stale data from triggering false alerts.
- Decay begins after the tenant's configured decay window (default: 30 days of inactivity).
- Once the decay window has passed, the score reduces at the configured decay rate (default: 10% per week).
- A daily background job runs at 02:00 UTC to recalculate scores for all contacts that have entered their decay window.
- The decay cron processes up to 5,000 contacts per run, in batches of 100.
4. Hot Lead Threshold
When a contact's score reaches or exceeds the hot threshold (default: 60), NurtureHub fires a hot lead alert. The threshold is configurable per tenant in Settings → Lead Scoring.
Once an alert fires, it will not fire again for the same contact until the score resets — preventing alert fatigue.
Hot Lead Alerts
When the hot threshold is crossed, two things happen simultaneously:
In-App Notifications
An in-app notification is created for every admin and owner in your organisation, visible in the NurtureHub dashboard.
Email Alert
An alert email is sent to:
- The agent assigned to the contact, if one exists.
- Otherwise, the first available org admin.
The email includes the contact's name, category, intent score, and a direct link to their contact record.
CRM Writeback
A hot_alert_fired event is queued to write back to the connected CRM (agentOS, Reapit, Alto, etc.), keeping your CRM records in sync.
Configuration
The following settings can be configured per tenant:
| Setting | Default | Description |
|---|---|---|
hotThreshold | 60 | Score at which a hot alert fires |
decayAfterDays | 30 | Days of inactivity before score decay begins |
decayRate | 10% | Weekly decay rate once decay window is exceeded |
| Category multipliers | See above | Per-category score weighting |
Settings are managed under Settings → Lead Scoring in the dashboard.
Event Architecture
email/engagement.received
└─► email-engagement-processor
└─► lead/score.recalculate
└─► intent-scorer
├─► upsert leadScores
└─► [score ≥ hotThreshold AND alert not yet fired]
├─► create hotAlerts record
├─► notification/hot.alert.dispatch
│ └─► hot-alert-dispatch
│ ├─► platformNotifications (all admins/owners)
│ └─► sendEmail (assigned agent or first admin)
└─► crm/writeback.queue → hot_alert_fired
score-decay (daily cron, 02:00 UTC)
└─► fan-out lead/score.recalculate for stale contacts
Notes
- Alert dispatch is idempotent: if an alert record is already in a non-
pendingstate, the dispatch step is skipped. - Email alerts degrade gracefully if no recipients are available or no email provider is configured.
- The
calculateIntentScore()function is exported as a pure function and can be called independently for testing or manual score refreshes.