Blog · Report Templates

Marketing report templates you can pin as live dashboards

Published July 17, 2026 · 8 min read

Searching for a marketing report template usually gets you a nicely designed document with empty charts — and the layout was never your problem. The problem is the refill: every week or month, someone pipes fresh numbers into the old frame, checks the totals, fixes the chart that broke, and ships a file that's stale on arrival. This page takes a different approach. Below are three marketing report templates defined not as documents but as widget lists — a title plus a SQL query per widget — that you pin once with a single command. Each becomes a live dashboard URL that refreshes itself. The template stops being a chore you repeat and becomes a report that maintains itself.

The template was never the work — the refill is

Be honest about where reporting time actually goes. Picking a layout happens once. What repeats, forever, is:

  • Exporting this period's numbers from every platform, in every platform's own format.
  • Pasting them into the template's spreadsheet or slides and repairing whatever shifted.
  • Re-checking definitions — was ROAS computed off the same conversion value column as last month?
  • Re-sending the file, and answering "which version is current?" three days later.

A document template can't fix any of that, because a document is a snapshot by nature. The fix is to change what the template is.

A marketing report template is just titles + SQL

On TableBI — a data backend built to be driven by an AI agent like Claude Code (Anthropic's terminal-based coding agent) — a report template is literally a list of widgets. Each widget is "Title=SQL" for a table, or "Title::line=SQL" for a line chart. One tablebi pin command publishes the list as a dashboard with a public, read-only URL that re-pulls from your connected sources automatically — on access and on a schedule. Definitions come from shared macros (roas(), ctr(), cpa()…), so the arithmetic is identical in every report, every period, no matter who pins it.

Setup, if you haven't already:

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

# connect whichever sources the template needs (OAuth in browser)
tablebi connect gsc --site sc-domain:example.com
tablebi connect ga4
tablebi connect meta_ads
tablebi connect google_ads

Meta Ads is in beta. The Meta app hasn't cleared App Review yet, so today only people added to it as test users can authorize their ad accounts. Everything else on this page is live.

Now the three templates. Each is a complete command — copy, paste, done. Your agent can also adapt any of them from a plain-English request ("add a country breakdown"), which is the intended workflow.

Template 1: weekly marketing overview

When to use it: the standing Monday view — is anything up, down or on fire across all channels. Who it's for: you, your team standup, or a founder who wants one link instead of four platform logins.

terminal — copy & pin
tablebi pin --title "Weekly marketing overview" \
  --widget "Clicks by day (28d)::line=SELECT date, SUM(clicks) AS clicks FROM facts WHERE date >= (SELECT MAX(date) FROM facts) - 28 GROUP BY date ORDER BY date" \
  --widget "Spend by platform (28d)=SELECT platform, SUM(cost) AS spend FROM facts WHERE date >= (SELECT MAX(date) FROM facts) - 28 GROUP BY platform ORDER BY spend DESC" \
  --widget "Top campaigns by spend (28d)=SELECT platform, campaign, SUM(cost) AS spend, SUM(conversions) AS conversions FROM facts WHERE date >= (SELECT MAX(date) FROM facts) - 28 GROUP BY platform, campaign ORDER BY spend DESC LIMIT 10"
✓ published → https://<your-ws>.tablebi.com/d/dsh_…  (public, read-only, self-refreshing)

Note the date idiom used throughout: date >= (SELECT MAX(date) FROM facts) - 28 anchors the window on the freshest data actually present, not today's calendar date — so a platform reporting a day behind never punches a fake dip into your charts.

Template 2: SEO monthly report

When to use it: the monthly organic check-in — search trend and which pages carry it. Who it's for: whoever owns content and SEO, or a client who asks "is the blog working?"

This one runs on the Search Console tables rather than the cross-channel layer, because page-level detail is platform-specific. The daily trend reads search_console_totals_raw (the same totals as the Search Console overview) and the page list reads search_console_pages_raw; neither is summed from the per-query table, which leaves out every query Google anonymises:

terminal — copy & pin
tablebi pin --title "SEO monthly report" \
  --widget "Impressions by day (28d)::line=SELECT date, SUM(impressions) AS impressions FROM search_console_totals_raw WHERE search_type = 'web' AND date >= (SELECT MAX(date) FROM search_console_totals_raw) - 28 GROUP BY date ORDER BY date" \
  --widget "Clicks by day (28d)::line=SELECT date, SUM(clicks) AS clicks FROM search_console_totals_raw WHERE search_type = 'web' AND date >= (SELECT MAX(date) FROM search_console_totals_raw) - 28 GROUP BY date ORDER BY date" \
  --widget "Top pages by clicks (28d)=SELECT page, SUM(clicks) AS clicks, SUM(impressions) AS impressions FROM search_console_pages_raw WHERE date >= (SELECT MAX(date) FROM search_console_pages_raw) - 28 GROUP BY page ORDER BY clicks DESC LIMIT 15"
✓ published → https://<your-ws>.tablebi.com/d/dsh_…

Every pinned dashboard also carries the trust context the queries ran with — source freshness and caveats — which matters here because Search Console's numbers arrive on a platform-specific lag, and a report that silently pretends otherwise invites the wrong conclusions.

Template 3: paid efficiency review

When to use it: weekly or before any budget conversation — where paid money works, where it doesn't, and what's burning with nothing to show. Who it's for: the person who moves budgets, and anyone who has to defend the ad spend line.

terminal — copy & pin
tablebi pin --title "Paid efficiency review" \
  --widget "ROAS by platform (28d)=SELECT platform, SUM(cost) AS spend, roas(SUM(conversion_value), SUM(cost)) AS roas FROM facts WHERE cost > 0 AND date >= (SELECT MAX(date) FROM facts) - 28 GROUP BY platform ORDER BY spend DESC" \
  --widget "CPA by campaign (28d)=SELECT platform, campaign, SUM(cost) AS spend, cpa(SUM(cost), SUM(conversions)) AS cpa FROM facts WHERE cost > 0 AND date >= (SELECT MAX(date) FROM facts) - 28 GROUP BY platform, campaign ORDER BY spend DESC LIMIT 15" \
  --widget "Spending, zero conversions (14d)=SELECT platform, campaign, SUM(cost) AS spend FROM facts WHERE date >= (SELECT MAX(date) FROM facts) - 14 GROUP BY platform, campaign HAVING SUM(cost) > 0 AND SUM(conversions) = 0 ORDER BY spend DESC"
✓ published → https://<your-ws>.tablebi.com/d/dsh_…

The third widget is the one that pays rent: ad sets and campaigns that spent in the last two weeks and converted nothing, ranked by damage. Because the facts layer normalizes Meta, Google and CSV-imported channels into the same columns, this list is cross-platform for free — Meta's purchase value and Google's conversion value are both just conversion_value here.

What a pinned template looks like

Templates on a page are hypothetical. Here is a live dashboard on real data you can open now: Search Console totals across the TableBI founder's own sites. It is a different dashboard from the one described above, published the same way, and it re-runs its queries as the sources sync (what the demo shows, and what it doesn't):

