Customer story · Attribution & Lead Lifecycle

Scoring intent when nobody fills out a form: a behavioral MQL model and the attribution layer under it

A B2B software company sells into a small, finite target list where form fills are far too rare to qualify on. LeanScale built a capped behavioral scoring model with a title-specific persona multiplier, plus a metadata-driven UTM-to-channel attribution engine that stamps original, latest and MQL touch on the contact.

ProofWhat happened on a real engagement.
Fintech & Financial ServicesSector
Growth-stageStage
3–6 monthsDuration
7Min read

Anonymized. The company is described by sector and stage only — no customer is named, and quotes are attributed by role.

#The challenge

The target list was small and finite, and deals ran for years across a large, multi-function buying committee. In that shape, a form-fill-driven MQL funnel is the wrong instrument — there simply are not enough hand-raises to qualify on, and the ones that do arrive skew wrong because the generic contact form was dominated by existing end users of a separate self-serve product line rather than prospects. No scoring model existed at all, MQL and SQL had never been defined, and marketing had no way to tell leadership which accounts were warming. Underneath that, lead source and channel had never been modeled: there was nowhere on the record to say where an opportunity actually came from.

#The approach

Score the people who have not raised their hand

Demo and contact form fills already auto-stamped MQL through the existing web-form → automation → CRM path, and that was deliberately left alone. The behavioral score does not touch hand-raisers. Its entire job is to surface the contacts at target accounts who are evaluating quietly. Identity capture was likewise excluded as a scoring signal on the grounds that it is the prerequisite, not the signal.

Five signal groups collapsed to three

Version one used five groupings (high-intent pages, repeat engagement, key conversions, evaluation content, identity capture). Version two collapsed to three, on the reasoning that a twelve-signal model is unwarranted at this volume: G1 high-intent product and solution page views (three specific URLs), G2 repeat engagement, G3 evaluation content and gated downloads (a handful of case-study and build-versus-buy URLs). Each group is capped at 20 points; behavioral subtotal maxes at 60.

Points shaped around sessions, not raw pageviews

Within G1 and G3, a single pageview under thirty seconds scores 2; a single pageview at thirty seconds or more scores 5; two or more pageviews on scored URLs inside the same session score 8; and hitting two distinct scored URLs in one session adds a 3-point bonus. G2 counts distinct sessions in the rolling window, filtered to sessions with two or more events so bounces do not score: two sessions = 5, three to four = 10, five or more = 15, plus 5 if three sessions land inside any fourteen-day span. Gated downloads add 10 for the first and 3 for each additional.

Window sized to the sales cycle, not to convention

The rolling window was stretched from 90 days to 180 at the client's insistence — a three-month window against a multi-year cycle produces a score that is mostly noise.

A persona multiplier instead of a persona filter

The behavioral subtotal is multiplied by a title-specific tier: 1.5x for the champion / pain owner, 1.3x for influencers and evaluators, 1.1x for director-level secondary roles, and 0.7x for a low-propensity catch-all. Roughly a hundred titles were mapped by exact match against the client's own approved target-title list, with everything unmapped defaulting to the bottom tier. Notably, the catch-all deliberately contains marketing titles, implementation staff, executive assistants, individual-contributor technologists — and bare 'VP' and 'AVP', because a title with no function in it carries no buying signal. Maximum final score is 90; the MQL threshold was set at 30.

State the threshold in behaviour, not in points

The model was presented to the client's team as what 30 actually costs each persona: a top-tier persona MQLs on 20 behavioral points (one deep session, three return visits, one case study), a second-tier on 24, a third-tier on 28, and the catch-all needs 43 — which effectively cannot be reached without maxing two groups. The bottom tier therefore functions as a soft filter rather than a hard exclusion. That was intentional: the previous version had a 0x bucket, and v2 removed it so nobody becomes invisible, holding a hard-exclude rule in reserve if false positives appeared.

Anti-flap, decay and knockouts

Once MQL flips true it stays true until the score sits under 25 for thirty consecutive days, and the notification fires once on the false-to-true flip rather than on every nightly refresh. Existing end users, off-ICP accounts and unmatched free-mail addresses are scored but suppressed rather than routed. A set of self-service product events that an earlier strawman had been scoring were removed outright — those are existing-customer actions, and account status already flags them. A do-not-contact list and a known-competitor domain list were folded in with the client's marketing lead, alongside a score-decay rule for inactivity.

Identity is the gate — and it was the blocker

Before building further, LeanScale audited a full month of the incoming web-intent sample feed (roughly two thousand event rows across a few hundred unique visitors) and found the join fields entirely empty: zero populated hashed-email values, zero populated person-ids, no identity-capture events. Without a join key the whole pipeline had nothing to attach a score to. This was escalated as a hard blocker ahead of the sandbox date rather than discovered in production. The resolution was a hashed-email join key — a CRM formula reproducing the vendor's hash format on the contact record, a backfill for existing contacts, and an explicitly-flagged open problem for contacts created by hand in the UI, which the client's admin identified as the most common creation path.

