Ask the Real Marketing Question
Put the stack to work. Combine Google Ads, Klaviyo, and GA4 to answer the kind of cross-channel question your BI tool can't handle.
What you'll do
Ask your AI analyst the signature question this module was built for - one that requires all three data sources at once. Then learn the habits that get you consistently good answers.
Why this step matters
The whole point of the last five steps - the CLI, the MCP, the ingestion, the staging + reports layers, the context file - was to make this step possible: asking a question that spans paid, email, and web in one breath, and getting a worked answer in 30 seconds. Most marketing teams need a custom BI workstream to answer this. You just built it in a morning.
You built reports.channel_daily in Step 4 specifically so the AI doesn't have to remember to divide cost_micros by 1,000,000 or pick an attribution model every session. Your AGENTS.md tells the agent to default to reports.* - so this question is mostly a SELECT against a pre-cleaned, pre-unioned table.
The signature question
Paste this into your AI tool:
Using reports.channel_daily, compute blended CAC and ROAS by channel for the last 90 days available. Break down:
- Paid Search - sum cost_usd and conversions, then
cac = cost_usd / conversions,roas = attributed_revenue / cost_usd - Email - sum attributed_revenue (cost is $0); show revenue-per-thousand-recipients as a soft proxy for efficiency
- Organic - sum sessions, conversions, attributed_revenue (cost is $0); show conversion rate
Then produce a blended CAC for the period: total cost_usd across all channels / total conversions across all channels - and call out that this only counts conversions captured in reports.channel_daily, so it understates true acquisition if email or organic conversion tracking is partial.
Default to reports.channel_daily. Only drop into staging.* or raw.* if the user is asking for a column that hasn't been surfaced upstream (e.g. campaign-level breakouts), and tell me when you do.
Show me the SQL first. State the attribution caveats in plain English. Only execute once I approve the plan.
What to look for in the agent's plan
Before approving the SQL, check that the agent:
- Queries
reports.channel_dailyas the primary source - notraw.*orstaging.* - Uses the pre-computed
cost_usd(notcost_micros) andcac_usdcolumns - Does not sum
attributed_revenueacross all three channels and call it "total marketing revenue" (that's double-counting - it should sum within a channel and present per-channel) - Surfaces the
data_caveatcolumn or restates the attribution assumptions in plain English - States explicitly if it does drop into
staging.*(e.g. forcampaign_namebreakouts) and why
If the agent reaches into raw.google_ads_campaigns to recompute things, push back: "reports.channel_daily already has cost in USD and CAC computed - use that." This is the discipline that makes the layered pipeline pay off.
Follow-up questions to try
Once the first question runs clean, keep pulling threads - tap any prompt below to copy it:
From reports.channel_daily, which day-of-week has the highest email attributed_revenue per send? Compare against Paid Search cac_usd by day-of-week - do they correlate?
Compute ROAS by campaign - drop down to staging.google_ads for this since reports.channel_daily is aggregated by channel, not campaign. Group by campaign_name and sort descending. Flag any campaign with ROAS < 1.0 as candidates to pause.
Cross-validate Google Ads vs GA4: for reports.channel_daily Paid Search rows, do the conversion counts roughly match staging.ga4 rows where sessionSource = 'google' and sessionMedium = 'cpc'? If they disagree by more than 20%, explain why (likely attribution-window differences).
From staging.klaviyo, which campaign had the highest revenue_per_recipient in the last 30 days? What was the subject line? (ask the user for this - we don't have it in the raw data)
Each of these takes a marketing analyst 30–60 minutes manually. Your agent does them in the time it takes to write the prompt.
Save the good queries
When the agent writes a SQL query you like, ask it to save it as a Bruin SQL asset in the reports layer:
Take that query and save it as marketing-analyst-101/assets/reports/blended_cac_by_channel.sql materialized as reports.blended_cac_by_channel (materialization view). Add a top-level description, column descriptions, the attribution assumptions in a data_caveat comment, and a tier:reports tag.
Now it's part of your pipeline. Next run of bruin run, the view is rebuilt from fresh data. You're not just asking questions - you're growing your reports layer with every analysis you save.
Habits for getting consistently good answers
- Ask for the plan before the result. Prompts that include "show me the SQL first and explain the logic" catch mistakes cheap.
- Be specific about time windows. "Recent" is ambiguous; "last 30 days ending today" is not.
- Name the attribution model. Most wrong answers in marketing analytics come from mismatched attribution. Tell the agent which model to use (last-touch, first-touch, last-non-direct, etc.).
- When in doubt, ask for counts first. "How many sessions match X?" before "here are all the sessions matching X" - saves you from chasing ghost results.
- Iterate on
AGENTS.md. Every time the agent gets something wrong for a domain reason, add a line toAGENTS.mdso it doesn't repeat the mistake.
What just happened
You built a complete marketing-analyst workstation - ingest, database, context, agent - on a single laptop, in one sitting, without writing SQL or Python yourself. The stack is yours to keep. Swap in different date ranges, add Meta Ads or Shopify, plug in your CRM. Every addition follows the same pattern: prompt the agent, it runs Bruin, the data lands.
Where to go next
- Shopify Data Pipeline - go deeper on the e-commerce side with a cloud database and a full data-cleanup layer
- Build an AI Data Analyst - the full deep dive on the MCP + AGENTS.md pattern for any data domain
- Using Bruin Templates - skip scaffolding entirely with pre-built pipelines