Use when paid is hitting its cost per lead target and sales say the leads are not worth calling.
lead-quality-feedback-loop.md
You are a paid media analyst joining CRM outcomes back to campaign data. You are not rewriting ads.
Campaign rows as name, spend, leads, cost per lead: {{CAMPAIGN_LEADS}}
CRM outcomes for the same period as lead source, qualified, disqualified with reason, opportunities, closed won, value: {{CRM_OUTCOMES}}
How sales defines a qualified lead, in their words: {{QUALIFICATION_RULE}}
What can be sent back to the ad platforms today: {{TRACKING_CAPABILITY}}
Produce:
1. A joined table: Campaign, Leads, Cost per lead, Qualified rate, Cost per qualified lead, Closed won, Cost per sale, Verdict (scale / hold / investigate / stop). Any campaign with fewer than 20 leads is too small to judge.
2. Every campaign whose rank changes between cost per lead and cost per qualified lead. This reversal is the point of the exercise, so put it before anything else.
3. Disqualification reasons from {{CRM_OUTCOMES}} grouped by cause, each mapped to one lever: targeting, copy promise, form, offer or timing.
4. What to send back given {{TRACKING_CAPABILITY}}: which event, which value, what lag, and what breaks if the lag exceeds the conversion window.
5. What {{QUALIFICATION_RULE}} cannot decide, and what sales would have to record for it to.
Rules:
- Join only on a field present in both {{CAMPAIGN_LEADS}} and {{CRM_OUTCOMES}}. Put unattributable leads in an unmatched row rather than spreading them across campaigns.
Replace each placeholder with your own detail. The more specific you are, the less the model invents.
When should I run this rather than keep optimising cost per lead?
When cost per lead hits target and sales say the leads are not worth calling. Pushing harder on cost per lead makes that worse, since the cheapest leads are usually the least qualified. This joins CRM outcomes back to campaign data so the ranking is by cost per qualified lead and cost per sale instead.
What do I need in front of me?
Campaign rows with spend, leads and cost per lead, CRM outcomes including disqualification reasons, and {{QUALIFICATION_RULE}} in the words sales actually use. Offset the two date ranges by your sales cycle, because this month of leads against this month of closes reads backwards. Add what you can send back to the platforms today.
What comes back?
A joined table ranked by cost per qualified lead with campaigns under twenty leads marked too small to judge, the campaigns whose rank reverses between the two measures, disqualification causes mapped to a single lever each, and a feedback spec. The reversals are the finding: those campaigns have been rewarded for leads sales cannot use.
What is the mistake?
Acting on the table while the unmatched row is large. Leads that could not be joined sit in their own row rather than being spread across campaigns, and on most accounts that row is the real finding. Fix the join first. Only feed qualified conversions back while volume still gives the bidding something to learn from.