Blog · Marketing × Dashboards

Marketing dashboard: one live URL for every channel, no BI seat required

Published July 17, 2026 · 7 min read

A marketing dashboard fails in exactly two ways: the numbers stop being true, or they stop being fresh. Either the channel metrics were stitched together from exports with definitions that quietly disagree — Meta's purchase value charted next to Google's conversion value as if they were the same number — or the dashboard was accurate on launch day and then nobody maintained it. This guide walks through a marketing dashboard built the other way around: every channel piped into one unified metrics layer, an AI agent writing the SQL and owning the upkeep, and the output published as a single live URL you can hand to a boss or a client — read-only, self-refreshing, with no BI seat attached to it.

The two ways a marketing dashboard fails

Failure one: stitched definitions. Every ad platform reports generously about itself. "Conversions" on one platform is not "conversions" on another; attribution windows differ; value fields carry different names and different meanings. Most multi-channel dashboards are assembled by pasting each platform's export into adjacent columns — which produces something that looks comparable and isn't. The dashboard is precise, confident, and wrong, and you find out in the meeting where two channel owners bring numbers that can't both be true.

Failure two: built, then abandoned. Dashboards get built in an enthusiastic sprint — by an analyst, an agency, or you on a rainy Saturday — and then maintenance lands on nobody. The builder moves on; a "quick change" takes three weeks because nobody remembers how the pipeline works; someone starts exporting CSVs again just to be sure. Rot doesn't announce itself. The dashboard just gets quietly wrong, then quietly ignored.

Both failures are structural, which is why cosmetic fixes — a new template, a prettier charting tool — never touch them. You need a unified definition layer to fix the first, and a maintainer with infinite patience to fix the second.

Fix the truth problem: one metrics layer for every channel

TableBI is a hosted data backend with a CLI, built around three verbs: pipe sources in, ask with read-only SQL, pin the result to a live URL. It describes itself as "the data backend for your Claude Code" — Claude Code being Anthropic's terminal-based coding agent — and the part doing the heavy lifting for a marketing dashboard is the definition layer. Everything you pipe in lands at two altitudes:

  • facts — one cross-channel table with unified definitions. Meta's purchase value and Google Ads' conversion value both land as conversion_value; spend from every platform is cost. The dimensions are consistent — date, platform, account, campaign, ad_group, ad, channel, country — and so are the measures: clicks, impressions, cost, conversions, conversion_value.
  • <platform>_raw — the lossless per-platform tables underneath, for when you need exactly what one platform reported, in its own vocabulary.

On top of facts sit definition macros — roas, ctr, cpc, cpm, cpa, cvr — so ratio arithmetic is defined once in the backend instead of re-derived, slightly differently, in every chart. And every answer ships with a trust block: per-source freshness plus caveats like "GSC clicks ≠ GA4 sessions" — the cross-channel comparisons that look tempting but don't reconcile, flagged before anyone builds a slide on them.

That's the fix for failure one. Not more careful copy-pasting — one place where "conversion value" means one thing.

Fix the rot problem: let an agent do the maintenance

The fix for failure two is changing who does the chores. TableBI has no dashboard editor to learn, because the intended operator is an AI agent — Claude Code, or any agent that can drive a CLI. The division of labor is clean: the backend stores, syncs and serves trusted numbers; the agent writes the SQL, reads the trust block, and rebuilds the dashboard whenever you ask.

"Maintenance" stops being a ticket queue. "Break CPA out by country" or "add TikTok next to Meta" is one sentence typed into your terminal; the agent edits the SQL and re-pins the dashboard. Nobody has to remember how the pipeline works, because the pipeline is a CLI the agent already knows how to drive.

One economic detail worth naming: TableBI hosts no LLM, so inference cost is $0. Your own agent is the brain, under your own API key; the backend's whole job is to be the deterministic SQL engine underneath it.

Build it: four channels, one OAuth each

Install the CLI and plant the skill so the agent knows the tool exists and when to reach for it:

terminal
npm i -g @tablebi/cli && tablebi install

Then connect your channels. Each live source is one OAuth round-trip in the browser:

terminal
tablebi connect gsc --site sc-domain:example.com
tablebi connect ga4
tablebi connect meta_ads
tablebi connect google_ads

Channels without a live connector come in as CSV and are normalized into the same definitions:

terminal
tablebi connect csv --file f.csv --platform tiktok_ads

From then on, an agent session opens with tablebi context --json — connected sources, data freshness and the command cheatsheet in one JSON blob it can hold in context for the rest of the conversation.

Three widgets that cover the Monday questions

A marketing dashboard doesn't need twenty tiles. Three queries against facts answer "what did we spend, what did it return, and where is it going wrong." First, daily spend across all channels, as a line — the pulse of the account:

claude code → tablebi
tablebi ask "SELECT date, SUM(cost) AS spend
             FROM facts
             WHERE date >= (SELECT MAX(date) FROM facts) - 28
             GROUP BY date ORDER BY date"

