Meta Campaign Build — Friction Report STC Q2 2026

Campaign: STC Q2 — Spring Pruning Lead Gen  |  Build date: April 24–25, 2026  |  Updated: April 27, 2026  |  BOSSTORQUE / Sperry Tree Care

Build Summary
10
Friction points hit
5
Fixed in-session
5
Deferred / workaround
ItemValue
CampaignSTC Q2 — Spring Pruning Lead Gen
Ad account664046922693997
Ad set ID120245325333490017
Ad IDs120245328622400017, 120245328577180017, 120245325333500017
New form ID (with tracking)1649713622589937
Old form ID1479070424003893
Zapier zap ID361002715 (FB Lead → Jobber, "Any Form" trigger)
Launch dateApril 27, 2026 @ 8:00 AM PT
Budget$50/day CBO, ends June 30
AudienceAdvantage+ broad, 350K–412K estimated reach
Location17 zip codes — Lane + Benton counties, OR
Friction Points — What Slowed Us Down
F1 — Blocker
Meta Instant Form locks on activation — can't edit tracking parameters after publishing
Once a form status changes from Draft to Active, all fields are locked. There is no way to add hidden fields or tracking parameters post-activation, even if no leads have been collected.
Fix applied: Duplicated the original form, added 5 tracking parameters (campaign_name, adset_name, ad_name, source, medium) to the copy, published the copy, then swapped ads to the new form.
F2 — Blocker
React-controlled date picker — start date couldn't be changed programmatically
Meta Ads Manager uses React-controlled inputs for dates. All programmatic methods failed: nativeInputValueSetter, execCommand, fiber traversal, and direct value assignment. The field visually updated but React's synthetic state did not sync.
Fix applied: Jason manually set the start date to Apr 27 via the UI.
F3 — Partial
Form swap confirmation unavailable after publish lock
After clicking the new form in the edit panel and Jason completing the business info gate + publishing, editing was locked immediately. Could not verify which form is attached to the 3 ads. DOM automation did not confirm selection state before publish.
Status: Zapier is set to "Any Form" trigger so leads will still flow to Jobber regardless. Tracking data will be present if the new form was selected; absent if not. Cannot confirm without checking the Lead Center.
F4 — Time sink
Ad IDs not accessible programmatically from Ads Manager DOM
Ads Manager renders ad data entirely in React state — no IDs exposed in HTML attributes, href links, or data- attributes. Multiple JS approaches (fiber tree traversal, outerHTML regex, Graph API fetch) all failed due to React rendering and CORS restrictions.
Fix applied: Jason selected all 3 ads, clicked Edit, and the resulting URL contained all 3 ad IDs in the selected_ad_ids parameter. Extracted IDs from URL.
F5 — Deferred
Stories/Reels 9:16 crops couldn't be added after publish
Placement-specific media crops require editing the ad creative. Once the campaign was published, editing was locked. The crops were identified as needed during the build but not added in time.
Workaround: Meta will auto-crop for Stories/Reels. Calendar reminder set for Apr 25 4pm ET to add crops manually once active status potentially unlocks creative edits.
F6 — Deferred
Zapier step 3 tracking field mapping — incomplete
The hidden tracking fields (campaign_name, adset_name, ad_name, source, medium) are captured in the FB lead payload but not yet mapped into the Jobber Create Request note or source field. The step was added after the form was built.
Next step: Edit Zapier zap 361002715, step 3 (Jobber Create Request), and map the 5 hidden fields into the request note.
F7 — Surprise gate
Meta required business address before allowing first publish
On first publish attempt, Meta surfaced a business info gate requiring legal name and address. This is a one-time step for new ad accounts or first campaign publishes.
Fix applied: Address confirmed and saved (Sperry Tree Care, 29978 East Enid Road, Eugene OR 97402). Will not recur for this account.
F8 — Tooling FIXED
Meta Marketing API MCP configured with personal ad account ID instead of Sperry account
The meta-marketing MCP was configured with META_AD_ACCOUNT_ID = act_664046922693997 (Jason's personal account) instead of act_2556180444815953 (Sperry Tree Care). All MCP campaign calls during the build targeted the wrong account. Confirmed via list_ad_images returning IDs prefixed with 664046922693997.
Next step: Edit claude_desktop_config.json → mcpServers → meta-marketing → env → META_AD_ACCOUNT_ID → change to act_2556180444815953. Restart Claude Desktop. Verify with list_campaigns.
✅ Resolved Apr 27 2026: claude_desktop_config.json updated to act_2556180444815953. Claude Desktop restarted. MCP verified — list_campaigns returns STC_Residential_Spring_LeadGen_Apr2026 in correct Sperry account. list_ad_images and get_account_insights both functional (ads_read + ads_management permissions confirmed).
F9 — Incident (Apr 27)
Campaign launched and ran in personal ad account — $11.98 spent, 1 lead lost
On Apr 27 2026, the campaign "STC Q2 — Spring Pruning Lead Gen" (ID: 120245325333480017) was built and activated in the personal ad account (664046922693997) instead of Sperry's business account (act_2556180444815953). The campaign ran for several hours before Jason noticed via Ads Manager. Total damage: $11.98 spent, 735 impressions, 1 lead captured in the personal account (not Jobber-connected). Root cause: MCP account ID misconfiguration (see F8). Campaign was paused at 12:28 PM PT. All creative/targeting documented at sperry-meta-rebuild-apr2026.jason-8ce.workers.dev. Full rebuild required in correct account.
Fix required: 1) Fix MCP config (F8). 2) Retrieve the 1 lead from personal account lead center and enter manually in Jobber. 3) Rebuild full campaign (campaign + ad set + 3 ads) in act_2556180444815953 using rebuild doc. 4) Archive wrong-account campaign after new one is confirmed live. 5) Add pre-build account verification to standard operating procedure.
F10 — Client Rejection (Apr 27)
AI-generated creative rejected by Rob Miron — 4 specific issues
Rob Miron (Sperry owner) saw the ads and flagged 4 problems via iMessage: (1) Trees were topped — improper pruning that contradicts Sperry's care standards. (2) Images are "obviously AI" — synthetic look, not real Sperry work. (3) Person shown is not a Sperry employee. (4) "Spring is the best time to prune" is factually incorrect — pruning timing depends on species. Rob requested the IG post be taken down and asked Jason to use real Sperry photos/videos (being collected by his team). Rob approval required before relaunch. Approval page: sperry-meta-approval-apr2026.jason-8ce.workers.dev.
Fix required: (1) Remove inaccurate "best time to prune" claim from Ad 1 copy. (2) Wait for real Sperry team photos from Rob. (3) Rebuild ads with real imagery showing proper pruning technique and actual Sperry employees. (4) Send approval page to Rob for sign-off before activating. Revised copy already documented in approval page.
Improvements for Next Time
1
Build the tracking form first — before creating any ads
Create the instant form with all 5 hidden tracking parameters before the first ad is created. This eliminates the duplicate-and-swap workflow entirely and ensures all ads are born with the correct form attached.
2
Add Stories/Reels crops during ad creation, not after
When building each ad creative, go to "Edit creative for each placement" and upload the 9:16 crop immediately. Don't leave this for post-publish. Meta locks creative editing on publish.
3
Save ad IDs to a reference file during build
After creating each ad, immediately copy the ID from the URL and paste it into a campaign reference sheet. Ad IDs are needed for Zapier mapping, reporting, and any programmatic edits.
4
Map Zapier tracking fields before the campaign goes live
Once the form is published, immediately update Zapier step 3 to map the hidden fields into the Jobber request note. Don't wait until post-launch — the mapping should be ready on day one.
5
Close extra Zapier editor tabs before making changes
Multiple open Zapier editor tabs for the same zap cause a "multiple tabs" conflict warning and can cause edits to be overwritten. Open one tab, make the change, publish, close.
6
Confirm Meta ad account ID at session start
Verify which ad account the campaign runs under (found in Ads Manager URL: act=XXXXXXX) and confirm it matches the meta-marketing MCP configuration before attempting any API-based work.
7
Verify MCP account ID against Ads Manager URL before every Meta session
At session start, read the META_AD_ACCOUNT_ID from claude_desktop_config.json and compare to the act= parameter in the Ads Manager URL for the target account. If they don't match, fix the config BEFORE doing any campaign work. This one-time check prevents the F9 incident from recurring. Add to session start checklist.
8
Never use AI-generated images with people or trees in client-facing Sperry ads
Sperry's brand depends on authenticity — 35 years of real local work. AI imagery looks fake to homeowners, shows incorrect pruning technique, and features non-Sperry people. Policy going forward: all Sperry ad creative must use real photos from Rob's team or Michele's existing library. AI can be used for backgrounds, overlays, or text treatments only. Get explicit client sign-off on all creative before building the campaign.
9
Send creative for client approval BEFORE building the campaign
Build a lightweight approval page (CF Worker) showing ad images and copy. Send to Rob/Michele for thumbs-up before touching Ads Manager. This catches factual errors (pruning claims), brand issues (AI people), and creative mismatches before they go live. Approval takes 10 minutes. Fixing a live campaign takes hours and costs real money.
Connecting More Efficiently to Meta — Next Build

