What wires in, and when
Connections
V1 runs on generated data. This is the list of what replaces it, in the order it can be replaced, with what is genuinely confirmed separated from what somebody still has to check.
Are the accounts still there?
Every account this app is configured to read, checked against what Windsor actually holds. The roster moved in both directions on 2026-08-21 and nothing noticed: an account that drops out returns no rows, which reads on every screen as a client that simply is not spending.
Systems
| System | Role | State | Phase | What is actually known |
|---|---|---|---|---|
| Windsor.ai | Google Ads and Microsoft Ads read and push, Meta read | Wired | Wired for 9 clients | Nine of the ten clients read spend and traffic from Windsor: real account ids, real field names, and CRM leads attributed to a channel. JG Hause reads leads from a Google Sheet instead and needs no key, which is why it is the one client showing live data today. The rest need the API key: set WINDSOR_API_KEY in .env.local and they go live on the next request. |
| JG Hause Meta ad account | Spend, alongside the sheet leads | Wired | Added 2026-08-21 | Account 1171989478475558 went into the connector on 2026-08-21, so this client now reads spend from Windsor and leads from its sheet. The first thing it shows is that the account is spending with nothing but Meta's own test submission recorded against it. Worth considering the facebook_leads connector too: it pulls Instant Form leads from Meta directly and would remove the sheet and the manual step behind it. |
| Resto Dispatch, both accounts | Gone from the connector | Blocked | Regressed 2026-08-21 | Meta 991472139968253 and Google Ads 961-709-1844 were both listed in the connector on the morning of 2026-08-21 and were gone by the evening. The Meta account carried $10,040 and 96 leads since February, so the history exists and the connection does not. The client is marked disconnected rather than left configured, because a configured account that returns nothing reads as a client with no spend. |
| Meta MCP | Push changes to Meta | Confirmed | V2 | Windsor reads Meta but does not write it. This is the write path for Cuseum, Corsa and JG Hause. |
| HubSpot | Lead and revenue truth for Cuseum and EditShare | Confirmed | V1.1 | Two portals: 9055727 for Cuseum, 6296100 for EditShare. Contacts whose source is OFFLINE are bulk imports and are excluded, otherwise imports swamp the real leads. |
| GoHighLevel | Lead truth for the pool clients | Confirmed | V1.1 | Reachable through Windsor. Poolside Renos also serves its landing pages from here, which is where the broken anchor URLs come from. |
| Google Sheets | JG Hause leads, in place of a CRM | Wired | Live now | Read straight from the sheet as CSV, no key and no connector needed, so this is the one client returning live data today. Meta seeds every new Instant Form with a test submission and that row is excluded. The sheet must stay shared as "anyone with the link can view" for this to work, which is worth weighing: it holds homeowner names, emails and phone numbers. Connecting it in Windsor instead would keep it private. Nothing personal ever leaves the server either way; only daily counts reach the browser. |
| Semrush | Keyword volume, cost per click, difficulty | Wired | Captured for 2 clients | The Keywords tab runs on a real Semrush pull for EditShare and Poolside Renos, captured 2026-08-21 from the phrase_these report on the us database. Ahrefs is not used: Keyword Explorer is off the current plan and would fail on the first call. Research is a dated snapshot rather than a live feed, which is how it is actually used. |
| Higgsfield | Creative generation, image and video | Confirmed | V2 plus | MCP is available. Feeds the creative fatigue cards once competitor harvesting can say what to make. |
| Leadpages | Building and publishing landing pages | Answered, no | Checked 2026-08-21 | Checked, and the answer is no. The connection covers pages, sites, blogs, assets, SEO and publishing, and a page record carries only slug, title, url, status and timestamps. There is no views, visitors, submissions or conversion figure anywhere, and no results endpoint even for the A/B experiments it does run (four Cuseum pages currently have variant B records). Landing page performance has to come from somewhere else. |
| Google Ads final_url | Landing page performance, in place of Leadpages | Wired | Verified 2026-08-21 | The workable substitute. Windsor exposes final_url alongside clicks, impressions, spend and conversions, so a landing page can be judged by the ads pointing at it. Proved on Poolside: four GoHighLevel anchor URLs took 713 impressions and 5 clicks for zero leads, against 1.25% click through on the clean URL. It also covers the clients whose pages are not on Leadpages at all, which includes Poolside. |
| Ad libraries and Google Ads Transparency | Competitor creative harvesting | Later phase | V2 plus | A custom rig, no MCP. Deliberately last: auction insights inside Google Ads already covers most of the value. |
| analytics.1212agency.com | The client facing side of the same data | Confirmed | Shipped | Separate app, same Windsor pipe. That one is what a client logs into. This one is what you log into. They should not be merged: the audiences want opposite things. |
Client by client
What each client can show today, and the one thing standing in the way where it cannot.
| Client | Channels | Lead source | State | Blocked on |
|---|---|---|---|---|
| EditShare | HubSpot | Full picture | ||
| Cuseum | GoogleMetaLinkedIn | HubSpot | Full picture | |
| Poolside Renos | GoogleLSA | GoHighLevel | Full picture | |
| Landmark Custom Pools | GoogleLSA | GoHighLevel | Full picture | |
| Millenium Construction | GoogleLSA | GoHighLevel | Full picture | |
| Majestic Pool Construction | GoHighLevel | Full picture | ||
| JG Hause Construction | Meta | Google Sheet | Full picture | |
| Corsa America Rally | Meta | Not connected | Spend only | Rally spots are bought straight from the ad. Meta reports zero purchase events and zero leads across August against $2,322 of spend, so there is no conversion signal of any kind. Spend and traffic show; nothing else can. |
| Resto Dispatch | MetaGoogle | HubSpot | Waiting on access | Dropped out of the Windsor connector during 2026-08-21. It carried $10,040 and 96 leads since February, so the history exists; the connection does not. |
| Beyond Blue Outdoor Group | GoHighLevel | Full picture | ||
| Tidal Custom Pool | GoHighLevel | Full picture |
What Apply can actually do
Checked against the live Windsor action list on 2026-08-21. Two rules have no write path at all, and V2 must show those as read only rather than as a button that quietly does nothing.
| Rule | How it gets applied | Detail |
|---|---|---|
| Negative keywords | Windsor pushes itpush_negative_keywords | Undo: remove_negative_keywords |
| Keyword opportunity | Windsor pushes itpush_keywords | Undo: remove_keywords |
| Bidding | Windsor pushes itset_target_cpa, set_campaign_bidding_strategy | Undo: set the previous strategy back |
| Ad schedule | Windsor pushes itset_ad_schedule | Undo: replay the snapshot taken before the change |
| Budget shift | Windsor pushes itset_campaign_budget | Undo: set the stored amounts back |
| Account structure | Windsor pushes itpause_ad_group | Undo: enable_ad_group |
| Creative fatigue | Windsor pushes itpause_ad on Meta and Google | Undo: enable_ad |
| Conversions stopped | Windsor pushes itpause_ad, enable_ad on Meta | Undo: reverse the pause |
| Search ad copy | Windsor pushes itcreate_responsive_search_ad, then pause_ad on the one it replaces | Undo: pause the new ad and enable_ad the old one |
| Landing page | Browser sessionGoogle Ads, ad level, final URL | Windsor has no action for editing an existing ad's final URL. It can create a responsive search ad but not redirect one. |
| Geography | Browser sessionGoogle Ads, campaign settings, locations | Windsor exposes language targeting but no location targeting, so a city exclusion cannot be pushed. |
| Needs new creative | Browser sessionMeta Ads Manager, and a creative brief for whoever produces the work | Making an ad is not an API call. The card produces the brief and the concept list; a person or a generation tool makes the asset. |
| Tracking | Read only | Informational by design. There is nothing to push. |
| Impression share | Read only | Informational by design. There is nothing to push. |
| Closed loop | Read only | Informational by design, and the fix is in the client's CRM, not the ad platform. |
| Nothing converting | Read only | Nothing to push. The answer is either a broken form or an offer nobody wants, and neither is fixed from here. |
Still needed from you
- The Windsor API key. Everything else for EditShare and Poolside is done. Put the real key in .env.local as WINDSOR_API_KEY and restart. Nobody should paste a key into a chat.
- The full list of data sources the brain should read, so nothing is discovered late.
- Per account, confirm an API key can be created. Access, not keys.
A decision on the two rules with no write path.Settled: landing page URLs and city exclusions are driven in the browser, on your machine, from the change list the card prepares.Confirm Leadpages can report landing page performance.Checked: it cannot. The landing page rule runs on Google Ads final_url instead, which also covers the clients who are not on Leadpages.- A screen recording of one full campaign build, thinking out loud. Raw is fine. That recording is the training data for the V2 account manager.
- A decision on JG Hause: add the Meta account to Windsor, or keep working from the Monday export and accept a week of lag.