Skip to main content

Fit Scoring

Fit scoring measures how well an account matches your Ideal Customer Profile (ICP). It evaluates firmographic data across four configurable dimensions, each returning a score of 0--100, then produces a weighted composite score.

The Four Dimensions

DimensionWhat It ChecksPerfect Score (100)Zero Score (0)
IndustryAccount industry vs. ICP target industriesExact match foundNo match or missing data
Company SizeEmployee count vs. ICP rangeWithin [min, max]At 0 or 2x outside range boundary
RevenueAnnual revenue vs. ICP rangeWithin [min, max]At 0 or 2x outside range boundary
Custom AttributesArbitrary fields vs. ICP criteriaAll attributes matchNo matches or missing data

Default Weights

The default dimension weights are:

DimensionDefault Weight
Industry30
Company Size25
Revenue25
Custom Attributes20
tip

Weights do not need to sum to 100. The engine normalizes by dividing the weighted sum by the total weight. Setting Industry to 60 and Company Size to 40 (with others at 0) would score purely on those two dimensions.

How Each Dimension Works

Industry Match

function industryScore(
accountIndustry: string | null,
icpIndustries: string[],
): number
  • Case-insensitive exact match: If the account's industry matches any entry in your ICP industries list, the score is 100. Otherwise, 0.
  • Returns 0 if the account industry is null or if the ICP industries list is empty.

Example: ICP industries = ["SaaS", "FinTech"]. An account with industry "saas" scores 100. An account with industry "Healthcare" scores 0.

Company Size (Employee Count)

function companySizeScore(
employeeCount: number | null,
min: number,
max: number,
): number
  • Returns 100 if the employee count falls within [min, max]
  • Uses linear falloff outside the range:
    • Below min: score = max(0, 100 - ((min - value) / min) * 100)
    • Above max: score = max(0, 100 - ((value - max) / max) * 100)
  • Score reaches 0 when the value hits 0 (below) or 2x the boundary (above)

Example (min=50, max=1000):

Employee CountScoreReasoning
500100Within range
2550Halfway between 0 and min
150050Halfway between max and 2x max
00At or below 0
20000At 2x max boundary

Revenue

function revenueScore(
revenue: number | null,
min: number,
max: number,
): number

Uses the same linear falloff algorithm as company size. The default ICP range is $1,000,000 to $100,000,000.

Revenue Parsing

Revenue is stored as a string in the database (Drizzle numeric column). The fit engine parses it to a number using parseFloat. Invalid or empty values result in a score of 0.

Custom Attributes

function customAttributeScore(
sourceData: Record<string, unknown> | null,
customAttributes: Array<{ field: string; values: string[]; weight: number }>,
): number
  • Each custom attribute is scored independently: 100 if the account's value matches any allowed value (case-insensitive), 0 otherwise
  • Results are combined as a weighted average across all custom attributes
  • Returns 100 if the customAttributes array is empty (no penalty for unconfigured attributes)
  • Returns 0 if sourceData is null

Example configuration:

{
"customAttributes": [
{ "field": "tech_stack", "values": ["Salesforce", "HubSpot"], "weight": 2 },
{ "field": "funding_stage", "values": ["Series B", "Series C"], "weight": 1 }
]
}

If an account has tech_stack = "Salesforce" (match, score 100) and funding_stage = "Seed" (no match, score 0), the custom attribute score is:

(100 * 2 + 0 * 1) / (2 + 1) = 66.7

Composite Fit Score Formula

The final fit score is a weighted average of all four dimension scores:

fitScore = round(
(industry * w_industry + size * w_size + revenue * w_revenue + custom * w_custom)
/ (w_industry + w_size + w_revenue + w_custom),
1 decimal place
)

Configuration Reference

The full FitConfig type:

interface FitConfig {
icpProfile: {
industries: string[];
minEmployees: number; // default: 50
maxEmployees: number; // default: 1000
minRevenue: number; // default: 1_000_000
maxRevenue: number; // default: 100_000_000
customAttributes: Array<{
field: string;
values: string[];
weight: number;
}>;
};
weights: {
industry: number; // default: 30
companySize: number; // default: 25
revenue: number; // default: 25
customAttributes: number; // default: 20
};
}
Weight of Zero

Setting a dimension weight to 0 effectively disables that dimension. If all weights are 0, the fit score is 0.