The current setup requires heavy manual UI interaction because there's no reliable programmatic access to the Ads Manager. Here's the path to fix that:

1
Create a System User in Meta Business Manager
Go to Business Settings → System Users → Add. Create an Admin-level system user (e.g., "BOSSTORQUE Automation"). Assign it to the Sperry Tree Care ad account with full access. System Users generate tokens that never expire — no more manual token refresh.
2
Generate a never-expiring access token
From the System User, click "Generate Token" → select the app (BT API for Social Campaigns, app ID 1508033547582606) → grant: ads_management, ads_read, leads_retrieval, pages_read_engagement. Copy the token — it does not expire unless revoked.
3
Store token in the CLAUDE.md memory
Save the token to .claude/memory/context/api-keys.md under a "Meta System User Token" entry. Also update the meta-marketing MCP configuration with the correct ad account ID (664046922693997 for Sperry) and this token.
4
Fix the meta-marketing MCP account configuration
The MCP is currently pointed at act_2556180444815953 but Sperry campaigns run under act_664046922693997. Update the MCP config to use the correct account. Once fixed, campaign reads/writes, ad creation, and form lookups can all be done via MCP tools — no browser required.
5
Use Graph API for ad ID lookups and creative reads
With a valid system token, ad IDs, form IDs, and creative details are a single API call away: GET /v21.0/{adset_id}/ads?fields=id,name,creative. No more browser DOM scraping or manual URL extraction.
6
Pre-build a campaign template script
Build a bash/Python script that: (1) creates the instant form with tracking parameters via API, (2) creates the ad set with correct targeting and schedule, (3) uploads creatives and creates ads with the form attached. For the next Sperry campaign, the entire build is one script run — not a 3-hour UI session.
Key reference IDs for next build: Meta App ID: 1508033547582606  |  Business ID: 296763005283516  |  Sperry Page ID: 125022367516741  |  Sperry Ad Account: 664046922693997  |  Instagram: sperrytreecare
Audience & Budget — How Meta Manages This Campaign

