skip to content
san.is
Table of Contents

HubSpot’s lead scoring can’t include Custom Events. I spent an hour looking for the option before accepting that it genuinely doesn’t exist. An hour I’ll never get back.

If you’re tracking product usage, login frequency, or in-app behaviour through Custom Events and want those signals in your lead score, there’s no dropdown for that. But there’s a workaround — and it’s now running in three of my enterprise implementations.

The Lead Scoring Landscape in 2025

Before diving into the solution, let’s clarify what’s happening with HubSpot lead scoring. There’s been significant change recently.

The Score Property Sunset

HubSpot is retiring the legacy score properties:

DateChange
May 1, 2025Cannot create new score properties
July 1, 2025Cannot edit existing score properties
August 31, 2025Existing score properties stop updating

If you’re reading this before August 2025, you have time to migrate. If after, you’re already on the new system.

The New Lead Scoring Tool

HubSpot’s replacement separates scoring into two distinct dimensions:

Fit Score — How well does this record match your ICP? Based on demographic and firmographic properties like industry, company size, job title, and revenue.

Engagement Score — How actively is this record interacting with your brand? Based on behavioural events like email opens, page views, form submissions, and meeting bookings.

This is conceptually cleaner than the old single-score model. But it still has gaps. Gaps you’ll discover at the exact moment you need them not to exist.

The Custom Events Problem

Custom Events (formerly Custom Behavioral Events) let you track virtually anything:

  • Product logins and feature usage
  • In-app actions and milestones
  • Third-party system events via API
  • JavaScript-tracked interactions beyond standard HubSpot tracking

You can create up to 500 unique custom events per portal. They appear in contact timelines, can trigger workflows, and work with lists.

But here’s the gap: The native lead scoring tool has limited support for custom events in its criteria. Specifically:

  1. You can’t use “contains” logic on event names (e.g., “any event where name contains ‘upgrade’”)
  2. Event property filtering is limited
  3. Aggregate counting (e.g., “completed event X more than 5 times in 30 days”) requires workarounds
  4. Legacy custom behavioral events work differently from new custom events

The HubSpot Ideas forum has been asking for better custom event integration in scoring since 2020. Progress has been made, but for complex scoring requirements, you’ll likely need to augment the native tool.

The Workflow-Driven Scoring Pattern

The solution is to use workflows as your scoring engine, with custom number properties storing the calculated scores.

Architecture Overview

┌─────────────────────────────────────────────────────────────┐
│ CUSTOM EVENTS │
│ (Product usage, app interactions, external system events) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ SCORING WORKFLOWS │
│ • Event triggers increment/decrement score properties │
│ • Time-based decay via scheduled workflows │
│ • Aggregate logic via branching │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ CUSTOM SCORE PROPERTIES │
│ • Behavior Score (number, workflow-controlled) │
│ • Engagement Score (number, workflow-controlled) │
│ • Combined Score (calculated field) │
└─────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────┐
│ DOWNSTREAM ACTIONS │
│ • Lifecycle stage updates │
│ • Sales notifications │
│ • List membership for segmentation │
│ • Native HubSpot lead score (optional hybrid) │
└─────────────────────────────────────────────────────────────┘

Step 1: Create Score Properties

Create custom contact properties to hold your workflow-calculated scores:

PropertyTypeDescription
behavior_scoreNumberPoints from behavioural events
fit_scoreNumberPoints from demographic attributes
engagement_velocityNumberRecent engagement intensity
total_lead_scoreCalculationbehavior_score + fit_score

For the calculated property, use this formula:

behavior_score + fit_score

You can also add weighting:

(behavior_score * 0.6) + (fit_score * 0.4)

Step 2: Build Event-Triggered Scoring Workflows

Create workflows that trigger when custom events occur and increment the appropriate score.

Example: Product Login Scoring

Workflow: [Scoring] Product Login
Trigger: When event occurs → Custom Events → "app_login"
Re-enrollment: Yes, every time
Actions:
1. Increase property value
- Property: behavior_score
- Increase by: 5
2. Branch: If behavior_score > 200
- Yes → Set behavior_score to 200 (cap)
- No → Continue

Example: Feature Usage Scoring

Workflow: [Scoring] Premium Feature Used
Trigger: When event occurs → Custom Events → "feature_used"
AND event property "feature_tier" equals "premium"
Re-enrollment: Yes, every time
Actions:
1. Increase property value
- Property: behavior_score
- Increase by: 15
2. Increase property value
- Property: engagement_velocity
- Increase by: 1

Step 3: Implement Score Decay

