Most companies buy new lists before they have used up the information they already have. That is almost always the wrong order.

A typical CRM holds several years of signals: who replied to email, who asked for a quote and never signed, which industries produced short sales cycles and which produced long ones. That is enough to sort a list by likelihood of a sale. Not perfect, but considerably better than calling alphabetically.

Start by defining what a good lead was

Before you build anything, you have to decide what the model is meant to predict. "Interesting customer" is useless. "Signed a contract within 90 days of the first meeting" is something you can measure in the database. Pick one such definition, write it down, and hold to it through the whole exercise.

Then you need history. Pull every lead from the last two or three years and mark each one as having met the definition or not. If you have fewer than a couple of hundred closed cases, drop the modelling and do this as a simple manual analysis instead — the numbers will not carry more than that.

Find the variables that separate

The goal is to find attributes where the winners and the losers behave differently. Industry, headcount, geography, which channel the lead arrived through, how long it took to respond, whether they made contact or were contacted. Calculate the conversion rate per value:

SELECT channel,
       COUNT(*)                                 AS total,
       SUM(CASE WHEN won = 1 THEN 1 ELSE 0 END) AS won,
       ROUND(100.0 * SUM(CASE WHEN won = 1 THEN 1 ELSE 0 END)
             / COUNT(*), 1)                     AS conv_pct
FROM   leads
WHERE  created >= DATEADD(year, -3, GETDATE())
       AND status IN ('won', 'lost')
GROUP  BY channel
HAVING COUNT(*) >= 30
ORDER  BY conv_pct DESC;

The HAVING line matters more than it looks. Without it, a category with four leads and two sales will top the list at 50 percent, and you will build strategy on noise. Set a minimum threshold and stick to it.

Build the scoring simply first

You do not need machine learning for a first version. Take the four or five variables that separated most clearly, give each of them points according to how much they lifted conversion, and add them up. A customer in the best industry, of the right size, who made contact themselves, gets a high score. The result is a sorted list a salesperson can work from the top down.

The advantage of the simple model is that it can be explained. When a salesperson asks why a lead sits in third place, there is an answer in plain language. That decides whether the model actually gets used, and use is the entire point.

A concrete points table

Say the analysis above gave four variables that separated clearly. The scoring can then look like this, with points set according to how much each value lifted conversion above the average:

Variable            Value                      Points
------------------  -------------------------  ------
Industry            Healthcare / public          +30
                    Industrial                   +15
                    Other                         +5
Headcount           50-250                       +25
                    250+                         +10
                    under 50                      +5
Channel             Inbound enquiry              +30
                    Referral                     +20
                    Cold outbound                 +0
Time to respond     under 4 hours                +15
                    same day                      +8
                    over 24 hours                -10

The sum gives a number between 0 and 100. Set two thresholds — say 60 and 35 — and you have three buckets: call today, call this week, get to it when you can. The salesperson does not have to deal with the number at all, only with which bucket the lead is in.

Note that "time to respond" is the only variable you control yourself. Strictly speaking it does not belong in a model meant to rank leads — it describes you, not the customer. But it is worth measuring anyway, because it often turns out to be the single factor that matters most to whether a lead becomes anything. In that case the answer is not better scoring, it is faster follow-up.

How to notice that the model is lying

A scoring model built on historical data inherits every bias in how sales has been run. If the sales team has always prioritised large customers, large customers will appear to convert better — not because they are better leads, but because they got more attention. The model will then recommend more of the same, and you have had your own working habits confirmed with numbers.

There is no elegant fix for this in a simple model, but there is a practical one: keep a small share of leads outside the scoring, chosen at random, and follow them up regardless of score. Over time they tell you what you would have missed. That is cheap insurance against building a machine that only sees what it was trained to see.

Data quality is the job

Expect a third of the time to go on discovering that the industry field is free text with twelve spellings of the same industry, that "won" was used differently before and after a reorganisation, and that some leads have no creation date. Clean this up first. A model built on a field nobody filled in consistently produces numbers that look precise and are not.

Put it where the work happens

A score that only exists in a spreadsheet will not be used. It has to go into the CRM, as a column on the lead and a sort option in the list the salesperson opens every morning. Technically this is a manageable job: a table for the scores, a query that calculates them nightly, and a field in the CRM that shows the result.

-- Nightly calculation, simplified
MERGE INTO lead_score AS m
USING (
    SELECT l.id,
           CASE l.industry WHEN 'healthcare' THEN 30
                           WHEN 'industrial' THEN 15
                           ELSE 5 END
         + CASE WHEN l.headcount BETWEEN 50 AND 250 THEN 25
                WHEN l.headcount > 250 THEN 10
                ELSE 5 END
         + CASE l.channel WHEN 'inbound'  THEN 30
                          WHEN 'referral' THEN 20
                          ELSE 0 END AS score
    FROM   leads l
    WHERE  l.status = 'open'
) AS k ON m.lead_id = k.id
WHEN MATCHED THEN UPDATE SET m.score = k.score, m.calculated = GETDATE()
WHEN NOT MATCHED THEN INSERT (lead_id, score, calculated)
                      VALUES (k.id, k.score, GETDATE());

Keep the calculation in one named place, not scattered through application code. The points will change as you learn more, and you will want one place to change them.

Measure the effect before scaling

Run the scoring alongside the current way of working for a quarter. Let half the leads be handled as before and half by score. Compare conversion rate and time to signature. If the difference is marginal, you learned that cheaply. If it is clear, you have an argument that holds up in a management meeting.

The most common wrong turn is jumping straight to buying a tool. A scoring model like this is a few queries, a table and a view in the CRM. The work is in defining the target and cleaning the data, not in the technology.

When the model should be retired

A scoring model is never finished. The market changes, the product changes, and an industry that converted well last year may have cut its budgets this year. Set a fixed date — every six months, say — when you run the same analysis on newer data and compare. If the variables that separated have swapped order, update the points. If none of them separate any more, that is a signal in itself: something other than customer attributes is deciding your sales.

The most important thing to take away is the order. Definition of a good lead, historical data, cleanup, analysis, simple scoring, measurement — and only then automation and tooling. Projects that start at the other end usually end with a system nobody trusts and a list nobody uses.