When a document template is still the right call

Some deliverables genuinely need to be documents — a board pack with commentary, a quarterly review your client's procurement files away, anything contractually required as a PDF. These templates don't produce that, and dashboards here carry a "Powered by TableBI" footer rather than your branding. What they replace is the recurring operational report — the one whose only job is to be current — and for that, a link that refreshes itself beats a file that doesn't, every week from now on.

If the report is for a client, the client reporting guide shows the one-workspace-per-client delivery pattern around these same templates. For more on how pinning and refresh behave under the hood, see Claude Code dashboards; for the full workflow these templates slot into — connect, ask, pin, repeat — start with Claude Code for marketing.

FAQ

How do these report templates stay up to date?

You pin a template once and it becomes a live dashboard URL. The dashboard re-pulls from your connected sources automatically — when someone opens the link and on a schedule — so there is no weekly refill step at all.

Can I customize a template?

Yes — a template is just a list of widgets, each a title plus a SQL query. Add, remove or edit widgets by changing the SQL. The facts table exposes date, platform, account and campaign for every connected source (the live connectors sync at campaign level), so most customizations are a one-line change your agent can make.

What do I need before I can pin one of these?

Install the CLI (npm i -g @tablebi/cli, then tablebi login and tablebi install) and connect at least one source. Search Console, GA4, Meta Ads and Google Ads connect via OAuth; anything else comes in as CSV. Then paste the pin command.

Do the paid templates work for channels beyond Meta and Google?

Yes. Any channel you import as CSV with a platform tag — TikTok Ads exports, for example — is normalized into the same facts definitions, so it shows up in the platform breakdowns and efficiency widgets automatically.

Try it

Give your Claude Code a data backend in five minutes.

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