Do the maths outside the CRM, keep the raw data inside it

Scoring runs in automation-platform code steps rather than in CRM Apex, on the reasoning that computation belongs where it is cheap to change. A new file landing in the SFTP folder triggers the run; the code parses the JSON, groups events by session, skips anything without an email hash, finds the matching contact, upserts a session record into a custom object (so multi-visit history is preserved and auditable), gathers that contact's sessions inside the window, computes the sub-scores, and writes the totals plus the MQL flag and timestamp back to the contact. A safeguard filters out person-account matches.

Attribution as a metadata table, not a hard-coded flow

UTMs are parsed out of the session landing URL in the same pipeline. Translation from raw UTM source / medium / campaign plus last-referring-site into channel grouping, channel and sub-channel is held in a CRM custom metadata object, and the flow simply reads it. Adding a new paid source, deprecating an old one, or re-grouping a channel is a record edit — the flow never gets touched. Blank UTMs default to direct; a UTM value with no matching mapping clears the fields and raises a notification rather than silently mis-stamping.

Original, latest and MQL touch on the contact

Three stamping behaviours on the same object: latest-touch fields update on every new inbound signal; original-touch fields are written once, only when blank; and MQL-touch fields copy the latest values at the moment MQL fires, freezing what actually converted the person. All three surface on a dedicated attribution tab on the contact layout. The persona tier table uses the same custom-metadata pattern as the channel mapping, with title normalization (expanding abbreviations such as VP and EVP) ahead of an exact-match lookup so multipliers can be re-tuned without a code change.

#Outcomes

A scoring model the client could argue with

Rather than a black box, the model was delivered as an explicit weights-and-caps table plus a worked example showing the same browsing behaviour MQL-ing for a buyer persona and not MQL-ing for a support-adjacent one. The client's marketing leadership reviewed the tier list, rejected the first pass on the grounds that generic technology titles were being valued above line-of-business buyers, and supplied their own target-title list, which became the source of the tiering.

Built and validated end to end in a sandbox

The full pipeline — intent feed to CRM to scoring to MQL flag to attribution stamping — ran in a partial sandbox with data flowing, with production cutover sequenced behind finalizing the hashed-email join key and the page layouts.

A recalibration plan shipped with the model

The MQL threshold went in at 30 with a written instruction to recalibrate to 35 if the queue ran noisy after thirty days of live data, rather than treating the first number as final.

A data gap caught before launch, not after

Auditing the vendor feed for join-key coverage before building the pipeline turned what would have been a silent zero-match production failure into a scoped upstream ask.

Attribution that is maintainable by the client

Channel mapping and persona tiering both live in editable metadata tables with the logic documented and handed over for the client's own internal knowledge base, so re-tuning does not require the consultant.

In their words

What the customer said

“We need to change the window from 90 to 180 days given our sales cycle. Unlikely to see any real traction in 3 months.”
“Need assurance from LeanScale/[our web-intent partner] that identity resolution against our [CRM] contact database will work at a meaningful match rate. If it doesn't, a significant portion of the model's signals fall away and the architecture needs to be reconsidered.”
“What's the point of building it all if we don't have something to populate it?”
The method behind it

This ran the Attribution playbook

The delivery standard this engagement followed.

Connected

In the knowledge graph

Every entity below has its own page, aggregating what we measured, what we recommend and what guests said.

Companies
Related

More on these topics

Method Revenue Systems

Attribution

Every Attribution project moves through the same four phases. Know what you produce in each — and know that, like CPQ, this is a project you win or lo…

32 sections · 20 min read
Method GTM Structure

Lead Routing

Every Lead Routing project moves through the same four phases. Know what you produce in each one. 1 Blueprint Pick the routing model, map the channels…

40 sections · 18 min read
Proof Attribution & Lead Lifecycle

Replacing weekly manual dashboard clean-up with nightly correction flows

A cybersecurity company's marketing-ops team was hand-correcting lead tier and channel values every week to keep dashboards defensible. LeanScale repl…

3 sections · 2 min read
Proof Attribution & Lead Lifecycle

When a picklist rename silently broke a dozen pipeline reports

A B2B software company could not reconcile what its BDR team generated with what its dashboards showed. LeanScale rebuilt inbound and outbound attribu…

3 sections · 2 min read
Proof Attribution & Lead Lifecycle

Closing the gap between MQL and pipeline

A growth-stage workforce-technology company was losing inbound leads and event contacts between MQL and pipeline, with attribution that did not agree …

3 sections · 2 min read
Proof Lead Routing & Speed-to-Lead

From an empty CRM to enrichment, territories and a live lead-routing engine

An AI company scaling its sales org fast had a nearly empty Salesforce: no enrichment, no territory model, no routing, and inbound piling up in a defa…

3 sections · 2 min read