Engineering • Behavioral Model Series
Part 1 of 10

Scoring Intent, Frustration, and Engagement in Real Time

The three foundational behavioral models: how ClickStream classifies what users want, detects when they are struggling, and measures how deeply they are engaging -- all within milliseconds at the edge.

March 2026

Introduction Part 1: Intent, Frustration & Engagement Part 2: Value & Anomaly Part 3: Confusion & Emotion Part 4: Decision & Regret Part 5: Churn & LTV Part 6: Abandonment & Timing Part 7: Affinity, Friction & Next Action Part 8: Momentum, Entropy & Attention Part 9: Conversion, Hover & Scroll Part 10: Price, Loyalty, Micro-Conversion & Bot Detection

What You'll See in the Dashboard

In the Intelligence tab at einstein.clickstream.com, Intent, Frustration, and Engagement scores appear as real-time cards for each active visitor. Scores range from 0–100 with color coding: green (0–30), amber (31–60), red (61–100) for risk scores like Frustration (reversed for positive scores like Intent and Engagement). Click any score card to see its trend chart and contributing signals.

Business Actions: Configure threshold alerts in Settings → Alerts to trigger webhooks, Slack messages, or email notifications when scores cross your thresholds. Use the Intelligence → Rules engine for real-time personalization based on score combinations.

Model 1: Intent Classification

The intent score predicts the likelihood that a visitor will complete a conversion action during their current session. It answers the question every marketing and product team asks: Is this user going to buy?

Rather than relying on a single signal, the intent model combines multiple weighted behavioral indicators that collectively paint a picture of user motivation.

Intent Signal Weights

Each behavioral signal contributes to the overall intent score with a calibrated weight. These weights were derived from analysis across thousands of sites and are continuously refined.

SignalWeightDescription
Product page depth0.25Number of product/service pages viewed relative to session total
Cart/pricing interaction0.20Any interaction with cart, pricing page, or plan comparison
Return visit frequency0.15Number of sessions in past 7 days (normalized)
Search refinement0.12Number of search queries with filter adjustments
Time on high-value pages0.10Dwell time on product/pricing pages vs. informational pages
Scroll depth on product pages0.08Average scroll depth on product-category pages
Form field engagement0.06Interaction with checkout/signup form fields
Direct navigation0.04Navigating directly to deep pages (bookmarks, typed URLs)

Intent Categories

The raw intent score (0–100) maps to five categorical intent levels, each with distinct implications for real-time action:

Score RangeCategoryBehavioral PatternRecommended Action
0–15BrowsingCasual exploration, no product focusContent engagement, educational CTAs
16–35ResearchingMultiple product pages, some comparisonSocial proof, comparison guides
36–55EvaluatingDeep product engagement, pricing viewsCase studies, ROI calculators
56–80ReadyCart additions, form starts, repeated pricingUrgency messaging, limited offers
81–100ImminentCheckout initiated, payment field focusRemove friction, ensure smooth checkout

Practical Application

