Campaign 120250641116100494 · account act_833808848824841 (CAD) ·
business 505925625406736 · flight 2026-06-26 → 2026-08-16 (51 days) ·
compiled 2026-08-16 from the official Meta Ads MCP (read-only) + hub D1 + GA4.
non_meta_source is decided — the actual field, quotedThree hops in boogles-hub @ bf0c44b:
src/conversions/meta-capi.ts:308
if (isBirthdayConversion && !row.lead_id) → 'skipped:non_meta_source'
src/conversions/meta-capi.ts:286
lead_id: body?.lead_id ?? customer.lead_id ?? null
src/conversions/birthday-triggers.ts:166 (twin: src/leads/read-source.ts:158)
LEFT JOIN meta_leads ml ON ... WHERE LOWER(ml2.email) = LOWER(sh.customer_email)
⇒ The determining field is slot_holds.customer_email on the RESOLVED hold, matched
by exact lower-cased equality against the Meta lead-form address. No phone lane, no name lane, no
cross-hold lineage lane. conversions has no lead_id column at all — the
classification is derived at fire time and never persisted.
| Lane | Matches among the 29 |
|---|---|
| L1 exact email | 0 |
| L2 phone (last-10, business + boilerplate numbers excluded) | 2 (same person) |
| L3 name / fuzzy local-part | 0 additional |
MEASURED: 2 of 29 (6.9%) are Meta-originated people whose credit was dropped. 27 of 29 are genuinely non-Meta. Total B7 leakage across both campaigns: 2 parties / 4 conversion events. Within Birthday — GTA: 1 party / 3 events (2 qualified + 1 booked, CA$1,000).
Controls, because three lanes returning near-zero is exactly the shape that lies:
the same matcher on the 18 ok events matches 16/18 (all via L1). L2/L3 were then proven separately —
across all 483 holds since 2026-06-20 the phone lane fires on 317 holds and the name lane on 331, producing
6 genuine non-email cross-identity matches elsewhere. The non-email lanes demonstrably fire.
Phone coverage was recovered for 20 of 22 phone-less holds by deep-scanning all thread messages — so this is
an observed absence, not an untested one.
Residual limit (INFERRED, unbounded): a lead submitted by one parent and a booking made by the other with a different email AND phone AND name is undetectable by construction.
Unresolved: two ok events (2026-07-06) have no row in
meta_leads or leads. A post-fire emails CASCADE delete is the most
plausible cause (resend-guard.ts:16 names that failure mode) but it was not proven.
Website form (no-reply@) 13 · customer's own address 10 (8 of them replies to the nurture
email) · birthdays-LP 5 · PR-agency referral 1. ⚠ The nurture list is broader than the Meta lead
list — none of those 8 repliers has a Meta lead under any identity, so a nurture reply is not a
Meta signal.
qualified:<hold_id> — per hold, not per party —
so a merge defeats it. Both instances here happened to skip, so nothing double-uploaded; a Meta-matched
merge pair would send two Leads for one party.
lost.Plays ÷ impressions is 23–33% for R2 against 87–93% for R1 and R4 — and it persists within identical placements (feed 85–88% vs 23–40%; IG stories 99%+ vs ~17%). Video length does not explain a play-start gap.
R2 also beats R1 on CTR in all three ad sets. If R2 is serving a static preview/fallback to a large fraction of impressions, then the static first frame may be the campaign's best click creative — which changes the test from "replace R2 with another video" to "test R2's static treatment against video."
Needs: object_story_spec / effective_object_story_id, the underlying
post's attachment/media type, thumbnail and static-fallback configuration, and video-start metrics split by
device × platform × placement.
Post-click conversion fell at SQ1 and Hillcrest but rose at UCM; and within SQ1, Instagram CVR rose slightly while Facebook CVR fell materially. A compositional shift could produce the apparent geo divergence with nothing changing in the form or in underlying demand. Check whether SQ1/Hillcrest shifted toward cells with weaker form completion while UCM shifted the other way. This is one of the few explanations capable of reconciling both at once.
The denominator is not "42 unmatched." It is confirmed customers whose identifiers could have matched a Meta lead but did not versus confirmed customers for whom Meta-origin identity is fundamentally untestable. Nine of 25 in-window confirmed holds had no recoverable phone; email is complete on the confirmed-hold side. Classify the 42 by observability and put an explicit upper bound on attribution rather than assuming zero or proportional.
{ and {{All nine were bulk-created through a template path that left the creative name as literal
{{product.name}}. Harmless in name (renamed since). But nobody has checked whether other
template-driven fields carry unresolved braces — url_tags, lead-form hidden/tracking params.
Weak corroborating signal: ad_id/adset_id are present on only 326 of 332 leads.
| Period | Spend | Leads | CPL |
|---|---|---|---|
| Jun 26–30 | 270.51 | 37 | 7.31 |
| July | 1,845.83 | 225 | 8.20 |
| Aug 1–16 | 891.68 | 79 | 11.29 |
| Last 7d (Aug 9–15) | 418.14 | 29 | 14.42 |
Caution: "CPL doubled" is an artifact of mismatched bucket lengths. On matched clean 7-day weeks the series is 7.28 · 6.31 · 8.34 · 8.88 · 10.90 · 9.68 · 13.81 — matched 14-day windows give +69%, not ×2.
| Ad set | Spend | CTR | 7d freq | Leads | CPL | Parties | Cost/party |
|---|---|---|---|---|---|---|---|
| SQ1 / Mississauga | 1,003.11 | 3.11% | 1.64 | 172 | 5.83 | 2 | 502 |
| Hillcrest / Richmond Hill | 1,001.64 | 2.55% | 1.76 | 91 | 11.01 | 3 | 334 |
| UCM / Newmarket | 1,003.27 | 1.51% | 1.94 | 78 | 12.86 | 0 | — |
Spend spread across the three is CA$1.63 — ABO working as designed, so ad-set comparisons are efficiency comparisons, not allocation artifacts. Geo party counts are not significant: Hillcrest vs SQ1 z = 1.21 (p ≈ 0.23); UCM's zero has P(zero) = 0.22 under the null.
| Ad set | CPM Jun→Aug | CTR Jun→Aug |
|---|---|---|
| SQ1 | 14.81 → 11.35 (−23%) | 4.78% → 2.64% |
| Hillcrest | 13.59 → 12.87 (−5%) | 2.94% → 2.32% |
| UCM | 11.84 → 12.26 (+4%) | 1.65% → 1.30% |
CPM flat-to-down while CTR falls ⇒ auction pressure and algorithmic penalty both refuted. But anchoring on the 5-day launch window overstates decay: July→August is −16% / −11% / −18%.
| Ad | Set | Spend | Share of set | CTR | CPM | Leads | CPL |
|---|---|---|---|---|---|---|---|
| R2 Seamless — UCM | UCM | 911.33 | 90.8% | 1.53% | 11.52 | 70 | 13.02 |
| R2 Seamless — HILL | HILL | 622.72 | 62.1% | 2.79% | 12.80 | 67 | 9.29 |
| R2 Seamless — SQ1 | SQ1 | 509.74 | 50.8% | 3.18% | 12.11 | 87 | 5.86 |
| R1 4 Reasons — SQ1 | SQ1 | 483.23 | 48.1% | 3.03% | 11.23 | 83 | 5.82 |
| R1 4 Reasons — HILL | HILL | 376.89 | 37.6% | 2.18% | 12.35 | 24 | 15.70 |
| R1 4 Reasons — UCM | UCM | 87.22 | 8.7% | 1.32% | 11.77 | 8 | 10.90 |
| R4 Aya — SQ1 | SQ1 | 11.07 | 1.1% | 4.27% | 18.89 | 2 | 5.54 |
| R4 Aya — UCM | UCM | 5.57 | 0.6% | 1.48% | 11.78 | 0 | — |
| R4 Aya — HILL | HILL | 2.89 | 0.3% | 1.48% | 14.24 | 0 | — |
| Ad | Leads (hub) | Qualified (milestone) | Confirmed | Lead→booked |
|---|---|---|---|---|
| R1 4 Reasons — SQ1 | 82 | 1 | 1 | 1.2% |
| R2 Seamless — SQ1 | 81 | 2 | 1 | 1.2% |
| R2 Seamless — UCM | 66 | 2 | 0 | 0% |
| R2 Seamless — HILL | 66 | 1 | 1 | 1.5% |
| R1 4 Reasons — HILL | 21 | 1 | 2 | 9.5% |
| R1 4 Reasons — UCM | 8 | 0 | 0 | 0% |
| R4 Aya — SQ1 | 2 | 0 | 0 | 0% |
| total | 326 | 7 | 5 | — |
Leads (hub) is the hub-side count
(326 of 332 attributed). Every CPL on this page is Meta-denominated (341 campaign-wide). And
qualified here is the milestone count (7), not the money-event count (15) — two
different definitions.
| Ad | Impr | Plays | Plays/impr | p25/impr | ThruPlay/impr | Avg watch |
|---|---|---|---|---|---|---|
| R4 Aya — SQ1 | 586 | 539 | 92% | 15.4% | 11.09% | 6s |
| R4 Aya — HILL | 203 | 184 | 91% | 11.8% | 7.39% | 4s |
| R1 4 Reasons — SQ1 | 42,995 | 39,898 | 93% | 8.96% | 5.65% | 4s |
| R1 4 Reasons — HILL | 30,510 | 28,054 | 92% | 7.28% | 4.51% | 3s |
| R4 Aya — UCM | 473 | 425 | 90% | 5.07% | 3.17% | 2s |
| R1 4 Reasons — UCM | 7,391 | 6,447 | 87% | 5.34% | 3.13% | 2s |
| R2 Seamless — SQ1 | 42,059 | 13,971 | 33% | 5.24% | 1.14% | 3s |
| R2 Seamless — UCM | 79,100 | 25,447 | 32% | 3.64% | 0.70% | 2s |
| R2 Seamless — HILL | 48,609 | 11,032 | 23% | 2.90% | 0.64% | 2s |
reel1 (= R1) is 35.133s;
reel2 (= R2) is 16.02s. ThruPlay fires at 15s or 97%, whichever first — so it
means 43% watched for R1 and 94% for R2. The comparison ranks the short video last by
construction, and it killed an earlier "R2 is the weakest creative" finding.
video_continuous_2_sec_watched_actions returns NULL for every ad, so a true 3-second
hook rate is unavailable. Never substitute video_play_actions — on autoplay it approaches 100% of
impressions.
| Position (30d, all 3 sets) | Spend | Leads | CPL | SQ1 | UCM | HILL |
|---|---|---|---|---|---|---|
| feed | 789.01 | 84 | 9.39 | 5.64 | 14.63 | 13.25 |
| facebook_reels | 220.75 | 25 | 8.83 | 6.24 | 9.69 | 15.74 |
| instagram_stories | 544.89 | 54 | 10.09 | 5.93 | 16.71 | 11.89 |
| facebook_stories | 102.16 | 7 | 14.59 | 15.36 | 13.49 | 15.49 |
| instagram_reels | 129.99 | 6 | 21.67 | 14.46 | 28.64 | 43.52 |
instagram_reels is worst in all three sets; instagram_stories is fine —
Hillcrest's best. An aggregate "Facebook beats Instagram" reading is the wrong granularity.
Do not exclude it anyway: a placement exclusion is a targeting edit that resets the ad set,
shrinks the auction pool, and kills the Feed-format probe — for CA$2.38/day.
| Age | Spend | Leads | CPL |
|---|---|---|---|
| 18–24 | 6.17 | 0 | — |
| 25–34 | 661.79 | 68 | 9.73 |
| 35–44 | 1,089.89 | 103 | 10.58 |
| 45–54 | 29.46 | 5 | 5.89 |
| Tier | Count | Rate |
|---|---|---|
| Inquiry (hub) | 333 | 100% |
| Qualified — money event | 15 | 4.5% |
| Qualified — milestone stamped | 7 | 2.1% |
| Confirmed (lineage) | 6 | 1.8% |
| Confirmed (contact identity) | 7 | 2.1% |
| Paid | CANNOT RESOLVE — deposit_received_cents populated in 3 of 699 holds (failed control) | |
meta_leads → slot_holds yields
462 rows and exactly ZERO on confirmed. Positive control proves scope: 170 inquiry,
150 lost, 7 cancelled.
lost; the family re-enters through a
different door — the website form or a reply to the nurture email — creating a second hold that
confirms. Confirmed-hold source surfaces: 39 organic inbound email · 11 main-site form · 2 birthday LP ·
0 Meta lead form.
| Hold | Match rule | Meta lead date | Sibling Meta hold | Lag (days) |
|---|---|---|---|---|
| 355 | phone | 2026-07-03 | 341 lost | 4.11 |
| 281 | phone | 2026-06-28 | 279 lost | 4.48 |
| 344 | phone | 2026-06-29 | 290 cancelled | 4.76 |
| 555 | email local-part (probable) | 2026-07-18 | 491 inquiry | 5.00 |
| 421 | phone | 2026-07-02 | 331 lost | 8.74 |
| 618 | 2026-07-17 | 479 lost | 14.37 | |
| 579 | phone | 2026-07-08 | 392 merged | 18.76 |
Lag: min 4.11 · median 5.00 · p75 8.74 · max 18.76 days. Every sibling Meta hold is dead — that is the two-door pattern, seven times out of seven.
| Cohort | People | Meta-door hold | Meta-door died | 2nd-door re-entry | Confirm % (lineage) | Confirm % (reconnected) |
|---|---|---|---|---|---|---|
| C1 Jun 27 – Jul 10 | 111 | 111 | 111 | 6.31% | 0.00% | 3.60% (4) |
| C2 Jul 11 – Jul 24 | 98 | 96 | 96 | 4.08% | 0.00% | 2.04% (2) |
| C3 Jul 25 – Aug 7 | 79 | 78 | 78 | 1.27% | 0.00% | 0.00% (0) |
| C4 Aug 8 – Aug 16 | 38 | 37 | 37 | 0.00% | 0.00% | 0.00% (0) |
| total | 326 | 322 | 322 (100%) | 3.68% | 0.00% | 1.84% (6) |
CANNOT RESOLVE: the website-origin control comparison. Website-form and nurture-reply prospects have no origin event independent of the hold itself, so a second-door rate for them is not defined the same way. No number was manufactured on an incomparable base.
At the measured median lag of 5.0 days, P(zero August confirms) = 6%, not the 76% an
assumed two-week lag implies. The censoring defence does not hold. Note also that five genuine
status-kind confirms did occur account-wide in August — none Meta, two Google-LP — and the identity
join fires on them, so the Meta zero is not a scope artifact.
optimization_goal = QUALITY_LEAD — Meta's "Conversion leads",
which optimizes for lead quality and requires a CRM lead-status feed. What is actually flowing into
dataset 647265948134079 over 7 days: thousands of PageView, ~50 Purchase, and
one Lead — against 29 campaign leads. Meanwhile cost_per_result is labelled
"Leads (form)".
| Signal | Count | /week | /ad-set/week | vs ~50 threshold |
|---|---|---|---|---|
| Meta leads (the lead event itself) | 332 | 45.5 | 15.2 | 3.3× short |
birthday_qualified generated, all channels | 48 | 6.6 | 2.19 | 23× short |
birthday_qualified delivered to Meta | 18 | 2.9 | 0.95 | 53× short |
birthday_booked generated, all channels | 35 | 4.8 | 1.60 | 31× short |
The CAPI rail is partly shipped, not absent — 28 events have landed ok, but
29 of 47 qualified attempts were skipped:non_meta_source (see B7).
birthday_lead is a Google-only rail (meta_status NULL on all 42).
⇒ CAPI is instrumentation, not a rescue strategy.
ads_get_errors: empty. auction_ranking_benchmarks: no data.Meta Lead Form: emails; form v5
(4366657526983768) sole form since 2026-06-29; drafts 92–93%.form_start 101 → 53).learning_stage_info is not MCP-readable and the direct Graph API was unavailable ⇒
"learning-limited" is inferred from the 50-events/7-days heuristic. A 10-events/3-days variant
may apply.capi_crm_setup on this campaign (+8),
budget_limited on the Hillcrest ad set (+5), partnership_ads (+1).slot_holds.customer_email is 53/53 real
addresses. The @boogles.ca placeholder rule applies to Square customer records — a
different table.leads.party_id
(NULL 549/549) · conversions.party_id (NULL since 2026-07-26) · conversions.lead_row_id
(0/125 on all birthday types).conversions.party_id is NULL on every birthday_qualified row from 2026-07-25 onward, so
the Meta-cohort share of 24 of the 48 qualified events cannot be resolved.CAMPAIGN 120250641116100494 Birthday — GTA ACTIVE
AD SETS (all ACTIVE · CA$20.00/day · QUALITY_LEAD · bid "Highest volume")
SQ1 / Mississauga 120250660577030494
UCM / Newmarket 120250660577020494
Hillcrest / Richmond Hill 120250660576970494
ADS (all ACTIVE) — spend · ad_id · adset_id · creative_id
911.33 120250738811920494 R2-Seamless-UCM 120250660577020494 1789682088862554
622.72 120250740889250494 R2-Seamless-HILL 120250660576970494 1390539682920319
509.74 120250739216590494 R2-Seamless-SQ1 120250660577030494 4667070246949676
483.23 120250738928910494 R1-4Reasons-SQ1 120250660577030494 2084061652519688
376.89 120250738984910494 R1-4Reasons-HILL 120250660576970494 2228187117956550
87.22 120250660576980494 R1-4Reasons-UCM 120250660577020494 1269230088423756
11.07 120250739213690494 R4-Aya-SQ1 120250660577030494 36705252715788517
5.57 120250660576990494 R4-Aya-UCM 120250660577020494 1723567632218836
2.89 120250740881430494 R4-Aya-HILL 120250660576970494 2143369303229689
VIDEO ASSETS
reel1_birthday_9x16_v2.mp4 1388250519892946 35.133s (= R1)
reel1_birthday_4x5.mp4 1535628331547571 35.133s
reel2_birthday_9x16.mp4 1348636140545018 16.020s (= R2)
reel2_birthday_4x5.mp4 2159971927913514 16.020s
FIXED REFERENCES
FB Page 427011523828543
instagram_user_id 17841462856760171 (hardcode — API re-resolution blocked on this token)
Instant Form v5 4366657526983768
Pixel / dataset 647265948134079
NOTE: all 9 creatives were renamed 2026-08-16 from "{{product.name}} 2026-06-28-<hash>"
to "<concept>-<geo>-2026-06-28". Older documents show the stale names.