Audience — Advantage+ (Broad)

This campaign uses Meta's Advantage+ audience with zero targeting inputs — no age, gender, interests, behaviors, or lookalikes. Meta's algorithm has complete freedom to find whoever it thinks will submit a lead form within the 17-zip-code geo constraint.

What Meta DoesDetail
Starts broad Uses early engagement signals (form opens, completions, dwell time) to identify patterns in the 350K–412K addressable pool
Builds a conversion model Learns who converts based on anyone who submits the form — model is specific to this campaign and ad account
Adjusts in real time Shifts delivery toward users similar to converters; narrows toward high-intent profiles without any manual input
Geo stays fixed 17 zip codes (Lane + Benton counties) are the only hard constraint. Everything else is Meta-controlled.

Budget — $50/Day CBO (Campaign Budget Optimization)

The $50/day sits at the campaign level. Meta allocates across all 3 ads dynamically — not evenly — based on which creative is generating the lowest cost-per-lead.

PhaseWhat HappensTimeframe
Learning phase Meta explores — delivery is less efficient, CPM and CPL are higher than steady-state. May underspend the $50 cap while calibrating. Do not make changes during this window — it resets the clock. Days 1–7 (approx. 50 optimization events)
Optimization phase Spend stabilizes near $50/day. Meta shifts budget toward the best-performing ad — typically one ad captures 60–70% of spend. Other ads stay in rotation as hedges. Day 7+ once learning exits
Steady state Efficient delivery, consistent CPL, creative winner established. Review performance at 2-week mark before making any adjustments. Week 2+
Operating rule for this campaign: Jason sets the geo and the daily budget cap. Meta controls audience selection, creative allocation, placement mix, and bid strategy. Do not adjust targeting, budget, or creative during the 7-day learning phase. First meaningful performance review: May 11, 2026 (2 weeks post-launch).
Open Items Before / After Launch
ItemPriorityOwnerWhen
Add 9:16 crops to all 3 ads for Stories/Reels Medium Jason Apr 25 @ 4pm ET (calendar set)
Map tracking fields in Zapier step 3 → Jobber note Medium Claude Before Apr 27 launch
Verify new form (1649713622589937) is attached to 3 ads High Jason Check Lead Center after first test lead
Trash old prototype Zapier zap (ID 359442545) Low Claude Any time
Retrieve 1 lead from personal account → enter in Jobber manually High Jason ASAP — lead may go cold
Fix meta-marketing MCP account ID in claude_desktop_config.json ✅ Done Apr 27 Done Jason + Claude act_2556180444815953 active, verified with list_campaigns
Receive real Sperry photos from Rob's team High Rob's team → Jason Before April 29
Rob approval via sperry-meta-approval-apr2026.jason-8ce.workers.dev High Rob Miron Before April 29 launch
Rebuild campaign in Sperry account (act_2556180444815953) High Claude April 29 (after config fix + photos + approval)
Fix meta-marketing MCP account ID (config file) ✅ Done Apr 27 Done Jason + Claude Completed — act_2556180444815953 active, MCP verified
Create Meta System User + never-expiring token Medium Jason + Claude Before next build