Keep Google Ads spend on pace with your monthly budget

Every weekday: Google Ads spend month to date against your monthly budget, where the month lands at this rate, and the daily spend that lands it on budget.

Runs
Weekdays at 9:00
Posts
Stat tile

From your apps to your board

How the skill works: your agent reads total spend since the 1st from Google Ads; google ads customer id, monthly budget from What you tell it, weekdays at 9:00, and gives you projected month-end spend and the report in the chat.

Reads

  • Google AdsTotal spend since the 1st
  • What you tell itGoogle Ads customer ID, Monthly budget
reads
Your agentClaude Code, Codex, Cursor or GeminiWeekdays at 9:00
posts

You get

  • Projected month-end spendA stat tile on your board, with its trend
  • The report in the chatEvery run, with or without Briefkin

What you get

  • Projected month-end spend at the current rate, against the monthly budget.
  • Month to date: spend so far, what was expected by today, and pacing in percent.
  • The last 7 days' daily average, next to the daily spend that lands the month on budget.
  • By campaign: spend so far, daily budget and projected month end.
  • What to change, for example "Cut daily budgets by about 26% to land on $30,000".

The card on the right is a sample. Yours shows your own numbers and updates in place every run.

What lands on your board

AcmeProjected month-end spend$33,480+1% vs previous period, worsevs last report
Month to date$16,200 of $30,000
Expected by today$14,520
Last 7 days$1,170/day
Needed per day$863
An example with made-up numbers. Your agent posts your real ones.

What it does

Google Ads thinks in daily budgets; finance thinks in a monthly number. Overspend lives in the gap between them: Google may spend up to twice a daily budget on a busy day, budgets raised for a promotion are never lowered, and nobody adds it up until the invoice arrives.

The agent adds it up every weekday. It totals spend since the 1st, compares it with how much of the month has passed, projects the month end at the current rate and gives the daily figure that lands on budget. Marketing and finance end up looking at the same number.

How it works

  1. 1Total spend since the 1st

    Run GAQL on campaign for segments.date BETWEEN the first of the month and yesterday, selecting campaign.name, campaign.status, metrics.cost_micros and campaign_budget.amount_micros. Divide micros by 1,000,000.

  2. 2

    2Compare with the calendar

    Expected spend by now is the monthly budget times days elapsed over days in the month. Pacing is actual over expected; between 95% and 105% counts as on pace.

  3. 3

    3Project the month end

    The straight-line projection is spend so far divided by days elapsed, times days in the month. Report the last 7 days' daily average next to it, since a budget raised mid-month makes the straight line too low.

  4. 4

    4Work out the correction

    The daily spend that lands on budget is what remains of the budget divided by the days left. Set it against the sum of current daily budgets and say by how much to raise or cut them.

  5. 5

    5Post the tile

    Projected month-end spend is the number, with one point per weekday run as history. The glance shows month to date against budget as a progress bar, and the card opens to the campaign table.

  6. Post it to the board

    With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.

Install and run it

Pick your agent, where the data comes from and how to schedule it; the commands below follow.

Agent
Data
Schedule
  1. Install the skill

    One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.

    shellcurl -fsSL https://briefkin.dev/skills/google-ads-budget-pacing/install | sh
  2. Run it

    Ask Claude Code:

    promptRun the google-ads-budget-pacing skill

    Or paste the prompt instead of installing:

    promptCheck my Google Ads budget pacing with the Google Ads API. Sum metrics.cost_micros by campaign from the 1st of this month to yesterday (GAQL on campaign, with campaign_budget.amount_micros). My monthly budget is $[budget]. Tell me: spend so far, what I should have spent by now (budget times days elapsed over days in the month), pacing in percent, the straight-line projection for the month end, the last 7 days' average daily spend, and the total daily spend that would land the month exactly on budget, compared with the current daily budgets. Show each campaign's spend so far, daily budget and projection.
  3. Put it on a schedule

    Weekdays at 9:00, from cron on any machine where Claude Code is signed in:

    crontab0 9 * * 1-5 claude -p "Run the google-ads-budget-pacing skill"

    Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.

  4. Send it to your board

    Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a stat tile. How setup works

View the SKILL.mdRaw file
SKILL.md---
name: google-ads-budget-pacing
description: "Every weekday: Google Ads spend month to date against your monthly budget, where the month lands at this rate, and the daily spend that lands it on budget. Use when the user asks for this, or when it runs on a schedule."
---

# Google Ads budget pacing

Every weekday: Google Ads spend month to date against your monthly budget, where the month lands at this rate, and the daily spend that lands it on budget.

