Most tools treat the ideal customer profile as a saved search: pick an industry, drag a headcount slider, save. That produces a list of companies that resemble your customers. Resemblance is not the problem. Timing is.
Here an ICP is a written standard that a qualification argument gets held to. It says who is worth contacting, why, what would count as proof that they are worth contacting now, and who is explicitly not worth contacting even though they look like they are.
What an ICP is here#
An ICP has four parts. The first two are common; the last two are where the work is.
| Part | Answers | Example |
|---|---|---|
| Shape | What kind of company is this? | Regional freight and 3PL operators, 50–400 staff, own their fleet |
| Problem | What is broken for them? | Dispatch is coordinated by phone and spreadsheet; margin leaks on empty return legs |
| Trigger | What indicates it is broken right now? | A second depot opening, a first ops-manager hire, a new fleet-telematics rollout |
| Exclusions | Who looks like a fit but is not? | Freight brokers with no assets; anyone already running the incumbent TMS under contract |
Shape narrows the universe. Problem gives the message something true to say. Trigger is what turns a plausible account into a contactable one. Exclusions stop the engine spending effort arguing for accounts you already know are wrong.
Building one from your own material#
The ICP builder takes source material rather than form input. Give it any of the following and it will read them:
- Your website. A URL is enough. It reads positioning, pricing signals, named use cases and the vocabulary you actually use.
- A deck or a PDF. Sales decks are usually the densest single source, because they already contain the problem statement in a form a buyer accepted.
- A short written description. Three honest paragraphs beat thirty filter selections.
- A list of closed-won accounts. Ten names, with a line each on why they bought, is the strongest input available. The engine looks for what those ten had in common at the moment they bought — not what they have in common today.
What the engine extracts#
The builder does not summarise your material. It proposes a structured profile and then argues against its own proposal before showing it to you — the same propose, challenge, revise loop used for account decisions. What you see is the revised version, with the challenge attached so you can see what it nearly got wrong.
{
"id": "ICP-3",
"shape": {
"sectors": ["freight", "third-party logistics"],
"headcount": { "min": 50, "max": 400 },
"geography": ["GB", "IE"],
"must_have": ["owns fleet"]
},
"problem": "Dispatch coordinated manually; margin lost on empty return legs.",
"triggers": [
{ "name": "second depot", "families": ["expansion", "property"] },
{ "name": "first ops manager hire", "families": ["hiring"] },
{ "name": "telematics rollout", "families": ["tech change"] }
],
"exclusions": [
{ "rule": "asset-light brokers", "reason": "no dispatch surface to improve" },
{ "rule": "under contract with incumbent TMS", "reason": "window closed until renewal" }
],
"confidence": 78,
"unresolved": [
"Deal size floor not stated in source material — assumed from pricing page."
]
}The unresolved array is the part worth reading. It lists the things the engine had to assume because your material did not say. Every entry there is a place where a wrong assumption will quietly propagate into every decision made under this profile.
Firmographic and behavioural halves#
An ICP has a static half and a moving half, and they are used at different moments.
The firmographic half#
Sector, size, geography, business model, tech stack. This half is slow-moving and it is used as a filter: it decides which companies are eligible to be considered at all. Getting it wrong is expensive but obvious — you will see companies in the shortlist that are plainly not your market.
The behavioural half#
Triggers, and the evidence families that satisfy them. This half is fast-moving and it is used as a ranking: among eligible companies, which ones show signs that the problem is live right now. Getting it wrong is expensive and invisible — the shortlist looks reasonable, and every account on it is six months early.
Exclusions#
Exclusions are rules with reasons attached. The reason matters, because it is what lets the engine generalise the exclusion rather than blacklisting one company.
| Exclusion | Weak form | Useful form |
|---|---|---|
| Competitors | Block a list of domains | Block companies whose positioning overlaps ours, with the overlap cited |
| Too small | Headcount under 50 | Companies where the problem exists but no budget line owns it yet |
| Already served | Block current customers | Block current customers and their subsidiaries, sourced from the CRM account hierarchy |
| Wrong moment | — | Under contract with an incumbent; revisit 90 days before renewal |
The last row is the one people forget. An exclusion with a date on it is not a rejection, it is a scheduled reconsideration, and the system treats it that way.
Keeping it honest#
An ICP degrades. Your market moves, your product changes, and the accounts you actually close stop matching the profile you wrote in month one. Three mechanisms push back against that.
- Rejection reasons become constraints. When you reject a qualified account and say why, the reason is added as a candidate exclusion. After it recurs, the engine proposes promoting it to a rule.
- Reply classifications are graded against the profile. A pattern of “wrong person” replies from one sector is evidence the shape is wrong, not that the copy is wrong.
- Closed-won accounts are re-read. When a deal closes, the account’s evidence at the moment of first contact is compared against the profile’s triggers. Triggers that never precede a win get flagged as decorative.
None of these edits the ICP silently. Each one produces a proposal you approve or decline, because an ICP that changes without you noticing is worse than one that goes slightly stale.
Next: signals — the observable events that satisfy the triggers you just defined.