Define the ICP from real customers
Who stays, who pays and who recommends you.

Your ICP should come out of a query on your customer base. A persona slide can serve as a first hypothesis, but a TAM built from it inherits every wishful line it contains, and a list of 8,000 accounts is an expensive way to discover that one line was wrong.
This chapter produces two things: a customer table with one row per account, and a one-page ICP card saying who goes in the list and who stays out. The ICP and positioning audit asks a related question for your marketing. Here the output has to be precise enough to become list filters.
Throughout this part of the guide, say you sell payroll and scheduling software to French employers with several sites. Every figure below is invented for the example.
Build one table with one row per customer account
Take every account that started paying at least 12 months ago, including the ones that left. Removing churned accounts is the mistake to avoid first, because you would end up describing whoever happens to still be around.
| Column | Comes from | Used for |
|---|---|---|
account_id, domain, legal_name |
CRM | Joining everything, matching to outside data |
siren |
Invoices | Exact match to the French registry |
first_paid_at, churned_at |
Billing | Cohorts and retention |
first_year_arr, arr_month_12 |
Billing | Expansion or contraction |
discount_pct, failed_payments |
Billing, CRM | Revenue quality |
support_tickets_12m |
Help desk | Cost to serve |
sales_cycle_days, source |
CRM | Cost to acquire |
referrals_made, reference_calls, public_review |
CS notes, CRM | Advocacy |
sector, headcount_band, open_sites, tech_stack |
Enrichment, next section | Cutting into segments |
Advocacy data is rarely in one place. Ask customer success and the founders to go through the list by hand and mark who sent you a lead, took a reference call or wrote a public review. It takes an hour, and nothing in your tools will replace it.
Fill the company columns from outside
Your billing tool knows a name and maybe a domain, rarely a headcount or an activity code. Derrick, which I co-founded, so weigh this accordingly, fills those columns from the list you already have, in its web app, a Google Sheets sidebar, its API or an MCP client.
| Column to fill | Feature | Input | Output | Credits |
|---|---|---|---|---|
| Activity, headcount, legal data | SIRET/SIREN Enrichment | SIREN, SIRET or company name, with an optional département | Name, directors, revenue, headcount, address, legal fields, and a confidence score on name searches | 1 per company |
| LinkedIn URL | Search Companies | Company name | LinkedIn company URL | 1 per company |
| LinkedIn industry and size | Enrich Companies | LinkedIn company URL | Data from the company page | 1 per company |
| Stack | Website Technologies | Website URL | Detected CMS, CRM and similar | 2 per site |
Registry lookups cover French companies only, and a match on a name alone can land on the wrong entity, so review the low-confidence rows by hand. None of this tells you why a customer stayed. Below a hundred customers, you can do the same work without any tool: look up each SIREN in the free SIRENE data from INSEE, and read the company page and the website yourself.
Measure stays, pays and recommends separately
A single “customer health” score hides the trade-offs you need to see. An account can pay well and leave in month 14, and a small account can love you and send you three leads a year. Keep three measures.
| Behaviour | Measure | Example of a good result |
|---|---|---|
| Stays | Still active at month 12, then month 24 | Active at 12 months |
| Pays | Net ARR retention at 12 months, discount given, failed payments, tickets per account | Net retention at 100% or more, with a normal discount |
| Recommends | Referrals, reference calls, public reviews | At least one in 24 months |
Once sector, open_sites and headcount_band are filled, define a few segments by combining them, then run this. Twenty accounts is a floor below which I would not read a percentage.
SELECT
segment,
COUNT(*) AS customers,
AVG(CASE WHEN active_at_month_12 THEN 1.0 ELSE 0 END) AS stays,
SUM(arr_month_12) / NULLIF(SUM(first_year_arr), 0) AS pays,
SUM(referrals_made) * 10.0 / COUNT(*) AS referrals_per_10,
AVG(sales_cycle_days) AS sales_cycle_days
FROM customer_accounts
WHERE first_paid_at < CURRENT_DATE - INTERVAL '12 months'
GROUP BY segment
HAVING COUNT(*) >= 20
ORDER BY pays DESC;
Read the output against what sales believes
| Segment | Customers | Stays | Pays | Referrals per 10 accounts | Sales cycle (days) |
|---|---|---|---|---|---|
| Childcare groups, 3+ sites | 38 | 92% | 116% | 4.2 | 35 |
| Care home groups, 3+ sites | 22 | 95% | 109% | 2.7 | 60 |
| Restaurant groups, 3+ sites | 64 | 71% | 88% | 0.9 | 20 |
| Single-site employers | 190 | 58% | 74% | 0.5 | 12 |
Sales would probably name restaurants as the best segment: plenty of logos, quick deals. The table says they shrink after signature. Childcare and care home groups do all three things, even with a slower cycle on care homes. Single-site employers bring volume and leave, so they go on the exclusion list, however easy they are to close. Feed the same cut into the retention audit if you run one.
The weights are yours to decide. If cash is tight, a short sales cycle counts for more. Write down the reasoning, because someone will challenge it when the list comes out smaller than they hoped.
Interview for what was true before they bought
The numbers name the segment. You now need to know what those companies had in common the month before they started looking, since that is what you will search for in the market. Talk to five to eight accounts from the best segment and three that churned.
| Question | What you are after | What it may become |
|---|---|---|
| What had changed in the months before you looked for a solution? | A dated event | A signal to monitor |
| How many people handled this, and with what? | Team shape, existing tools | A size bound, a stack criterion |
| Who first raised the problem, and who signed? | Job titles | Personas |
| Which companies like yours would not need this? | Their own exclusion logic | A disqualifier |
| For churned accounts: when did you know it would not work? | The missing precondition | A disqualifier |
Note anything visible from the outside. “We opened our fourth site and the spreadsheets broke” can be found in data. “We wanted to modernize” cannot.
When you have too few customers
Under 20 accounts per segment, the HAVING clause returns nothing, and lowering it gives you percentages built on noise. Widen the evidence instead: add lost deals with their reasons, live opportunities and anyone who agreed to pay before the product was finished. Then mark each line of the card with what supports it, so “seven customers” and “my hypothesis” stop looking the same. Review the card when you reach 50 customers.
Write the ICP card, with the exclusions
| Line | In | Out | Evidence |
|---|---|---|---|
| Sector | Childcare and care home operators | Restaurants, for now | 60 customers, retention above 100% |
| Structure | 3 or more sites | Single site | Single-site cohort at 74% net retention |
| Size | 20 to 499 employees | Under 20, 500 and above | 41 of the 60 customers; larger accounts untested |
| Geography | France | Other countries | All customers |
| Buyer | Head of HR, finance director, founder in small groups | IT as sole contact | Interviews, 8 of 11 |
| Trigger | New site opened, payroll hire | None | Interviews, 6 of 11 |
Your next step: export the customer table this week, fill the company columns and run the segment query. Then write the card, and take each of its lines to the next chapter to turn it into something a data source can answer.