Target persona and scoring
The target persona describes who a campaign is reaching, and lives on the (Product, Goal) pair: a sales campaign of a product carries a buyer persona, a press campaign of the same product carries a publications-and-journalists persona, a recruiting campaign carries a candidate persona — each independent, each with its own approval state. We historically called this the “Ideal Customer Profile” (ICP) and the term is still used as an alias in sales-shaped flows, but the underlying object is goal-agnostic. Every account that enters a campaign gets a fit score for that goal: a number 0–10, a categorical label, and a short list of typed justifications.
Scoring is the bridge between your raw account database and an actionable campaign list. Done well, it turns “here are 2,000 leads” into “here are the 80 to focus on this week.”
Structure of a target persona
Section titled “Structure of a target persona”LeadHunter’s target persona is structured — not just a paragraph. The AI generates it from your Product’s description, website, and example URLs, then you review and approve.
| Field | What it holds |
|---|---|
name | Short label for the persona (e.g. “The Tech-Forward CFO” for sales, “Senior B2B SaaS Reporter” for press, “Senior Backend Engineer, Series A Berlin” for recruiting). Auto-generated; editable. |
summary | Plain-language overview of who you’re targeting. Read first by the model. |
industries | List of sectors / editorial domains / specialties relevant to the goal. |
job_titles | List of relevant decision-maker / journalist / candidate / partner roles. |
pain_points | What this persona cares about — what would motivate them to engage. For sales it’s product-relevant pain; for press it’s editorial angles; for candidates it’s career drivers. |
company_size_min / company_size_max | Size band — employees for company targets, audience size for publications, team size for partners. Either may be omitted. |
confidence_level / confidence_score | How confident the AI is in this draft (low / medium / high, plus a 0–100 score). A low-confidence first draft is the signal to spend more time editing before approval. |
source_urls | URLs the AI cited while drafting. Useful when reviewing — you can see what the model was reading. |
is_approved | True once you click Approve. Scoring still runs against a draft, but approval is the signal the document is calibrated. |
revision_count | Number of times the persona has been re-generated. Bumped on every regenerate. |
revision_feedback | Free-text you provide when asking the AI to redraft (“focus more on tier-1 trade press, less on general business pubs”) — fed into the regeneration prompt. |
You can edit any field after generation; the model uses the whole structured persona plus the Product description on every score.
ICP review and approval
Section titled “ICP review and approval”A fresh ICP starts in Pending approval. You see the AI’s draft, edit it, click Approve to mark it ready for scoring. Until approval, scoring runs against the draft anyway — but the “this ICP is approved” flag is the signal that the document is calibrated and stable.
If the first draft is off, you have two options:
- Edit in place — change individual fields and re-approve. Best for small refinements.
- Regenerate with feedback — fill in
revision_feedback(“focus on independent garages, drop the enterprise framing”) and ask the AI to re-draft. The feedback flows into the regeneration prompt;revision_countincrements. Best for course corrections.
You can revise the ICP at any time. Pay attention to confidence_level on the draft — a low-confidence draft from a sparse Product description usually means the model couldn’t anchor; sharpening the Product description before regenerating is more effective than editing the ICP by hand.
How scoring works
Section titled “How scoring works”Goal-aware framing
Section titled “Goal-aware framing”Scoring asks “how well does this account fit the target?” — but the answer to “what target?” depends on the campaign’s goal. For a Sales campaign it’s “how well do they fit our buyer profile”. For a Press campaign it’s “how well does this outlet fit our story”. For Recruiting it’s “how well does this person fit the role”. For Partnership it’s “how strong a partner would this be”.
The 0-10 scale and the typed reasons (positive / negative / neutral) stay the same regardless of goal, so a 9 always means very strong fit and a 3 always means clear mismatch. What shifts is the axis being rated. The model is told the goal up front so the score reasons it returns are framed correctly — “covers our space editorially” for Press, “complementary product stack” for Partnership, “recent stack matches the role” for Recruiting.
See Outreach reasons and targets for the full goal list.
What the model sees — the full ordered list
Section titled “What the model sees — the full ordered list”Every input that contributes to scoring, in the order it appears in the prompt. If a section is blank or empty, it’s skipped entirely — no empty headers reach the model.
Rubric block — built once per scoring run:
- Language — what language to write reasons in. Resolved from Campaign → Product → your account default → English.
- Campaign goal — sales / partnership / press / investor / recruiting / customer expansion / win-back / event / research / renewal / influencer. Decides which axis the score is rated against (see Goal-aware framing above).
- Target persona (ICP) — the structured persona: name, summary, industries, job titles, pain points, company size range. Generated once from the Product description + website + example URLs; revise or regenerate on the campaign page.
- Product name — the Product label.
- Value proposition — the Product’s free-form description. Capped at 2000 characters. Edit it on Settings → Products; changes take effect on the next rescore.
- Campaign scoring brief — optional free-text guidance specific to this campaign — “accounts must have a physical retail location”, “down-weight chains; prioritise owner-operated stores”, “weight community-event capability heavily”. Capped at 2000 characters. Edit it inline on the campaign page or through the “Give feedback & rescore” modal on the scoring review page. Blank by default.
- Good-fit example URLs + scraped content — 2–3 URLs on the Product, fetched in parallel. Capped at 2000 characters per URL. Single most powerful lever after the persona itself — short of a sharp persona, sharp example URLs do more for scoring quality than anything else.
- Bad-fit example URLs + scraped content — same shape.
- Calibration examples — your most recent approvals + rejections, once the feedback loop crosses the ~10-account threshold for the (product, goal) pair. Up to 3 of each side. Below threshold the section is omitted — small samples are noisier than no sample.
Per-account block — repeated once per account in the batch:
- Account ID — load-bearing identifier the AI echoes back so we can map scores to accounts.
- Name — the account’s name.
- Location — city, region, country, joined with commas.
- Business type — free-form category, set during enrichment.
- Specialization — sub-category if any.
- Website — URL.
- Rating — only included in scoring (not outreach), out of 5.
- Language — the account’s own language. The model uses it as a signal, not as a writing instruction.
- Email, Phone — contact details if known.
- Notes — free-form operator notes. Capped at 500 characters. Treat this field as operator-shared AI context, not private scratch space — it goes to the model.
- Custom field values — every non-empty key/value pair from the custom fields you’ve defined for the Company under Settings → Custom fields.
- Website content — the cached scraped text from the account’s website. Capped at 3000 characters. Wrapped in delimiters that tell the AI to treat it as untrusted evidence (a prompt-injection guardrail).
What it produces
Section titled “What it produces”| Field | Type | Meaning |
|---|---|---|
ai_score | 0–10 | Numeric fit score. |
score_label | enum | excellent (≥8), moderate (5–7), mismatch (<5). |
score_reasons | array | 2–4 short, typed justifications — see below. |
Score reasons are typed for at-a-glance reading
Section titled “Score reasons are typed for at-a-glance reading”Each reason carries a type so the UI can show you what’s pulling the score up vs. down without you having to read prose:
| Type | Icon | What it means | Example |
|---|---|---|---|
| Positive | green check | Concrete ICP match | ”FM rock station — matches ICP industry.” |
| Negative | red X | Concrete ICP gap | ”Single-location operator — below the size range.” |
| Neutral | amber warning | Relevant context that doesn’t clearly help or hurt | ”Spanish-language content.” |
excellent scores lead with positives, mismatch scores lead with negatives, and when both signals are present the AI includes at least one of each so the trade-off is visible.
Cost and latency
Section titled “Cost and latency”Scoring runs on Gemini Flash by default — fast and cheap. Per-account cost is a fraction of a cent (typically <€0.001); a batch of a few hundred accounts finishes in 5–15 minutes. Cost is tracked per account and per campaign, with a per-model breakdown on both surfaces — see Usage and costs.
When scoring fails
Section titled “When scoring fails”The campaign’s scoring_status flips to failed when the background job hits an error (provider quota exhausted, malformed account data the LLM rejects, etc.). Scores from batches that completed before the failure are kept — re-running scoring will pick up where it left off and only score the accounts that don’t yet have a score. Today the campaign page doesn’t surface the failure prominently, so if a rescore finishes faster than expected and you see fewer scored accounts than you launched with, check scoring_status on the campaign.
What scoring does not see
Section titled “What scoring does not see”- Conversation history with the account — past outbound and inbound aren’t part of the scoring prompt. (They are part of the AI-continue drafting prompt — different surface.)
- Activity from other companies in your tenant — scoring is strictly scoped to the active Company’s Product and Account.
- Paid data sources unless you’ve integrated them — LeadHunter’s default scoring doesn’t subscribe to ZoomInfo, Apollo, etc. If you’ve enriched accounts with data from those services and stored it in custom fields, that data goes in; the integrations themselves don’t.
The notes field on the account is sent to the scoring prompt (truncated to 500 characters). Notes are a useful place to drop short context the model should weigh — “Referred by an existing customer”, “Recently raised Series B”, “Operates in two countries” — and they’ll influence the score and the reasons. Treat the field like operator-shared AI context, not private scratch space.
Score caching: one per (Product, Account, Goal)
Section titled “Score caching: one per (Product, Account, Goal)”The fit score lives on the (Product, Account, Goal) triplet — one score row per campaign goal. That means:
- The same account in three sales campaigns of the same product is scored once — adding it to a second sales campaign reuses the existing score (no Gemini cost, no waiting).
- The same account in a sales campaign and a press campaign of the same product gets two scores — they’re rated against different criteria (buyer fit vs editorial fit) so reuse would be wrong. Each goal owns its own score.
- Swap a campaign to point at a different product, and all its accounts will need to be rescored. The dashboard offers a single-click bulk rescore for this case.
- Switch a campaign’s goal and existing scores stay as they were (they’re for the previous goal); rescore to get fresh scores under the new framing.
Per-campaign overrides are scoped to a single account and don’t touch the underlying (Product, Account, Goal) score, so a manual adjustment in one campaign doesn’t bleed into the others. The API for setting an override exists today; the in-app UI for it is on the roadmap, so for now overrides are set programmatically rather than from the scoring page.
Sibling campaigns share scores — the rescore caveat
Section titled “Sibling campaigns share scores — the rescore caveat”Because the score is per (product, goal), two campaigns of the same product at the same goal literally read from the same score row — different brief, different audience filters, same cached score. When you use the “Give feedback & rescore” flow on Campaign A, the new scores also become what Campaign B sees if B targets the same product and goal.
What survives the rescore on those siblings: every approval / rejection you’ve made, every per-account override you’ve set, every outreach interaction. Only the AI’s score and the reasons it wrote change.
The rescore modal warns you explicitly when sibling campaigns exist, so you can decide whether to proceed. If you need genuinely independent rubrics for two campaigns, either (a) put them on different goals (e.g. one Sales + one Customer Expansion) so each gets its own score row, or (b) clone the Product so the two campaigns each have their own product context — the trade-off is that the Product’s example URLs and value proposition must be maintained in two places.
Give feedback & rescore — the iterative loop
Section titled “Give feedback & rescore — the iterative loop”The scoring review page (Score review in the dashboard) has a Give feedback & rescore button next to the “Score remaining” action. Click it whenever you notice the AI is overlooking something across many scores — “the persona should include a physical retail location”, “we’re scoring chains too high, prioritise owner-operated stores”, “weight community-event capability heavily for this campaign”. The modal:
- Pre-fills the textarea with the campaign’s current scoring brief so you can revise, append, or rewrite freely.
- Saves whatever you type to
Campaign.scoring_briefimmediately — even if the rescore itself fails, your feedback isn’t lost. - Re-evaluates every account in the campaign under the new brief — both already-scored and unscored — overwriting the cached AI score and reasons in place.
- Polls until scoring completes, then shows the new distribution.
Approvals, rejections, and overrides are preserved across the rescore — only the AI’s verdict changes. If you’ve already calibrated the campaign by approving/rejecting 10+ accounts, those validations still feed the scoring few-shot, so the brief stacks on top of your prior calibration rather than replacing it.
The brief stays on the campaign indefinitely. Subsequent rescores (manual or automatic) keep using it until you change or clear it.
The feedback loop — your reviews calibrate the model
Section titled “The feedback loop — your reviews calibrate the model”The biggest lever for improving scoring quality isn’t tweaking the ICP — it’s marking accounts as Approved or Rejected in the campaign review queue. Once a (product, goal) pair crosses about ten reviewed accounts across all its campaigns, LeadHunter starts feeding your most recent approvals and rejections to the scoring prompt as concrete examples of “what good looks like here” and “what to skip even when the surface details look fine.”
Below that threshold, the calibration few-shot is held back — small samples are noisier than no sample, so the original example URLs on the Product remain the only anchor.
The signal is goal-scoped within a product: approvals on a sales campaign of Product X don’t leak into a press campaign of the same product, and vice versa. The two are rated against different criteria — mixing them would teach the model the wrong lesson. The same Account approved in two sales campaigns of the same product counts once; the same Account being rescored never gets fed its own past verdict (avoids a self-reinforcing loop).
This is why the first campaign on each new (product, goal) pair is the most important one to be thorough on the review step — every approve/reject you make there is shaping the next several hundred scores for that pair.
Reasons are written in the campaign’s language
Section titled “Reasons are written in the campaign’s language”ICP summary text, score reasons, and outbound message drafts are all produced in the same language. The chain is Campaign.communication_language → Product.communication_language → your account default → English. Set the campaign’s language to run parallel campaigns of the same product in different markets without duplicating the product.
The Account’s own language field affects outbound message drafting (the message is written in the account’s language) but not scoring — scoring renders reasons in the campaign’s language regardless of where the account is located.
What if the account has no website?
Section titled “What if the account has no website?”Some accounts arrive with a name, a city, and nothing else — phone-only entries, scanned business cards, old CRM exports. Scoring can still run, but with no website content the model is leaning on the structured fields alone (business type, custom fields, location). Scores tend to cluster in the moderate-mismatch range and the reasons are vaguer.
Two ways to improve them:
- Let auto-enrichment discover and scrape the website (the default for newly-created accounts).
- Trigger Deep research from the account detail page (multi-page crawl + contact extraction).
Once content lands, rescoring picks up the new signal.
After scoring: prune the mismatch tail
Section titled “After scoring: prune the mismatch tail”Once a scoring pass completes, the bottom of the list — the mismatch band — is usually not worth your outreach time. The campaign-accounts panel has a one-click Remove low-fit action that clears these rows, with safe defaults that preserve anything you’ve already approved or started outreach on. See Campaign → Pruning the low-fit tail after scoring for what it removes, what it keeps, and the per-campaign scope.
When to rescore
Section titled “When to rescore”Re-run scoring when:
- You edit the ICP — the largest possible scoring shift.
- You change the example URLs on the Product — second-largest shift.
- You enrich accounts with new data — website discovery completed for accounts that had no URL; custom fields backfilled from an import.
- You’ve passed the calibration threshold — if you’ve just reviewed your tenth account, the next batch of fresh scores benefits from the calibration examples; existing scores don’t update until you rescore them.
The same account isn’t auto-rescored across campaigns of the same product — the score lives on the (Product, Account) pair and is sticky until you explicitly rescore.
Single-account vs bulk rescore
Section titled “Single-account vs bulk rescore”Two entry points for re-running scoring:
| Mode | Where | Use when |
|---|---|---|
| Quick-score on one account | The account detail page → Score button. | You’ve just enriched one account and want its score refreshed without re-running the whole campaign. |
| Bulk-rescore the whole campaign | The campaign page → Re-score action. | You edited the ICP, changed example URLs, or just crossed the calibration threshold and want the existing accounts updated. |
A rescore overwrites the previous score in place — there’s no per-account score history kept. If you want to see what the previous score was for a specific account before re-running, screenshot it or take a note; the new score will replace it.
What about the score distribution?
Section titled “What about the score distribution?”The campaign detail page shows a 10-bucket histogram of fit scores after scoring runs (0-1, 1-2, … 9-10). It’s the fastest way to read whether the ICP is well-calibrated. See Campaign → Score distribution.
Read next
Section titled “Read next”- Run your first campaign — the operator-side workflow, including the review-and-calibrate pass.
- Company and Product — why ICP lives on the product and not the campaign, and when to spin up a second product instead of a second ICP.
- Custom fields — define the structured business context the scoring prompt reads.
- Account — what scoring actually reads from, and the operator-only
notesfield it deliberately doesn’t.