Google Ads thinks in daily budgets; finance thinks in a monthly number. Overspend lives in the gap between them: Google may spend up to twice a daily budget on a busy day, budgets raised for a promotion are never lowered, and nobody adds it up until the invoice arrives.

The agent adds it up every weekday. It totals spend since the 1st, compares it with how much of the month has passed, projects the month end at the current rate and gives the daily figure that lands on budget. Marketing and finance end up looking at the same number.

## Two ways to get the data

Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.

## Route A: API or MCP server

### What you need

- Read access to the Google Ads account and its customer ID; pacing never edits budgets.
- Google Ads API access through a Google Cloud project with API access and OAuth credentials (developer tokens were retired in September 2026), plus `login-customer-id` for a manager account; or the official Google Ads MCP server, which is read-only and enough here.
- The monthly budget, for the whole account or per group of campaigns.

If something is missing, say what and stop; do not invent numbers.

### Steps

1. **Total spend since the 1st** (Google Ads): Run GAQL on `campaign` for `segments.date BETWEEN` the first of the month and yesterday, selecting `campaign.name`, `campaign.status`, `metrics.cost_micros` and `campaign_budget.amount_micros`. Divide micros by 1,000,000.
2. **Compare with the calendar**: Expected spend by now is the monthly budget times days elapsed over days in the month. Pacing is actual over expected; between 95% and 105% counts as on pace.
3. **Project the month end**: The straight-line projection is spend so far divided by days elapsed, times days in the month. Report the last 7 days' daily average next to it, since a budget raised mid-month makes the straight line too low.
4. **Work out the correction**: The daily spend that lands on budget is what remains of the budget divided by the days left. Set it against the sum of current daily budgets and say by how much to raise or cut them.
5. **Post the tile**: Projected month-end spend is the number, with one point per weekday run as history. The glance shows month to date against budget as a progress bar, and the card opens to the campaign table.

## Route B: the browser

### What you need

- Signed in to Google Ads with at least Read-only access to the account; through a manager account, pick the client account first.

If something is missing, say what and stop; do not invent numbers.

### Steps

Start at https://ads.google.com/aw/campaigns. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.

1. **Open the Campaigns table for this month**: Open `https://ads.google.com/aw/campaigns`. If the account picker appears, choose the client account (a manager account lists them all). In the date picker at the top right choose `This month`.
2. **Read cost and daily budgets**: Make sure the `Cost` and `Budget` columns show (Columns, then Modify columns, under Performance and Attributes). Read the Total row for spend since the 1st, then each enabled campaign's cost and daily budget.
3. **Read the last 7 days**: Switch the date range to `Last 7 days` and read the Total cost again. Divided by 7 it gives the current daily rate, which is what a budget raised mid-month shows up in.
4. **Cross-check Billing**: Open Billing, then Summary, for the month-to-date charge; on an invoiced account, Account budgets shows the spending limit. Use the Campaigns total for the math, since billing figures run a day or so behind.
5. **Do the pacing math**: Expected spend is the monthly budget times days elapsed over days in the month; pacing is actual over expected, with 95% to 105% on pace. Project the month end at the straight-line rate and at the 7-day rate, and give the total daily budget that lands on the monthly number.

Note: Cost in the Campaigns table can lag a few hours and excludes invalid-click credits, so it differs slightly from Billing. The table is fine for a few dozen campaigns; past that, use Download above the table and total the file.

## The report

- **Projected month-end spend** at the current rate, against the monthly budget.
- **Month to date**: spend so far, what was expected by today, and pacing in percent.
- **The last 7 days' daily average**, next to the daily spend that lands the month on budget.
- **By campaign**: spend so far, daily budget and projected month end.
- What to change, for example "Cut daily budgets by about 26% to land on $30,000".

## Post it to Briefkin

When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.