TypeScript
function classifyIntent(features: BehavioralFeatures, context: SessionContext): number { let score = 0; // Product page depth (weight: 0.25) const productRatio = features.productPageViews / Math.max(features.pageViewCount, 1); score += productRatio * 25; // Cart/pricing interaction (weight: 0.20) if (features.cartInteractions > 0) score += 12; if (features.pricingPageViews > 0) score += 8; // Return visit frequency (weight: 0.15) const returnBoost = Math.min(context.previousSessions / 5, 1) * 15; score += returnBoost; // Search refinement (weight: 0.12) const searchScore = Math.min(features.searchRefinements / 3, 1) * 12; score += searchScore; // Time on high-value pages (weight: 0.10) const timeRatio = features.highValueDwellTime / Math.max(features.sessionDuration, 1); score += timeRatio * 10; // Scroll depth on product pages (weight: 0.08) score += (features.productPageScrollDepth / 100) * 8; // Form field engagement (weight: 0.06) if (features.formFieldsInteracted > 0) score += 6; // Direct navigation (weight: 0.04) if (context.referrerCategory === 'direct') score += 4; // Apply frustration dampening const frustrationPenalty = frustrationScore * 0.3; score = Math.max(0, score - frustrationPenalty); return Math.min(100, Math.round(score)); }

Model 2: Frustration Detection

The frustration score quantifies how much friction a user is experiencing. High frustration correlates with abandonment, negative brand perception, and support ticket generation. Detecting it in real time lets you intervene before the user leaves.

The 9 Frustration Signals

Each signal is independently weighted and decayed over time. Recent frustration events carry more weight than older ones (exponential decay with a 90-second half-life).

SignalWeightDetection MethodThreshold
Rage clicks0.203+ clicks within 500ms on same element≥1 occurrence
Dead clicks0.15Click on non-interactive element with no DOM response≥2 occurrences
Error encounters0.15JS errors, 4xx/5xx responses, failed form submissions≥1 occurrence
Cursor thrashing0.12Rapid mouse direction changes (>4 reversals/sec)≥3 seconds sustained
Excessive scrolling0.10Scroll reversal rate >2x normal for page lengthRolling 10s window
Form re-entry0.08Same field cleared and re-entered >2 times≥1 field affected
Back-button pogo-sticking0.08Navigating forward then immediately back (<5s)≥2 occurrences
Prolonged inactivity after error0.07No interaction for 15+ seconds following an error event≥1 occurrence
Tab switching after frustration0.05Tab hidden within 3s of a frustration signal≥1 occurrence

Frustration Signal Storage

Each frustration event is recorded with enough context to enable post-hoc analysis and UX debugging:

TypeScript
interface FrustrationEvent { signalType: 'rage_click' | 'dead_click' | 'error' | 'cursor_thrash' | 'scroll_thrash' | 'form_reentry' | 'pogo_stick' | 'post_error_freeze' | 'frustration_tab_switch'; timestamp: number; pageUrl: string; elementSelector?: string; decayedWeight: number; // weight after time decay applied rawWeight: number; // original signal weight }

Frustration × Intent Interaction Matrix

The frustration and intent scores interact in ways that are diagnostically valuable. This matrix shows how to interpret the combination:

Low Frustration (0–30)Medium Frustration (31–60)High Frustration (61–100)
Low Intent (0–30)Normal browsing. No action needed.Confused browser. Show help/navigation aids.Lost user. Proactive chat or exit survey.
Medium Intent (31–60)Healthy evaluation. Nurture with content.Struggling evaluator. Simplify comparison.At-risk researcher. Immediate UX intervention.
High Intent (61–100)Smooth path to purchase. Minimize friction.Motivated but struggling. Fix checkout UX.Critical: high-value user about to abandon.

Model 3: Engagement Scoring

The engagement score measures the depth and quality of a user's interaction with your content. Unlike simple time-on-page metrics, engagement scoring accounts for active vs. passive time, interaction diversity, and content consumption patterns.

The 8 Engagement Signals

SignalWeightWhat It Captures
Active time ratio0.20Time with mouse/keyboard activity vs. total time on page
Scroll depth progression0.18How far down the page the user scrolled (0–100%)
Interaction diversity0.15Count of distinct interaction types (click, scroll, hover, type, select)
Content consumption rate0.12Estimated words read based on scroll speed and pause patterns
Meaningful click ratio0.10Clicks on interactive elements vs. total clicks
Session depth0.10Number of pages viewed with engagement > threshold
Return engagement0.08Higher scores for returning visitors who engage deeper
Cross-content exploration0.07Visiting diverse content categories (not just one section)

The Tab Visibility Problem

One of the biggest challenges in engagement scoring is tab visibility. A user with your page open in a background tab is not engaged, even though their session timer is running. ClickStream solves this with the Page Visibility API:

TypeScript
function calculateActiveTime(events: VisibilityEvent[]): number { let activeMs = 0; let lastVisible: number | null = null; for (const event of events) { if (event.state === 'visible' && lastVisible === null) { lastVisible = event.timestamp; } else if (event.state === 'hidden' && lastVisible !== null) { activeMs += event.timestamp - lastVisible; lastVisible = null; } } // If tab is still visible, count time to now if (lastVisible !== null) { activeMs += Date.now() - lastVisible; } return activeMs; }

Engagement Trajectories

Rather than just the current engagement score, ClickStream also tracks the trajectory -- whether engagement is increasing, stable, or declining. This is computed as the slope of a linear regression over the last 5 score updates.

TrajectorySlope RangeInterpretation
Rising>+2.0/minUser is becoming more engaged. Content is resonating.
Stable-2.0 to +2.0/minConsistent engagement level. User has found their rhythm.
Declining<-2.0/minInterest is waning. Consider content refresh or CTA.
Spike-then-dropPeak followed by rapid declineUser found what they needed (or got frustrated). Check frustration score.

How the Three Scores Interact

Intent, frustration, and engagement are not independent. They form a diagnostic triangle that tells you what the user wants, how they are experiencing your site, and whether they are connecting with your content.

The Four Behavioral Archetypes

Combining the three foundational scores reveals four primary behavioral archetypes:

1. The Smooth Buyer

High intent + Low frustration + High engagement

This is your ideal user. They know what they want, your site is working for them, and they are deeply engaging with relevant content. Action: clear the path to checkout and minimize distractions.

2. The Struggling Converter

High intent + High frustration + Medium engagement

This user wants to buy but is fighting your UX. They are engaged enough to keep trying, but frustration is building. Action: immediate UX intervention -- proactive chat, simplified checkout, or error resolution.

3. The Passive Explorer

Low intent + Low frustration + Low engagement

A casual visitor who is not encountering problems but also not connecting deeply. They may be comparison shopping or arrived via a broad search. Action: content-based engagement -- blog posts, guides, social proof.

4. The Frustrated Bouncer

Low intent + High frustration + Declining engagement

A user who arrived with some interest but is now fighting the experience and losing interest. They are the most likely to leave negative reviews or never return. Action: exit survey, proactive support, follow-up email with a direct link to what they were looking for.

Real-World Example: E-Commerce Session

Let us walk through a complete e-commerce session to see how the three scores evolve together across six key events:

Event #ActionIntentFrustrationEngagementArchetype
1Lands on homepage from Google search12015Passive Explorer
2Navigates to product category, scrolls 80%28042Active Researcher
3Views 3 product pages, compares specs52565Engaged Evaluator
4Adds to cart, clicks checkout78572Smooth Buyer
5Checkout form: rage-clicks submit (validation error)714558Struggling Converter
6Fixes error, completes purchase952870Recovered Buyer

Notice how the frustration spike at event 5 temporarily suppressed the intent score (from 78 to 71). ClickStream would have triggered a real-time alert at this point, potentially offering a proactive chat widget or a clearer error message. When the user recovered, both scores normalized -- but the frustration event remains in the session record for post-hoc UX analysis.

The interplay between these three scores provides a diagnostic toolkit that traditional analytics simply cannot match. You do not just know that a user bounced -- you know why, and you can intervene before they do.

Configuration & Tuning

All three models expose configurable parameters through the ClickStream dashboard:

Previous in Series ← Series Introduction

Know Exactly When Your Visitors Are Ready to Buy

Real-time intent scoring tells you who is converting, who is frustrated, and who needs a nudge. Stop guessing and start closing.

GET EARLY ACCESS