Note the window: anchored to MAX(date), not current_date, so platforms that report on a lag don't leave a fake dip at the end of the chart. Second, ROAS by platform — legitimate at last, because both value fields were normalized into conversion_value before the comparison:

claude code → tablebi
tablebi ask "SELECT platform, SUM(cost) AS spend,
             SUM(conversion_value) AS revenue,
             roas(SUM(conversion_value), SUM(cost)) AS roas
             FROM facts
             WHERE date >= (SELECT MAX(date) FROM facts) - 28
             GROUP BY platform ORDER BY spend DESC"

Third, CPA by campaign — where the money actually goes wrong. Big spenders with a cost per conversion that doesn't justify the budget float straight to the top:

claude code → tablebi
tablebi ask "SELECT platform, campaign, SUM(cost) AS spend,
             SUM(conversions) AS conversions,
             cpa(SUM(cost), SUM(conversions)) AS cpa
             FROM facts
             WHERE date >= (SELECT MAX(date) FROM facts) - 28
             GROUP BY platform, campaign ORDER BY spend DESC LIMIT 15"

You can type these yourself or just describe them — the agent writes SQL happily. Either way the queries are read-only and stay visible, which is what makes every number on the dashboard auditable instead of taken on faith.

Pin it: the link you send your boss

When the three queries look right, publish them as one dashboard. ::line renders a widget as a line chart; the default is a table:

claude code → tablebi
tablebi pin --title "Cross-channel overview" \
  --widget "Daily spend (28d)::line=SELECT date, SUM(cost) AS spend FROM facts …" \
  --widget "ROAS by platform=SELECT platform, … FROM facts …" \
  --widget "CPA by campaign=SELECT platform, campaign, … FROM facts …"
✓ published → https://<ws>.tablebi.com/d/dsh_…  (public, read-only, self-refreshing)

The URL that comes back has specific semantics, and they're the whole point:

  • Read-only. Your boss or client can look, not break. There's no edit mode to wander into.
  • Self-refreshing. Syncs are triggered by visits and run on a schedule, so the link is as alive in week thirty as in week one. No Monday screenshot ritual.
  • No seat. Viewers don't log in, don't get provisioned, don't need a license. Forward the link and you're done.
  • A feedback channel. Next to each widget sits an ask button: a viewer can copy a one-sentence question — "why did CPA jump in March?" — and send it back to the dashboard owner, instead of booking a meeting to ask it.

Dashboards carry a "Powered by TableBI" footer, and that's the extent of the chrome. Here's a live example of the mechanics — this one is pinned from real Search Console data (a search portfolio rather than paid channels, but the widget, refresh and ask semantics are exactly what you'd get):

When a traditional BI platform is the better call

Honest answer: sometimes it is. If your situation is thirty stakeholders who each want to drag-and-drop their own views, row-level permission governance, and an admin who provisions access by role, buy a traditional BI platform — that's exactly what the category is built for, and this approach won't replace it.

This approach earns its keep in the other shape of team: a solo operator or a small crew, already working alongside an agent, that needs every channel's truth behind one URL rather than a BI rollout. The differences are architectural, not cosmetic: agent-driven instead of GUI-driven, a live public URL instead of seat-gated workspaces, SQL as the single source of truth instead of a proprietary modeling layer, and pricing that isn't per seat — because the heaviest user of the system is an agent, not a row of licensed humans.

For the broader agent workflow — ad-hoc questions, weekly summaries, the analysis behind the dashboard — see Claude Code for marketing. If Meta is your dominant channel, Meta Ads reporting goes deeper on that connector. And if the person opening your dashboard is a paying client rather than your own team, the client reporting guide covers that relationship end to end.

FAQ

What should a marketing dashboard include?

Less than you think: daily spend across channels, ROAS by platform, and CPA by campaign — computed from one unified definition layer so channels are actually comparable. Add breakdowns like country, channel or ad group when a real question demands them, not before.

How do I keep a marketing dashboard up to date automatically?

Two mechanisms: connected sources sync on their own, and a pinned dashboard refreshes as it's visited and on a schedule. Changes are one sentence to your agent — it edits the SQL and re-pins — so the dashboard never rots for lack of a maintainer.

Can I share the dashboard with a client or boss without giving them a login?

Yes. A pinned dashboard is a public, read-only, self-refreshing URL — no account, no seat, no invite flow. Each widget has an "ask" button so a viewer can copy a one-sentence question to send back to the dashboard owner.

When should I use a traditional BI tool instead?

When many stakeholders need drag-and-drop self-serve analysis and you need permission governance at organizational scale — that's what traditional BI platforms are built for. For solo operators and small teams working alongside an agent, one live URL over a unified SQL layer is the lighter answer.

Try it

Give your Claude Code a data backend in five minutes.

terminal
npm i -g @tablebi/cli && tablebi install