Executive Summary
The ads are working. The wrong people are seeing them.
Josh's ad funnel is converting at a healthy $50.45 cost-per-lead — that part is fine. The problem is who's filling out the form. Roughly 50% of the leads who write anything in the "additional info" field describe a litigation, family law, criminal, personal injury, or court matter. Then they book a 15-minute consult with Josh, who shows up to a call about a federal court appeal or a social-security disability case — work he doesn't do.
We diagnosed three root causes, fixed the two that were code-deep, and just upgraded the Facebook audience targeting from a 15-customer Lookalike seed to a 582-customer, $1.08M-LTV value-weighted seed. The new ad set is built and paused, ready to flip on for a side-by-side test against the current Broad audience.
Last 14 Days — Active Ad Set
The real CPL on a qualified buyer is closer to $100, not $50.
Headline CPL looks great because Meta counts every form fill as a lead — including the litigation leads. Halve the leads, double the cost.
Diagnosis
Three causes, in order of impact
A stricter version of the intake modal — one that blocks submission for litigation/family/criminal/PI cases — exists in the source code but was never built and deployed. The version live on /lawyeroncall right now has 13 generic options plus an "Other" choice that shows a soft amber message saying "you're welcome to still submit and we'll let you know." Nothing actually stops a wrong-fit lead from booking.
Highest impact — this single fix kills ~30-50% of bad leads at the source.
The "Lookalike 1% — Stripe Subscribers" audience was built from a 15-person seed. That's not enough signal for Meta to learn anything meaningful — at that size, Meta is essentially picking random Americans aged 28-55. Josh has 582 actual paying customers in Stripe. They just hadn't been uploaded.
Highest impact for ad-side training — fixed today.
The single active ad set targets "Small business" + "Entrepreneurship" interests with Meta's Advantage+ Audience expansion turned on. That expansion sweeps in adjacent consumer segments — landlord/tenant, real-estate-curious, side-hustle dabblers — many of whom have personal legal issues, not registered-business needs.
Medium impact — fixed in the new ad set with audience expansion explicitly disabled.
Evidence
What the bad-fit leads actually wrote
Looking at the optional "additional info" field on the intake form for the last ~14 days. Each lead picked a business-sounding dropdown option, then described something Josh doesn't handle:
"Looking to draft an appeal letter to overturn dismissed complaint in Federal Court."
Picked: "I need employment or HR legal guidance"
"I need legal help in both social security disability law and family law and advise to get the proper amount for the sale of my house which is being under sold by 230k."
Picked: "I need ongoing general counsel"
"I have court on the 30."
Picked: "Ongoing general counsel"
"Contract breaches."
Picked: "Ongoing general counsel" (litigation, not contract drafting)
"Needs help to create family trust."
Picked: "I need to form an LLC or corporation" (close to scope but mismatched)
Inbound email referencing case number for legal malpractice — full lawsuit caption, asking Josh to take it on.
From a previous booked lead, post-call follow-up
Pattern: leads pick the closest-sounding dropdown option, then describe their actual need (which is litigation) in the free-text field.
By that point they're already through the gate. The dropdown isn't a real qualifier — it's a soft suggestion.
What's Now Live in Meta
Audience upgrade: 15 → 582 seed customers
Pulled every Stripe customer (active + churned, all-time), tied each to their lifetime spend, hashed PII (SHA-256), and uploaded to Meta as a value-weighted Custom Audience. Then built a 1% Lookalike off that audience. The previous Lookalike was using only the 15 currently-active subscribers as its seed.
$2,313
Avg LTV per Customer
What was created in the ad account today
| Asset |
Type |
Status |
| Stripe Customers — All-Time (Value-Weighted) |
Custom Audience |
Updating (30-60 min) |
| LAL 1% US — Stripe Customers (All-Time) |
Lookalike Audience |
Ready |
| LAL 1% US — Stripe Customers (All-Time, 582 seed) |
Ad Set (3 ads) |
Paused — awaiting go-live |
The new ad set is fully built — same creative, same targeting age range, just a much smarter audience.
Three top-performing ads (01 - Not Your Only Option, 07 - 500 Per Call Broken, 08 - Contract Thousands CTA) were cloned in. Advantage+ Audience expansion is explicitly disabled so Meta respects the Lookalike instead of "expanding" it back to consumers.
The Plan
What we're doing — and what's still on the list
582 Stripe customers, value-weighted by lifetime spend. New 1% Lookalike sits at roughly the same precision tier as the old one but with 39× more seed signal. Meta has a real pattern to match against now.
"LAL 1% US — Stripe Customers (All-Time, 582 seed)" sits inside the existing campaign, paused. Three ads cloned. Audience expansion disabled. Ready to go live with one click.
Once live, Meta's Campaign Budget Optimization will split the $100/day spend between the new LAL set and the existing Broad set. After 7-10 days we'll have side-by-side data on which audience converts cheaper and cleaner.
Expected: cleaner intake within 1-2 weeks as Meta learns from the new seed.
The fixed ContactModal already exists in the codebase — it just needs to be built and pushed. Once live, anyone selecting "I have a civil lawsuit, litigation, family, criminal, or personal injury matter" sees a red box recommending their state bar's referral service, and the submit button greys out.
Highest single-fix impact. Kills 30-50% of bad-fit leads before they ever reach Josh's calendar.
Right now the field is optional with a soft placeholder. Make it required ("In one sentence, what's the legal need?"), and add a client-side keyword filter that catches words like lawsuit, court, divorce, custody, criminal, injury, evict, malpractice — same red-box treatment as the dropdown disqualifier.
Two required questions on the booking page: "In one sentence, what do you need help with?" and "Is this for a registered business you own?" (yes/no). The second alone deflects most personal-legal-issue traffic before they grab a slot on Josh's calendar.
Every lead tagged disqualified/litigation/family/PI gets pushed to a Meta Custom Audience set as a campaign-level exclusion. Meta starts learning the patterns those people share and avoids them. Over 30 days this is the closest thing to "negative training" Meta still allows since they killed interest-based exclusions.
Today Meta optimizes for any form fill. Once we wire Stripe → Meta CAPI Purchase events, Meta can optimize for actual paying customers — the gold standard. Requires building a Stripe webhook (code is drafted) and configuring it in Stripe Dashboard. Not blocking; the audience upgrade alone moves the needle first.
What To Watch
The 7-day scoreboard
Once the new ad set is live, these are the numbers that matter. We'll have a clean read by day 7-10.
| Metric |
Baseline (Broad) |
Target (New LAL) |
| Cost per Lead |
$50.45 |
< $55 (acceptable if quality improves) |
| Wrong-fit rate (lawsuit/family/PI) |
~50% of described leads |
< 20% |
| Lead → Booked rate |
~12% (8 booked / ~66 form submits) |
> 20% |
| Booked → Showed-up rate |
~80% (2 no-shows / 10 booked) |
> 85% |
| Showed-up → Qualified for retainer |
Unknown — Josh tracks this |
Track this in CRM going forward |
The right north-star metric is "cost per qualified buyer," not "cost per lead."
If the new LAL ad set delivers a $60 CPL with a 30% wrong-fit rate, that's a $86 qualified-buyer cost. Beats a $50 CPL with a 50% wrong-fit rate ($100). Quality > volume.
Bottom Line
Three pulls of the lever — done, queued, and ready
Meta now has 39× more signal about who Josh's buyers actually look like. New Lookalike + Custom Audience are live in the ad account. Cloned ad set is built and waiting.
One toggle in Ads Manager. Same campaign, same daily budget. Side-by-side test against the existing Broad set begins immediately.
The single biggest lever for lead quality. Code is already written. Just needs to be built + pushed to Vercel.