```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
  -H "authorization: Bearer $BRIEFKIN_TOKEN" \
  -H "content-type: application/json" \
  -d @- <<'JSON'
{
  "v": 1,
  "event_id": "google-ads-budget-pacing/<date of this run, e.g. 2026-10-16>",
  "item_key": "google-ads-budget-pacing",
  "project": "Acme",
  "source": "Google Ads budget pacing skill",
  "kind": "metric",
  "title": "On pace to spend $33,480 of a $30,000 budget",
  "metric": {
    "label": "Projected month-end spend",
    "value": 33480,
    "prefix": "$",
    "better": "lower",
    "period_start": "<start of the period, ISO 8601>",
    "period_end": "<end of the period, ISO 8601>"
  },
  "glance": [
    {
      "type": "Progress",
      "props": {
        "label": "Month to date",
        "value": 54,
        "text": "$16,200 of $30,000",
        "tone": "warn"
      }
    },
    {
      "type": "Grid",
      "props": {
        "columns": 3
      },
      "children": [
        {
          "type": "Stat",
          "props": {
            "label": "Expected by today",
            "value": 14520,
            "prefix": "$"
          }
        },
        {
          "type": "Stat",
          "props": {
            "label": "Last 7 days",
            "value": 1170,
            "prefix": "$",
            "unit": "/day"
          }
        },
        {
          "type": "Stat",
          "props": {
            "label": "Needed per day",
            "value": 863,
            "prefix": "$"
          }
        }
      ]
    }
  ],
  "widget": [
    {
      "type": "Table",
      "props": {
        "columns": [
          "Campaign",
          "Month to date",
          "Daily budget",
          "Projected"
        ],
        "align": [
          "left",
          "right",
          "right",
          "right"
        ],
        "rows": [
          [
            "Non-brand Search",
            "$7,800",
            "$560",
            "$16,120"
          ],
          [
            "Performance Max",
            "$4,600",
            "$330",
            "$9,510"
          ],
          [
            "Brand Search",
            "$2,100",
            "$150",
            "$4,340"
          ],
          [
            "Display Remarketing",
            "$1,700",
            "$130",
            "$3,510"
          ],
          [
            "Total",
            "$16,200",
            "$1,170",
            "$33,480"
          ]
        ]
      }
    },
    {
      "type": "Callout",
      "props": {
        "text": "Pacing at 112% with 16 days left, and at the last 7 days' rate the month lands nearer $34,880. Daily budgets of about $863 in total, 26% below today's, land it on $30,000.",
        "tone": "warn"
      }
    }
  ],
  "size": "md"
}
JSON
```

Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.

Set `period_start` and `period_end` to the window the number covers: the tile names it from them ("Last 7 days", "Today", "This month"). For a count right now (open items, a balance), send `"period_label": ""` so no period shows; for another name, send it as `period_label` (at most 24 characters).

## Run it on a schedule

Suggested: Weekdays at 9:00 (`0 9 * * 1-5`). From cron, with the agent signed in on that machine:

```bash
0 9 * * 1-5 claude -p "Run the google-ads-budget-pacing skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```

Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/google-ads-budget-pacing#schedule

Source: https://briefkin.dev/skills/google-ads-budget-pacing

What your agent needs

  • Read access to the Google Ads account and its customer ID; pacing never edits budgets.

  • Google Ads API access through a Google Cloud project with API access and OAuth credentials (developer tokens were retired in September 2026), plus login-customer-id for a manager account; or the official Google Ads MCP server, which is read-only and enough here.

  • The monthly budget, for the whole account or per group of campaigns.

Connecting Google Ads

  1. Google Ads MCP server, Google's open-source, read-only server (google-ads-mcp, source). Run it locally with pipx run --spec git+https://github.com/googleads/google-ads-mcp.git google-ads-mcp, or deploy it to Cloud Run for remote clients. Its tools are list_accessible_customers, search for GAQL and get_resource_metadata (docs).
  2. Google Ads API with OAuth. Enable the Google Ads API in a Google Cloud project, sign in with Application Default Credentials (gcloud auth application-default login with the adwords scope) or an OAuth client, and set GOOGLE_PROJECT_ID. Add GOOGLE_ADS_LOGIN_CUSTOMER_ID when you reach client accounts through a manager account, and write customer IDs without dashes.

The adwords scope can't be narrowed, so sign in as a Google Ads user with Read only access; the MCP server has no write tools either way.

Questions

Can Google spend more than my daily budget?

On a single day, yes, up to twice the average daily budget. Over a month Google charges no more than 30.4 times the average daily budget per campaign, which is why the agent paces against the calendar rather than against single days.

We pay through an account budget with monthly invoicing. Does that change anything?

The skill can read the limit from the account_budget resource (approved_spending_limit_micros) instead of asking you for it. An account budget stops all ads when it runs out, so pacing matters even more there.

Do I need Briefkin to use the Google Ads budget pacing skill?

No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a stat tile, so you can glance at it instead of asking again.

Which agents can run it?

Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.

Can it work without an API or MCP server, from my browser?

Yes. Switch the data source to "Your browser" and the steps change to the Google Ads pages themselves: the agent opens ads.google.com/aw/campaigns in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.

Watch projected month-end spend on your board, run after run

Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.

Free during the open beta. No card.