Build a No-Code Marketing Analyst: Airtable + Claude + Slack in 3 Hours
Contents
At 9:14am on a Tuesday, the head of growth at a Series B e-commerce company typed into a channel: /analyst blended CAC by channel this month. Eleven seconds later, a Slack message came back with a small bar chart and a single sentence: "Paid social $48, Google $62, email $14, blended $39. Email is the cheapest by 3.4x — want me to look at scaling constraints?" She screenshotted it, pasted it into the board channel, and went back to coffee.
The system that produced that answer cost $99 a month in tools. It was built in a weekend by a marketing manager who had never written a line of Python. It is, in my opinion, the single most useful thing a small marketing team can build in 2025 — and almost nobody is building it, because they're stuck waiting for the $40k-a-year BI platform that the data team keeps de-prioritizing.
This is the build guide. Three hours, four data sources, one Slack command. By the end you have a marketing analyst that doesn't sleep, doesn't take PTO, and answers questions in plain English.
The architecture in one paragraph
Airtable is the database. It holds four tables — channel spend, GA4 traffic, email performance, and CRM-attributed revenue — all keyed by date and channel. Every morning, four automations (one per data source) refresh the rows. Claude is the analyst brain: it receives a user's question, looks at the relevant Airtable table (via a lightweight API call), and produces a structured answer that ends in a chart spec. Slack is the interface: a slash command /analyst <question> fires an Airtable automation that calls Claude, gets the answer, and posts it back to the channel as a rendered image. Total moving parts: three. Total code: zero, if you use Airtable's built-in scripting and Slack's built-in workflow steps.
The reason this works in 2025 and didn't in 2022 is that Claude can read a question like "what's our blended CAC by channel this month" and figure out which table to query, which filter to apply, and which chart best answers the question. In 2022 you would have had to hard-code every question. Now you write the schema once and Claude does the rest.
Hour 1: The Airtable base
The first hour is the most important. Get the data model wrong and Claude will confidently answer every question with garbage. Get it right and the rest of the build is a coffee break.
The four tables. Each table has a Date and Channel field, and that is the join key for everything downstream. Beyond that, the schema is intentionally narrow:
- Channel_Spend — one row per channel per day. Fields:
Date,Channel(Meta, Google, TikTok, etc.),Spend,Currency. - GA4_Sessions — one row per channel per day. Fields:
Date,Channel,Sessions,Engaged_Sessions,Conversions(GA4 key events),Revenue(purchase events, pulled from GA4 ecommerce). - Email_Performance — one row per campaign per send. Fields:
Send_Date,Campaign_Name,Recipients,Delivered,Opens,Clicks,Conversions,Revenue. - CRM_Attributed_Revenue — one row per channel per week. Fields:
Week_Start,Channel,New_Customers,Returning_Customers,Net_New_ARRorNet_Revenue(whichever fits your model).
The reason each table is keyed by channel + date is that almost every question a marketing team asks is a slice of those two dimensions. "CAC by channel this month" is CRM_Attributed_Revenue.New_Customers divided by Channel_Spend.Spend, grouped by channel, filtered to this month. Once Claude has the schema, it can pattern-match almost any question to a table.
Sync method. For an MVP, do not build a real-time pipeline. Use Airtable's CSV import or, better, Airtable's native sync with Google Sheets. The pattern: every Google Ads / Meta Ads / Klaviyo / HubSpot report gets exported to a Google Sheet on a daily trigger (a time-based trigger in Google Sheets does this in 30 seconds), and Airtable syncs to that sheet. The sync is bidirectional for the schema, one-way for the data. It is not glamorous. It works.
For GA4, the easiest no-code path is the official GA4 → BigQuery export, then a BigQuery → Google Sheets scheduled query that aggregates to channel + day. If that feels heavy, use the GA4 reporting API through a free connector like Airbyte or Coefficient. The goal at this stage is not elegance. The goal is having yesterday's numbers in Airtable by 9am.
Calculated fields. Add a few Airtable formula fields so the most common metrics are pre-computed:
Blended_CACin the daily summary view =Channel_Spend.Spend÷CRM_Attributed_Revenue.New_Customers(per channel, per day)Email_Revenue_Per_Recipientin Email_Performance =Revenue÷RecipientsROASin Channel_Spend =CRM_Attributed_Revenue.Net_Revenue÷Spend
These are the metrics Claude will reach for first. Having them as columns means Claude doesn't have to do the arithmetic in the prompt and can't get the math wrong.
By the end of hour 1 you should have: four tables populated with at least 30 days of historical data, a daily refresh set up for each, and a handful of formula columns. Open the Airtable interface designer and make a "Marketing Snapshot" view that joins the four tables on date + channel. You will use this view to spot-check answers later.
Hour 2: The Claude prompt
This is the single most important piece of the whole system, so do not skip the iteration. Most teams write a one-line prompt, get one bad answer, and decide AI doesn't work. The job in hour 2 is to write a prompt that survives 50 different questions.
The system prompt. Create an Airtable "Prompts" table with one record whose Body field contains the full system prompt. The body is the contract between you and Claude — change it once, the whole analyst changes with it. Start with this skeleton and customize:
You are a marketing analyst. You have access to four tables in this Airtable base:
- Channel_Spend: {Date, Channel, Spend, Currency}
- GA4_Sessions: {Date, Channel, Sessions, Engaged_Sessions, Conversions, Revenue}
- Email_Performance: {Send_Date, Campaign_Name, Recipients, Delivered, Opens, Clicks, Conversions, Revenue}
- CRM_Attributed_Revenue: {Week_Start, Channel, New_Customers, Returning_Customers, Net_Revenue}
Your job: answer the user's question with a number, a chart, and a one-sentence takeaway.
Steps:
1. Identify the metric the question is asking for (e.g. CAC, ROAS, conversion rate).
2. Identify the table(s) and the formula.
3. Identify the time window and the dimension to group by.
4. Pull the relevant rows from the Airtable API. If the user did not specify a window, default to "last 30 days".
5. Compute the metric. If you must estimate, label it "(est.)".
6. Return a JSON object in this exact shape:
{
"answer_short": "",
"table": [["Channel", "Value", ...], ...],
"chart_type": "bar" | "line" | "number",
"chart_title": "",
"x_label": "",
"y_label": "",
"caveat": ""
}
Rules:
- Never invent numbers. If the data is missing, return {"answer_short": "Data missing for "} with an empty table.
- Always include units in chart labels ($, %, etc.).
- If a question is ambiguous (e.g. "how is marketing doing"), pick the metric most likely meant (net new revenue, week over week) and state the assumption.
- If the question is not about marketing data, refuse politely. The reason this prompt is long is that Claude is only as disciplined as the contract you give it. "Never invent numbers" is the single most important line. Without it, Claude will produce a beautiful chart on days the data is incomplete. With it, Claude will say "data missing for TikTok on 2025-10-04" and the team trusts the system.
The "exemplar" pattern. After the system prompt, append 5–8 worked examples. The format is Q: ... A: ... and the A is the full JSON return shape. This is the single biggest lever for getting consistent output. Two examples are worth more than ten paragraphs of instructions. Cover: a CAC question, a trend-over-time question, a "what changed this week" question, an ambiguous question (so Claude sees the assumption-stating behavior), and a question the system can't answer (so Claude sees the refusal pattern). After you have 5 examples, the prompt rarely breaks.
Where Claude sees the data. You have two options. Option 1: feed Claude the relevant rows inline in the prompt. This is fine for small slices (a single channel × 30 days is 30 rows, well under Claude's context limit). Option 2: have Claude call the Airtable API itself using tool-use. Option 1 is what I'd ship in v1 — simpler, no MCP server, no auth dance. Option 2 is what you graduate to when the slices get larger than ~200 rows.
For Option 1, the Airtable automation that handles the slash command does the data fetch (one filter call to the relevant table), formats the rows as a markdown table, and appends them to the system prompt + user question before sending to Claude. Total latency: 2–4 seconds for the data fetch, 5–10 seconds for Claude. The whole round trip is under 15 seconds, which is fast enough that people actually use it.
By the end of hour 2 you should be able to paste any of the five exemplar questions into Claude with mock data and get back valid JSON in the right shape. If you can do that, the prompt is shippable.
Hour 3: The Slack command and the chart
The last hour is the smallest in code but the largest in user-experience payoff. A button the team can press is worth ten dashboards they have to remember to open.
The Slack slash command. In your Slack workspace, create a custom slash command /analyst pointed at an Airtable automation webhook. The body of the slash command is the question text. The automation receives it and:
- Parses the question to guess which table is needed (keyword match: "CAC" → CRM + Spend, "open rate" → Email, "sessions" or "traffic" → GA4). For ambiguous questions, default to a "summary" call that returns last 30 days across all four tables.
- Pulls the relevant rows from Airtable.
- Builds the prompt: system prompt + data table + user question.
- Calls the Claude API (Anthropic's
messages.createendpoint, modelclaude-sonnet-4-5). - Parses the JSON response.
- Renders the chart. For a bar chart, a quick way to ship is QuickChart.io's image API — you pass a Chart.js config as a URL, get back a PNG. For numbers, just post the
answer_shorttext. For line charts, same QuickChart pattern. - Posts the image + the one-sentence takeaway back to the channel with a
respondSlack step.
The response shape. Every answer is a Slack message with three parts: a one-sentence answer, a chart image, and a footer with the data freshness timestamp (e.g. "Data through 2025-10-12, refreshed 06:00 UTC"). The timestamp is non-negotiable — it is the only way the team can tell at a glance whether they're looking at yesterday's numbers or last Tuesday's. Without it, every answer gets the "is this current?" follow-up and the value of the tool halves.
The chat shortcut pattern. Most teams don't actually want to type /analyst every time. The pattern that gets adopted fastest is to add a Slack Workflow that triggers on the phrase "@analyst" in any channel. The bot reads the message after the mention, treats it as a question, and posts the answer in-thread. This is what my client used to ship the e-commerce version. The slash command is the fallback for explicit asks; the @ mention is the daily-driver interface. Build both — total time is 20 extra minutes.
By the end of hour 3 you should be able to type /analyst what's our blended CAC by channel this month into a test channel and get a bar chart back in under 15 seconds. If that works, the build is done.
The four gotchas
These are the four things that will eat your weekend if you don't plan for them.
Gotcha 1: Channel naming drift. The day Meta rebrands "Facebook" to "Meta" in their reporting API, your spend table says Meta and your CRM still says Facebook, and Claude's joined table silently drops half the data. The fix is a Channel mapping table — one row per logical channel with the names as they appear in each source. Spend 20 minutes normalizing the names at ingestion, never again. Audit quarterly.
Gotcha 2: Currency mixing. This is a European e-commerce team's favorite bug. Spend table is in EUR, CRM revenue is in USD, and the blended CAC is the wrong currency. Either: (a) convert at the daily FX rate at ingestion, or (b) have a Currency field in every numeric column and force Claude to convert before computing. Option (a) is cleaner. Do it at ingestion, not in the prompt.
Gotcha 3: The "off-topic" hallucination. The first time a teammate types /analyst what's the weather in London, Claude will answer it. Your team will lose trust. The fix is two lines in the system prompt: "If the question is not about the data in these four tables, return {"answer_short": "I can only answer questions about marketing data"}." Test it explicitly. Add an example for the refusal pattern in the exemplar block.
Gotcha 4: Context window on big questions. The day someone types /analyst compare every channel's weekly ROAS for the last 12 months, you'll hit a context limit. The fix is to pre-aggregate in Airtable: create a Weekly_Channel_Summary table that rolls up the daily data. Claude queries the summary table for "long" windows and the daily tables for "short" windows. The Airtable script picks the right table based on the time delta in the question. This is a 30-minute addition, but do it before the question is asked in a board meeting.
The single most useful thing this gives you
The point of the no-code analyst is not the chart. The chart is the easy part. The point is that the team's relationship to data changes. When the time-to-answer for "what's our CAC by channel" goes from 20 minutes (find the dashboard, find the right tab, filter, screenshot) to 11 seconds, the questions change. People start asking better questions, because the cost of asking is zero.
The other thing that changes is who asks. A no-code analyst has no opinion about the user's job title. The CEO, the intern, the customer success lead, the finance partner — they all get the same answer in 11 seconds. The bottleneck on data access in most small marketing teams is not data; it is the analyst's calendar. This system puts a thin layer of analyst in the channel.
A 4-figure BI tool gives you the same answer in 14 weeks. A 3-hour build gives you 80% of the value on a Monday. Build the 80%. The other 20% you'll know what shape it should take after you've actually used the thing for a month.