Scores should decrease over time if engagement stops. Without decay, a contact who was highly engaged two years ago still appears valuable. They’re not. They’ve forgotten who you are.

Option A: Scheduled Workflow (Simple)

Workflow: [Scoring] Weekly Score Decay
Trigger: Contact-based → Scheduled → Every Monday at 6:00 AM
Enrollment: All contacts where behavior_score > 0
Actions:
1. Decrease property value
- Property: behavior_score
- Decrease by: 5
2. Branch: If behavior_score < 0
- Yes → Set behavior_score to 0
- No → Continue

Option B: Time-Since-Event Decay (Advanced)

For more sophisticated decay based on time since last engagement:

Workflow: [Scoring] Engagement Decay Check
Trigger: Contact-based → Scheduled → Daily at 2:00 AM
Enrollment: All contacts where behavior_score > 0
Actions:
1. Branch: Days since last event > 30
- Yes → Decrease behavior_score by 20
- No → Continue to next branch
2. Branch: Days since last event > 14
- Yes → Decrease behavior_score by 10
- No → Continue
3. Branch: If behavior_score < 0
- Yes → Set behavior_score to 0

Step 4: Handle Score Caps and Floors

Prevent scores from going negative or exceeding sensible limits:

Workflow: [Scoring] Score Bounds Check
Trigger: Property value changed → behavior_score
Re-enrollment: Yes
Actions:
1. Branch: behavior_score > 200
- Yes → Set behavior_score to 200
2. Branch: behavior_score < 0
- Yes → Set behavior_score to 0

Step 5: Trigger Downstream Actions

Use score thresholds to drive lifecycle changes and notifications:

Workflow: [Lifecycle] MQL Qualification
Trigger: Filter-based → total_lead_score >= 100
AND lifecycle_stage is any of [Subscriber, Lead]
Re-enrollment: No
Actions:
1. Set lifecycle stage to "Marketing Qualified Lead"
2. Create task for sales
- Title: "New MQL: [Contact Name]"
- Assigned to: Contact owner
- Due: Today
3. Send internal notification email
- To: Sales team
- Subject: "High-scoring lead ready for outreach"

Handling the “Contains” Problem

One of the most common requirements is scoring based on event name patterns. For example:

  • Score any event containing “upgrade” in the name
  • Score all “webinar_” prefixed events the same way
  • Score different “feature_used” events differently based on properties

Pattern: Event Name Routing Workflow

Since you can’t filter by “event name contains”, create a router workflow:

Workflow: [Scoring] Event Router
Trigger: When event occurs → Any Custom Event
Re-enrollment: Yes, every time
Actions:
1. Branch: Event name equals "upgrade_prompt_shown"
- Yes → Increase behavior_score by 10
2. Branch: Event name equals "upgrade_button_clicked"
- Yes → Increase behavior_score by 25
3. Branch: Event name equals "upgrade_completed"
- Yes → Increase behavior_score by 50
4. Branch: Event name starts with "webinar_"
- Yes → Increase behavior_score by 15
5. Branch: Event name starts with "feature_used"
- Yes → Go to sub-branch on feature_tier property
- "premium" → +15 points
- "standard" → +5 points
- Other → +2 points

Note: You’ll need to update this workflow whenever you add new event types you want to score. Document your scoring logic externally so the team knows what’s being tracked. Future you will thank present you.

Aggregate Scoring: “5+ Events in 30 Days”

The native scoring tool struggles with aggregate requirements like “score contacts who have completed event X at least 5 times in the last 30 days.”

Solution: Counter Properties + Scheduled Reset

Step 1: Create counter property

Property: webinar_registrations_30d (Number)

Step 2: Increment on event

Workflow: [Counter] Webinar Registration
Trigger: When event occurs → "webinar_registered"
Re-enrollment: Yes
Actions:
1. Increase webinar_registrations_30d by 1

Step 3: Reset counter monthly

Workflow: [Counter] Monthly Reset - Webinars
Trigger: Scheduled → 1st of each month at 1:00 AM
Enrollment: All contacts
Actions:
1. Set webinar_registrations_30d to 0

Step 4: Score based on counter

Workflow: [Scoring] High Webinar Engagement
Trigger: Filter-based → webinar_registrations_30d >= 5
Re-enrollment: No (or Yes with suppression list)
Actions:
1. Increase behavior_score by 30
2. Add to list "High Webinar Engagement"

This pattern is more manual than native scoring but gives you precise control over aggregate logic.

Velocity Scoring: Rewarding Engagement Bursts

Sometimes you want to reward contacts who show sudden spikes in engagement — visiting 10 pages in a day, or attending 3 events in a week.

Pattern: Rolling Engagement Window

