Build Your Own Ads Reporting Dashboards
A step-by-step walkthrough for recreating two things: a live account health dashboard and a weekly written performance report for a Google Ads account — built entirely by describing what you want, in plain English, to Claude Code. No coding experience required.
What you need
Five things, all free or already something you likely have:
- A Claude account with Claude Code access — a Claude Pro, Max, Team, or Enterprise plan, or API access via the Anthropic Console.Check at claude.ai — Claude Code is the version that can read/write files and run commands on your computer, not the regular chat.
- A computer you can install software on — Mac or Windows both work. This guide's terminal commands lean Mac/VS Code-flavored; Claude Code will adapt them for Windows if that's what you're on — just tell it your OS.
- Admin access to a Google Ads Manager (MCC) account — the account that has your client accounts linked underneath it.If you only manage a single account with no MCC, that's fine too — the API access steps are the same.
- A free Cloudflare account — only needed if you want a shareable web link. Sign up at dash.cloudflare.com. Skip this if you're happy just opening the report as a local file on your own computer.
- Patience for one slow step — Google's "Basic" developer token access requires a short review.Apply for it as your very first action so it's approved by the time you need it.
Install the tools
Four installs, about fifteen minutes total.
python3 --version — if nothing prints, run
xcode-select --install and follow the prompts, which installs Python along with it.Get Google Ads API access
This is the fiddliest part, and it's a one-time setup. You're collecting five pieces of information.
I need to generate a Google Ads API refresh token. I have a Client ID and Client Secret from Google Cloud Console. Can you write and run a small Python script using the google-auth-oauthlib library that opens my browser, has me sign in and approve access with scope https://www.googleapis.com/auth/adwords, and prints out the refresh token?
123-456-7890..apps.googleusercontent.com1//Set up your project folder
Ads Dashboards..env in that folder, and fill it in
with the five values you collected above:| Key | Example |
|---|---|
| GOOGLE_ADS_DEVELOPER_TOKEN | AbCdEfGh12345... |
| GOOGLE_ADS_CLIENT_ID | 123-abc.apps.googleusercontent.com |
| GOOGLE_ADS_CLIENT_SECRET | GOCSPX-... |
| GOOGLE_ADS_REFRESH_TOKEN | 1//0g... |
| GOOGLE_ADS_LOGIN_CUSTOMER_ID | 1234567890 |
.gitignore file containing just .env on its own line.
Everything from here on is a conversation. Open the Claude Code panel in VS Code, and work through these prompts roughly in order — copy one in, let Claude do the work, look at the result, then move to the next. Claude will often ask you clarifying questions first; just answer honestly about your own setup. Nothing below is a rigid script — feel free to phrase things your own way.
Confirm access
Get a working connection before building anything on top of it.
I have Google Ads API credentials in a .env file in this project (developer token, client id, client secret, refresh token, and login customer id for my manager account). Using the "google-ads" and "python-dotenv" Python libraries, write a script that connects and lists every client account under my manager account, so I can confirm access is working. Then run it.
If it works, you'll see a list of account names and ID numbers print out. If it fails, Claude will
usually be able to tell you exactly which credential is wrong — most often it's the Basic access
approval still pending, or a typo in the .env file.
Build the audit script
This is the core data-pulling script everything else builds on.
Now build a script that pulls a 30-day performance snapshot for one client account: campaign list with status, budget, spend, clicks, conversions, search impression share, top search terms with real spend but zero conversions, ad strength distribution, active conversion actions, and shared negative keyword lists. I only want campaigns named starting with "YOUR-PREFIX" included in every number — everything else should be excluded entirely, not just hidden.
Replace YOUR-PREFIX with whatever naming
convention your campaigns actually follow — e.g. your agency's initials, or leave this rule out
entirely if you don't need it.
Turn it into a website
I want to see this as a website instead of raw data. Build a single self-contained HTML dashboard: summary stats at the top, a bar chart of accounts by spend, and a searchable, sortable table where each account expands to show its campaigns, wasted search terms, and any account hygiene issues.
Claude will generate an HTML file you can open directly in your browser by double-clicking it — no server needed yet.
Run it across every account
Can you run this across every client account under my manager account instead of just one, and combine the results into a single report?
Apply your business rules
Refine what counts as "real" data for your reporting.
A few rules to apply everywhere: (1) leave out any account you don't actually have API access to, (2) leave out any campaign not named with our "YOUR-PREFIX" convention, (3) leave out any campaign that's paused with zero spend, clicks, impressions, and conversions in the last 30 days. Apply all three to every number in the report, not just what's displayed.
KPI health colors
The most useful single feature: an at-a-glance red / yellow / green per account.
For each of our services we have a target cost-per-conversion: Service A $65, Service B $45, Service C $25 (replace with your real services and targets). Detect which service a campaign or ad group belongs to from its name. Mark each account green if every campaign is hitting its target, yellow if some are and some aren't, red if none are or it looks like a billing/serving problem. Let me hover over the color to see exactly why it was scored that way.
Expect some back-and-forth tuning this one — the first version is rarely exactly right. It's normal (and encouraged) to look at the result and say things like "this account should really be green, why isn't it?" — Claude can walk through the exact math with you and adjust the rule.
Style it
I'd like the design to be light with pastel colors, and forced to always render in light mode regardless of the viewer's system theme — some of the current text is hard to read.
Say exactly what's bothering you — "the yellow looks brown," "I can't read this text," "make the font bigger" — plain feedback like this works better than trying to specify hex codes yourself.
Schedule it automatically
I want this to run automatically every Monday at 8am, my local timezone. This is a Mac / Windows — what's the best way to schedule it without needing a separate cloud service?
On a Mac, Claude will typically set up a LaunchAgent; on Windows, Task Scheduler. Either way, your computer needs to be on and awake at that time for it to run — by default, it won't retroactively catch up if your laptop was asleep or off. See Troubleshooting below for a permissions issue that's very likely to come up here.
Worth fixing right away, since it will happen eventually: a missed run silently waits a full week otherwise.
My scheduled job didn't run this week — I think my computer was off at the scheduled time. Can you make this self-healing: run a check every time I log in or start my computer, and if this week's report hasn't been generated yet, run it then instead of waiting for next week's scheduled time?
Claude will typically add a "run on every login" trigger alongside the existing weekly schedule, plus a guard that checks whether this week's report already exists before doing any real work — so it costs nothing extra on a normal week, and quietly catches up on a missed one.
Host it online & share a link
I want to send this dashboard to other people as a link instead of a file. What are my options, including whether it can be access-controlled rather than fully public?
Claude will lay out the trade-off directly: a fully public link (simplest, but genuinely public forever to anyone who gets it) versus an access-controlled one (adds a login wall so only specific emails can view it, more setup). Decide based on how sensitive the data is, then follow up:
Let's go with [the option you picked]. I have a free Cloudflare account already — the login is your-email@example.com.
Claude will use Cloudflare's wrangler command-line tool, which opens a browser tab for
you to approve the connection to your Cloudflare account once.
The weekly narrative report
A second, plain-English companion to the dashboard.
On top of the dashboard, I also want a written weekly report per account, broken down by service: a GOOD / BAD / PLANS paragraph comparing this week against last week and against the last 30 days, plus a portfolio summary of top performers, accounts needing attention, and the biggest week-over-week movers. Generate this every time the dashboard regenerates.
Refine it as you go
The first version of any rule is rarely exactly right once you see real data against it. Some examples of the kind of plain-English feedback that works well here:
If an account is generating more than 50 leads a week, don't include it in "accounts needing attention" even if a service or two is technically off-target — strong volume like that doesn't need to be flagged.
In the "biggest weekly improvements" section, don't count it as a real win if the lead count stayed exactly the same as last week and the account is still failing its target — cost per lead ticking down on the same one or two leads isn't a meaningful trend, just noise.
Both of these came from actually reading a week's report and noticing something that looked technically-correct-but-wrong — that's the normal way this gets tuned, not something you need to anticipate up front.
Two more polish prompts worth asking for once the report itself is solid:
This report is getting long. Can you add collapsible "Show more" sections — keep the portfolio summary expanded by default since that's the quick-glance part, but collapse each individual account's detail by default so the page reads as a short list of names I can click into.
Can you add our logo to the top of the report, and a small label making clear this report only covers Google Ads — we run other marketing too and I don't want it read as our whole performance picture.
Also worth doing at this point, if you haven't already: any timestamp the report shows (like "Generated ...") should render in whoever's looking at it local time, not the timezone of the computer that generated it. Ask for that explicitly if you're sharing the report with anyone outside your own timezone.
Client-facing reports
Everything so far is built for you, the person managing the accounts — full of terms like CPA, impression share, and Quality Score. Clients mostly just want to know: how many leads did I get, and what did they cost. This phase builds a second, separate, jargon-free page per client.
I want a separate public webpage for each client, built from the same underlying data as the reports above, but reworded so someone with no Google Ads knowledge understands it instantly. Show: the current week's date, leads/cost-per-lead/spend per service for this week AND the last 30 days (so one bad week doesn't look like a crisis), a plain-English "status this week" line, and "what we're doing about it" if something needs attention. Don't use any Google Ads terminology anywhere — no CPA, no keywords, no impression share, no ad groups. Let's start with one client so we can get the tone right before rolling it out to everyone.
Expect to go back and forth on wording — this is the one place where "does a non-marketer actually understand this sentence" matters more than precision. A few refinements worth asking for once the first draft is up:
Add our booking link so clients can schedule a call directly: https://your-booking-link.example.com. Also give a realistic timeframe for when they should expect to see numbers improve if we're actively working on something — not a guaranteed promise, but an honest "check back around this date."
Switch to a lighter, pastel color palette, and make wins vs. needs-improvement easy to tell apart at a glance — a labeled badge, not just a subtle color dot. Add our real logo and use it as the basis for the color palette rather than colors we picked arbitrarily.
Once the tone is right on that first client, ask Claude to roll the same template out to every client account, and to add it to the same weekly automation from Phase 8 so it regenerates alongside everything else — no separate schedule to maintain.
Budget scale-up recommendations
A single week's snapshot can make a campaign look like a good scale-up candidate when it's really just a lucky week. This phase looks back further to find a real, sustained pattern instead.
Add a deep dive that looks at the last 3 months, broken down week by week, to find campaigns worth scaling the budget on. A campaign qualifies if it's been losing a meaningful share of its impressions to budget constraints (not ad quality or bid issues — specifically budget) while still hitting its cost-per-lead target, in most of those weeks — not just one good week. For each one, tell me: how much to increase the budget by, how long to run it before reassessing, and the reasoning. Skip anything currently paused.
The concept doing the real work here is a metric Google Ads itself tracks: the percentage of impressions a campaign missed specifically because its budget ran out (as opposed to losing them on bid/quality grounds — that's a separate number). Ask Claude to explain exactly which metric it used and how it weighted multiple weeks together if you want to understand the mechanics — it's a genuine Google-computed figure, not something derived or guessed.
Reasonable follow-up refinements once you see the first output:
Make sure this excludes campaigns that got paused for reasons unrelated to performance — like a client cancelling — even if their historical numbers would otherwise qualify.
Add this to the same weekly automation as everything else once you're happy with it, so it's a living recommendation list rather than a one-time analysis.
Extra signals worth asking for
Smaller, standalone additions — ask for any that are useful to you, in any order.
Also flag keywords (not just search terms) that spent money but got zero conversions in the last 30 days.
Flag any change made to an account by someone other than me in the last 30 days — I'm your-email@example.com. Show me who, what changed, and when, on hover.
Pull audience segment performance (in-market, affinity, remarketing lists) for accounts where that data exists, even though most of ours are Search-only campaigns.
For a specific account I want to look into more closely, write a hand-authored deep dive — root cause of what's going on, what's already changing, and the plan from here — and show it alongside that account's entry in the weekly report.
Troubleshooting
Four issues that came up building this the first time — all fixable, none of them your fault.
bash here won't
work — it's a protected system file macOS silently ignores.
Making it yours
Before you call it done, make sure these reflect your agency, not a template:
- Campaign naming convention — whatever prefix or pattern you used in Phase 2/5.
- Target CPA per service — your real numbers from Phase 6, not placeholders.
- Account owner email — used in Phase 14's "changes not made by you" check.
- Schedule day, time, and timezone — from Phase 8.
- Sharing model — public link, access-controlled, or manual snapshot — from Phase 9.
- "Needs attention" volume exemption and "real win" threshold — the numbers you picked in Phase 11, not generic defaults.
- Client report wording, booking link, and logo — verified against each client's real site, from Phase 12.
- Budget scale-up thresholds — the impression-share and lookback-window numbers you settled on in Phase 13.
None of this has to be perfect on the first pass. The whole point of building it this way is that "this looks wrong, can you fix it" is a completely normal, expected part of the process — every phase above was refined at least once in exactly that way.