LinkedIn Ads budget pacing dashboard for every client account
See every LinkedIn ad account's spend against the budget you committed to, catch overspend early, and rebalance without rebuilding a spreadsheet.
Build an internal app my paid social team opens every morning and again at month end, to see whether LinkedIn Ads spend is pacing against the budget we actually committed to for each client. Today that answer lives in a spreadsheet someone rebuilds by hand from Campaign Manager exports, and it is always a day or two stale.
The main screen
The main screen is a pacing table listing every LinkedIn ad account the connected user has access to (Search Ad Accounts), with its campaign groups (Search Campaign Groups) and campaigns (Search Campaigns) nested underneath as expandable rows. Each account renders as a group header with its own rolled up totals, and each campaign row is where the detail lives.
For every row show month to date spend (Get Ad Analytics), the committed monthly budget read from our Google Sheet (Get Values), percent of the flight elapsed, a pacing index, projected end of month spend, and dollars over or under budget. Sort worst pacing first, meaning the largest absolute deviation from on pace, so the campaigns that need attention sit at the top without anyone filtering. Use semantic status colours for the pacing index: on pace, overspending, underspending.
The budget sheet is the source of truth for what we committed to. Read it with Get Values from a tab holding one row per account or per campaign with the identifier, the month, the committed amount, and the currency. Match sheet rows to LinkedIn entities by that identifier, and show a clear no budget set state on any row with no matching sheet entry rather than treating a missing budget as zero.
How pacing is calculated
Pace every campaign against its own run schedule, not the calendar month. Percent elapsed is how much of the time between the campaign's scheduled start and end has already passed as of today, not the day of the month.
Pacing index is spend to date divided by committed budget, divided by percent elapsed. An index of 1.0 is exactly on pace, above 1.0 is overspending, below 1.0 is underspending.
Projected end of month spend is the run rate to date extrapolated across the remainder of the flight.
Dollars over or under is projected spend minus committed budget.
Campaigns running with no end date have no flight to pace against. Flag these visibly as open ended, fall back to calendar month pacing for them, and let the user filter to just those rows, since an always on campaign with no end date is usually the thing quietly eating the budget.
Inline actions
From any campaign row the user can change the daily budget or pause and resume the campaign inline, both through Update Campaign. The daily budget is an inline editable field on the row, and pause and resume toggles campaign status between ACTIVE and PAUSED. Both write immediately, reflect the result on the row, and surface any LinkedIn validation error inline rather than in a browser alert. Confirm before pausing a campaign that is currently active.
Sharing and spend history
A Post snapshot action sends the current pacing snapshot for an account to a client channel with Slack Bot Send a Message, formatted as a readable summary of each campaign's spend, budget, pacing index, and projected finish rather than a raw table dump. Every snapshot also appends a timestamped row per campaign to the spend history tab with Append Values, so we accumulate a spend history over time that nobody has to rebuild by hand.
Rebalance this account, a background agent
Each account header has a Rebalance this account button that kicks off a background agent. The agent pulls the last 30 days of per campaign analytics for that account (Get Ad Analytics pivoted by campaign), compares efficiency and pacing across the campaigns, works out which ones to trim and which to fund, and writes a proposed reallocation plan back into the app: one line per campaign with the current daily budget, the proposed daily budget, and a short written reason for the change. The plan must keep the account's total proposed spend within the committed budget.
The plan lands in the app as a pending proposal attached to that account, and nothing changes in LinkedIn when the agent finishes. The user reviews it line by line and approves or rejects each line individually. Only approved lines are applied, each through Update Campaign, and the app records which lines were approved, rejected, and applied so there is an audit trail. Show the agent's run state on the account row so people know a rebalance is in progress, and keep previously generated plans viewable.
Rules to respect
Keep every account in its own currency and never sum across accounts into a single blended total. A LinkedIn ad account's currency is fixed when the account is created and cannot change, so per account totals are the only honest rollup. Money values in the API are objects like {"amount":"100.00","currencyCode":"USD"} where the amount is a decimal string, and child entities must match the account currency.
There is no update operation for campaign groups, so every budget edit, whether from an inline change or an approved rebalance line, happens at the campaign level through Update Campaign. Campaign group rows are display and rollup only.
Update Campaign uses Rest.li partial update semantics: POST with the X-RestLi-Method: PARTIAL_UPDATE header and a body of {"patch":{"$set":{...}}}. A successful update returns 204 with no content, so treat 204 as success rather than waiting for a response body.
Analytics endpoints are throttled harder than the CRUD ones. Pull each date range in a single Get Ad Analytics call using timeGranularity and the appropriate pivot instead of looping day by day or campaign by campaign, and back off on 429 responses and on 403 responses carrying a throttling service error code.
Ad account, campaign group, and campaign identifiers are URNs, and the search endpoints use cursor pagination. Page through with pageSize and the returned next page token so the dashboard lists every account rather than just the first page.
What does this prompt do?
- One screen listing every ad account you can access, with its campaign groups and campaigns underneath, showing month to date spend next to the budget you committed to.
- A pacing score for each campaign measured against its own run dates, so a campaign that started mid month is not judged against the calendar, plus projected end of month spend and dollars over or under.
- Change a daily budget or pause and resume a campaign right from the row, post the snapshot to a client channel, and save every snapshot to your spend history sheet automatically.
- A Rebalance button that has an assistant study the last 30 days and propose which campaigns to trim and which to fund, with its reasoning, for you to approve or reject line by line.
What do I need to use this?
- A LinkedIn Ads login with admin access in Campaign Manager for the accounts you want to track
- A Google Sheet holding the monthly budget you committed to for each account or campaign
- A Slack workspace, if you want to post pacing snapshots to a client channel
How can I customize it?
- Set how far off pace a campaign has to be before it gets flagged as at risk
- Choose which Slack channel each account posts its pacing snapshot to
- Point it at your own budget sheet layout, whether you keep budgets per account or per campaign
- Decide whether the rebalance assistant can suggest pausing campaigns or only shifting daily budgets
FAQs
Will this change my budgets automatically?
Can it handle client accounts in different currencies?
What happens to campaigns that have no end date?
Does my budget spreadsheet need a specific format?
Does this work if I manage several client accounts?
Related templates
Every weekday at 10am, an AI voice agent phones your most overdue Xero accounts, logs what each customer promised, and reports back to finance in Slack.
See every Google Maps listing you manage on one screen, ranked worst first, with an audit button that writes the fix list for you.
Your team picks a template, finds the customer, checks they are safe to email, then sends it, with every send logged where the whole team can see it.
Every logo, photo, video cut and ad export in one searchable grid, with previews, campaign tags and rights expiry dates at a glance.
Twice a day we spot the people clicking your pricing and demo pages, create a follow-up task for their owner, and post a ranked recap to Slack.
One board showing every dashboard and Look with its folder, owner and favorite count, so you can find dead content and retire it safely.
Stop rebuilding pacing spreadsheets every month.
Open one dashboard that shows every LinkedIn ad account against the budget you actually committed to, sorted worst first.