Step 1: Track daily engagement

Workflow: [Velocity] Daily Engagement Counter
Trigger: Any engagement event (page view, email click, form submission)
Re-enrollment: Yes
Actions:
1. Increase engagement_today by 1

Step 2: Calculate velocity score nightly

Workflow: [Velocity] Nightly Velocity Calc
Trigger: Scheduled → Daily at 11:59 PM
Actions:
1. Branch: engagement_today >= 10
- Yes → Increase engagement_velocity by 20
- No → Branch: engagement_today >= 5
- Yes → Increase engagement_velocity by 10
- No → Decrease engagement_velocity by 2
2. Set engagement_today to 0 (reset for tomorrow)

Step 3: Use velocity in qualification

Add engagement_velocity to your MQL criteria alongside behavior_score. A contact with moderate lifetime engagement but high recent velocity might be more valuable than one with high historical engagement but no recent activity.

Hybrid Approach: Workflow Scores + Native Scoring

You don’t have to choose entirely between workflow-driven and native scoring. A hybrid approach works well:

Score TypeMethodUse For
Demographic/FitNative Lead ScoreIndustry, company size, job title, geography
Standard EngagementNative Lead ScoreEmail opens, page views, form submissions
Custom EventsWorkflow-drivenProduct usage, app events, third-party triggers
Aggregate/VelocityWorkflow-driven”5+ events in 30 days”, engagement spikes

Your final qualification logic can reference both:

MQL Criteria:
- Native HubSpot Score >= 50
- AND behavior_score >= 30
- AND (engagement_velocity >= 10 OR total_lead_score >= 100)

Performance Considerations

Workflow-driven scoring at scale requires attention to performance:

Workflow Execution Limits

  • HubSpot allows up to 500 workflow enrollments per contact per day
  • High-volume event tracking can hit this limit
  • Consider batching low-value events or sampling

Property Update Frequency

  • Score properties update nearly instantly for simple operations
  • Complex calculated properties may take up to 2 hours to recalculate
  • Build in tolerance for eventual consistency. Patience is a virtue.

Monitoring

Create a dashboard to monitor your scoring system:

  • Contacts by score tier (0-25, 26-50, 51-100, 100+)
  • Score distribution over time
  • MQL conversion rates by score range
  • Workflow error rates

Example: SaaS Product Usage Scoring

Here’s a complete example from a recent implementation for a B2B SaaS client:

Events Tracked

EventTriggerPoints
app_loginDaily login+5 (capped at 25/week)
feature_usedAny feature interaction+2 to +15 based on tier
integration_connectedConnects third-party tool+20
team_member_invitedInvites colleague+25
upgrade_page_viewedViews pricing/upgrade+10
support_ticket_createdOpens support ticket-5 (friction indicator)
export_dataExports their data-15 (churn risk signal)

Score Thresholds

Score RangeStageAction
0-25EvaluatingNurture sequence
26-50EngagedProduct tips sequence
51-100ActivatedCSM introduction
100+Power UserExpansion opportunity alert

Results

After 90 days:

  • 34% increase in CSM-initiated conversations with high-scoring accounts
  • 22% improvement in expansion revenue from score-triggered outreach
  • 45% reduction in time-to-first-contact for engaged trial users

Migration Path: Legacy to New Scoring

If you’re moving from legacy score properties to the new system (or workflow-driven scoring), here’s a migration checklist:

  1. Document current scoring logic — Export all criteria from existing score properties
  2. Map to new structure — Decide what goes in native Fit/Engagement vs workflow-driven
  3. Build new system in parallel — Don’t turn off old scoring until new is validated
  4. Compare scores — Run both systems for 2-4 weeks and compare MQL rates
  5. Validate with sales — Confirm new scores align with actual opportunity quality
  6. Cut over — Disable legacy scoring, update all downstream workflows and lists

Key Takeaways

  1. Native scoring has custom event limitations — Complex requirements need workflow augmentation
  2. Workflow-driven scoring gives full control — Event routing, aggregates, velocity, and decay
  3. Hybrid approaches work well — Use native for standard signals, workflows for custom events
  4. Build in decay — Scores without time decay become meaningless
  5. Monitor and iterate — Scoring models need regular validation against actual conversion data
  6. Legacy scores are sunsetting — Plan your migration before August 2025

If you’re building enterprise lead scoring in HubSpot and hitting the limitations of the native tool, the workflow pattern described here has worked reliably across multiple implementations. It’s not elegant, but it works — which, in enterprise software, is often the higher virtue.


What scoring patterns have you found effective in HubSpot? I’d be interested to hear other approaches — find me on LinkedIn.