Score and segment
Account tiers and a fit score you can explain.

Use a fit score you can explain to a sales rep in one sentence: four to six criteria, points written in a table, and tiers cut according to what your team can absorb. A model that outputs 73 with no reason attached gets ignored by the second week.
The example continues: payroll software for French SMEs, 6,000 accounts that passed the ICP filter, contacts being added. Every figure below is invented for the illustration.
Score fit and timing separately
Fit says whether a company could become a good customer, and it moves slowly. Timing says whether now is the moment, and it changes every week. Mix them in one number and a hiring spike at a poor-fit company outranks a perfect account having a quiet month.
This chapter builds the fit score. Intent signals come next, in their own column, and the two meet in a simple grid:
| Signal this month | No signal | |
|---|---|---|
| Tier A | Contact this week, personally | Planned sequence |
| Tier B | Move up to the front of the queue | Standard sequence |
| Tier C | Light sequence | Leave for later |
| Tier D | Nothing | Nothing |
Choose criteria your best customers can defend
Take your best customers, the ones from the ICP chapter, and compare how often each criterion appears among them and across the whole TAM. Lift is the first share divided by the second.
| Criterion | Share of best customers | Share of TAM | Lift |
|---|---|---|---|
| Three or more establishments | 46% | 15% | 3.1 |
| 100 to 249 employees | 58% | 22% | 2.6 |
| Target sectors | 38% | 17% | 2.2 |
| Located in Île-de-France | 24% | 22% | 1.1 |
A lift near 1 means the criterion doesn’t separate anything, so location goes. With fewer than 30 customers these ratios are fragile: use them as a guide and say openly that part of the grid is judgment.
Before scoring, apply the knock-outs. Existing customers, competitors, opt-outs and sectors you can’t serve get excluded = true and no score.
Write the grid and handle unknown values
| Criterion | Value | Points | Field |
|---|---|---|---|
| Headcount | 100 to 249 | 30 | headcount |
| 50 to 99 | 20 | ||
| 250 and up | 10 | ||
| Under 50 | 0 | ||
| Unknown | 15 | ||
| Sector | Target NAF codes | 25 | naf_code |
| Other | 5 | ||
| Establishments | 3 or more | 25 | establishments |
| 2 | 15 | ||
| 1 | 5 | ||
| Unknown | 12 | ||
| Payroll | Run in-house | 20 | payroll_mode |
| Unknown | 10 | ||
| Outsourced to an accountant | 0 |
Unknown gets about half the points. Give it zero and your score starts measuring how well your sources cover a company, which punishes exactly the small accounts your data sees badly. Add a score_completeness column with the share of criteria actually known, so a rep can tell a solid 80 from a guessed one.
In SQL, on your accounts table:
SELECT account_id,
CASE WHEN headcount IS NULL THEN 15
WHEN headcount >= 250 THEN 10
WHEN headcount >= 100 THEN 30
WHEN headcount >= 50 THEN 20
ELSE 0 END AS pts_size,
CASE WHEN naf_code IN ('4941A','5610A','8810A') THEN 25 ELSE 5 END AS pts_sector,
CASE WHEN establishments IS NULL THEN 12
WHEN establishments >= 3 THEN 25
WHEN establishments = 2 THEN 15
ELSE 5 END AS pts_sites,
CASE payroll_mode WHEN 'in_house' THEN 20
WHEN 'outsourced' THEN 0
ELSE 10 END AS pts_payroll
FROM accounts
WHERE excluded = FALSE;
In a sheet, one column per criterion and the total in the next. With headcount in E, then the reason column that makes the score readable:
=IF(E2="",15,IF(E2>=250,10,IF(E2>=100,30,IF(E2>=50,20,0))))
=TEXTJOIN(" / ",TRUE,"size "&F2,"sector "&G2,"sites "&H2,"payroll "&I2)
A restaurant group with 180 employees, two sites and an unknown payroll setup scores 30 + 25 + 15 + 10 = 80, and the rep reads size 30 / sector 25 / sites 15 / payroll 10.
Cut the tiers by what your team can absorb
Set the tier A threshold after looking at capacity. Two reps who can each work 60 new accounts a month properly will handle 720 over six months, so tier A is roughly the top 700. =PERCENTILE(J2:J6001,0.88) gives the score at that cut.
| Tier | Score in this example | Accounts | Treatment | Contacts |
|---|---|---|---|---|
| A | 80 and up | 700 | Researched by hand, personal message, phone | 3 to 5 |
| B | 60 to 79 | 1,800 | Sequence per segment, light personalization | 2 |
| C | 40 to 59 | 2,300 | Automated, only when capacity is left or a signal fires | 1 |
| D | Under 40 | 1,200 | Kept in the database, no outreach | 0 |
Then segment, which is a separate axis. A tier sets the effort you spend on an account, a segment sets what you say to it.
| Segment | Definition | Angle for the message |
|---|---|---|
| Road transport | NAF 4941A |
Driver hours and their collective agreement |
| Restaurants, multi-site | NAF 5610A, 2 sites or more |
Variable hours across locations |
| Home care | NAF 8810A |
Travel time and fragmented contracts |
| Other SMEs | Everything else in the ICP | Time saved per pay run |
Keep segments few enough that you can write a real message for each. The campaign chapter starts from this table.
Use AI to fill a field, and keep the score in the grid
Some criteria only exist as text: a company description, a page on the website, a list of job titles. A language model is useful for turning that text into a value your grid can read.
I co-founded Derrick, so take this with that in mind. Ask Claude reads each row and writes the answer back in a new column, for 2 credits per row. You can feed it the output of Website Crawler or the titles from the previous chapter, with a closed answer format:
Based only on the text below, answer with one word:
in_house, outsourced or unknown.
Does this company run payroll itself, or does an accountant or payroll bureau handle it?
If the text does not say, answer unknown.
Job titles found at the company: {{titles}}
Website text: {{site_text}}
Ask Claude can also return a score directly, and I wouldn’t let it own the final one. The same row can get a different answer on a second run, and nobody can defend a number whose reasoning changes. A closed field stays in your grid and is easy to audit: check 50 answers by hand before you trust the column. Derrick won’t define your grid either, since that comes from your own customers.
Any language model behind an API does the same job with the same prompt, and for the 700 accounts in tier A, reading the site yourself is a reasonable alternative.
Test the score on deals you already know
Score your best customers and your deals lost for lack of fit with the same grid, without peeking at the result while you build it.
| Group | Tier A | Tier B | Tier C | Tier D |
|---|---|---|---|---|
| Best customers (40) | 21 | 14 | 4 | 1 |
| Lost, poor fit (40) | 3 | 9 | 16 | 12 |
Here 35 of 40 customers land in A or B, and lost deals pile up lower down, so the grid separates the two groups. If your customers spread evenly across tiers, a criterion is wrong or missing. Read the worst misplacements one by one, since each usually points at the field responsible. Rerun this test each quarter with the new deals, and when reps tell you an account was scored wrong, add it to the test set.
Your next step: compute the lift on your own customers, write a grid of four to six criteria, and run it on your full list. Back-test it, set the tier A cut from your real capacity, and add the score and score_reason columns to the database before moving on to intent signals.