Building a Multi-Agent Marketing Stack: Wiring GA4, Search Console, and Meta Ads into One System A developer at Free Mind Consultancy built a multi-agent marketing stack that isolates specialized agents per channel (SEO, paid social, content) with narrowly scoped API credentials and a thin orchestration layer that only receives summarized state. The architecture prevents credential leakage, rate-limit issues, and data hallucination by normalizing API responses from GA4, Search Console, and Meta Ads into a flat dict shape before they reach an LLM. Most "AI marketing automation" content online is either a no-code tool pitch or a vague thinkpiece. This is neither — it's a breakdown of the actual architecture pattern we landed on after building out a multi-channel marketing agent system: separate specialized agents per channel SEO, paid social, content , coordinated by a thin orchestration layer, all backed by real APIs instead of scraped dashboards. The obvious first instinct is one big agent with access to every tool: GA4, Search Console, Meta Ads, CMS, everything. In practice this falls apart fast: The fix that worked for us: one agent per channel, each with narrowly scoped credentials and a fixed API surface , plus a coordination layer above them that only sees summarized state, not raw API access. For the SEO agent, GA4 and Search Console access is via a single service account with read-only Analytics + Search Console scopes: python from google.oauth2 import service account from google.analytics.data v1beta import BetaAnalyticsDataClient creds = service account.Credentials.from service account file "credentials/service-account.json", scopes= "https://www.googleapis.com/auth/analytics.readonly" , client = BetaAnalyticsDataClient credentials=creds The Meta Ads agent gets its own token, scoped to a single ad account ID — never a full Business Manager token. This is a deliberate constraint we enforce at the prompt/instruction layer too: even if the underlying token could see other ad accounts, the agent is told exactly one account ID is in scope and to refuse to act on anything else. Defense in depth beats trusting the token scope alone. GA4 and Search Console return data in almost-but-not-quite-compatible shapes. GA4: for row in response.rows: dims = d.value for d in row.dimension values mets = m.value for m in row.metric values Search Console: for row in response.get "rows", : keys = row "keys" clicks = row "clicks" ctr = row "ctr" float, e.g. 0.0248 position = row "position" If you feed raw API responses straight into an LLM's context across multiple sources, it will misattribute fields between them — CTR from one dimension values array gets confused with position from another. We normalize every source into the same flat dict shape {dimension, metric, value} before it ever reaches a prompt. Boring code, but it's the difference between reliable output and an agent that quietly hallucinates a number that looks plausible. The orchestration layer our "marketing manager" agent doesn't get API access at all. It only receives: This means the coordinator can't accidentally query GA4 directly and burn a rate limit, and it can't leak Meta Ads token access into an SEO conversation. Every cross-channel decision is made on summaries , not raw data — which also keeps the coordinator's context window small enough to reason well over a full week of multi-channel state. A few boring rules that saved us from leaking secrets, repeated per agent: .env per agent directory, never a shared root .env .gitignore scoped per agent .env , pycache / , .pyc , cache dirs rather than trusting a root-level ignore file to catch everything GET /users/me equivalent before anything else — cheap, catches key-format mistakes stray spaces in .env keys are a surprisingly common bug before they cost you a debugging session downstreamIf you're building anything beyond a single-tool AI agent, the channel-isolation pattern is worth the extra setup cost. It trades a bit of upfront boilerplate more credential files, more normalization code for a system where failures are contained, debuggable, and don't cascade — which matters a lot more once you have four or five channels running instead of one. Built and maintained by Free Mind Consultancy https://www.freemindconsult.com/ — we build AI-driven marketing automation SEO, paid social, content for authors, founders, and publishers. Read more about our business automation work https://www.freemindconsult.com/services/business-automation-india.html .