PQL scoring in HubSpot
Score PQLs in HubSpotUsing real product behavior.
A working PQL model takes 4 to 6 events, the right HubSpot property structure, and one workflow. This is the version that actually fires the right alerts at the right time, and the one we walk every Zoody customer through in the first week.
The problem with scoring free users
Most B2B SaaS companies on HubSpot are still scoring leads on form-fills, email opens, and pricing-page visits. That worked when sales had to call every lead. It does not work when 5,000 people sign up for the free tier every month and 4,950 of them will never pay.
The signal you actually need is whether they are getting value from the product. Did they reach activation? Are they coming back? Did they invite a teammate? Did they hit a usage threshold that pre-paid users hit before upgrading? Those are the signals that predict conversion. They live in the product, not in marketing.
Getting them into HubSpot historically meant a data warehouse, an analytics engineer, a reverse ETL pipeline, and three months of work. Most teams never get there. They run their PLG motion on instinct and HubSpot workflows that fire on form submissions, which is why the conversion rate from free to paid sits at 2% instead of 8%.
What a working PQL setup looks like
Five elements. Skip any of them and the model degrades within a quarter.
A short list of qualifying events
Four to six product events that correlate with conversion. Not 30. The shorter the list, the easier it is to debug, defend in a pipeline review, and update.
HubSpot properties for each input
One property per event aggregation, plus the rolled-up score. Named consistently (zo_ prefix is the convention we recommend) so RevOps can audit what's feeding the score.
A scoring formula with weights
Each event contributes a fixed weight to the score. Sum, threshold-based, or weighted. The math runs in Zoody and writes the result; HubSpot doesn't need to know the formula.
A workflow on score crossing
When zo_pql_score crosses a threshold (commonly 50), the workflow fires: change lifecycle stage, alert sales, drop into a sequence. The score is the trigger, not the destination.
Concrete setup walkthrough
Real HubSpot property names, real workflow logic, copy-paste ready.
- 1
Pick the events that signal real value
Look at your closed-won versus closed-lost from the last 6 months. What did the closed-won users do in the product before converting that closed-lost users didn't? That's your event list. Most B2B SaaS lands on activation_completed, invited_teammate, hit_key_action_3_times, visited_pricing, and one industry-specific event.
- 2
Create the input properties in HubSpot
Add zo_activation_completed (boolean), zo_invited_teammate (boolean), zo_key_actions_7d (number), zo_pricing_visits_7d (number), and any other inputs as contact properties. Group them under a 'Product activity' property group so they're easy to find. Each property should have a description like 'Set by Zoody from event X.'
- 3
Map events to properties in Zoody
In Zoody's mapping UI, point each product event at the matching HubSpot property. For activation_completed, map to a boolean with 'last value' aggregation. For key actions, map to a number with 'count in last 7 days' aggregation. Save and Zoody starts writing within 30 seconds.
- 4
Add zo_pql_score and configure the formula in Zoody
In Zoody, define zo_pql_score as a computed property: 30 if zo_activation_completed, plus 15 if zo_key_actions_7d >= 3, plus 10 if zo_invited_teammate, plus 10 if zo_pricing_visits_7d >= 1. Cap at 100. Zoody recomputes whenever an input changes and writes the result to HubSpot.
- 5
Build the HubSpot workflow on score crossing
In HubSpot Workflows, trigger on zo_pql_score crossing 50. Branch by company size if you want different routes (mid-market gets AE assignment, SMB drops into sequence). Add a Slack notification step using HubSpot's Slack integration so the AE sees the alert in real time. Done.
Worked example: Acme
A fictional B2B SaaS, 3,000 free signups per month, ACV around $12k.
Acme defines a PQL as a free trial user with zo_pql_score >= 50. The score is computed in Zoody from these contributions:
| Input property | Condition | Weight |
|---|---|---|
| zo_activation_completed | = true | +30 |
| zo_logins_7d | >= 3 | +15 |
| zo_invited_teammate | = true | +10 |
| zo_pricing_visits_7d | >= 1 | +10 |
| zo_key_event_count_7d | >= 5 | +15 |
A user who completed activation, logged in 4 times in the last 7 days, invited a teammate, visited pricing once, and hit the key event 6 times scores 80. That crosses the threshold and triggers the workflow.
Result after 90 days: Acme's free-to-paid conversion went from 2.1% to 5.4%. AE response time on hot PQLs dropped from 18 hours to under 1 hour because the Slack alert fires the moment the score crosses 50, not at the next morning's pipeline review.
What this enables
Slack alerts when a PQL is hot
HubSpot workflow fires a Slack DM to the AE the second zo_pql_score crosses 50. Sales no longer waits for the morning pipeline review.
Sales rep notifications inside HubSpot
Owner notifications, mobile push, and CRM tasks all trigger off the same score property. No CSV pulls, no 'who owns this lead' questions.
Lifecycle stage automation
Score >= 50 promotes the contact from Lead to MQL. Score >= 75 promotes to SQL with AE assignment. The funnel stages reflect actual product behavior.
Frequently asked questions
What is a PQL versus an MQL?+
An MQL is qualified by marketing engagement: visited the pricing page, downloaded an ebook, attended a webinar. A PQL (product-qualified lead) is qualified by what they did inside the product: signed up, activated, hit a usage threshold, invited a teammate. PQL scoring is more reliable because product behavior is harder to fake than form-fills.
Where does the actual scoring math run?+
Recommended: in Zoody, before the score lands in HubSpot. Zoody can compute weighted, time-decayed, rolling-window scores from the underlying events and write a single zo_pql_score property to HubSpot. HubSpot workflows then act on that score. You can also do simpler scoring inside HubSpot using calculated properties, but anything beyond a flat sum starts to feel constrained.
How often should the score recalculate?+
For trial-window scoring, daily is usually enough but real-time is better when sales acts on the threshold the same day. Zoody recomputes whenever a contributing event lands, so the score reflects current activity within seconds. HubSpot workflows can fire on score crossings the moment they happen.
Should every product event get a weight?+
No. The minute you weight 30 events, the score becomes opaque and impossible to debug. Pick 4-6 events that genuinely correlate with conversion. Skim, ignore the rest. Revisit weights once a quarter based on closed-won versus closed-lost analysis.
How do I avoid PQL score inflation as the model gets older?+
Use rolling-window aggregations rather than lifetime totals. zo_logins_7d resets pressure naturally. zo_lifetime_logins keeps growing forever and ends up scoring inactive users as PQLs because they used the product two years ago. Time-decay is your friend.
Build your PQL model this week
Beta cohort is small and we work directly with you on the first model. By the end of week one, the score is in HubSpot and the workflow is firing. Free while you're in.