Campaigns and budgets

Great ROAS. Then why is the bank account flat?

Because revenue is not profit. GrowCentric measures every campaign on what lands in your pocket after margin, and moves budget automatically from campaigns that only look good to campaigns that actually earn.

My agency reports 4x ROAS and I still cannot pay myself more.

Profit per ad dollar, not revenue per ad dollar

A campaign selling low margin products at 4x return can lose you money on every order. GrowCentric weighs every campaign by your real margins, so a modest looking campaign on a high margin product finally gets the credit and the budget it deserves.

Reallocating budget means a meeting, a spreadsheet and two weeks of delay.

Budget moves itself to where it earns

The engine checks margin, conversion, stock levels and competition for every campaign, then shifts budget in small, reversible steps. Big moves wait for your approval; routine ones just happen and show up in your briefing with the result attached.

It also respects reality: a winning campaign for a product with three weeks of stock left does not get more fuel.

I am sure some of my products would sell, if anyone ever saw them.

Your hidden bestsellers get their first campaign

Products people view and buy without any advertising are your cheapest growth. GrowCentric finds them, ranks the opportunity and proposes a starter campaign with budget taken from a loser. Two clicks and it runs, A/B tested from day one.

Under the hood

The allocator that never sleeps.

Every night the engine reads three sources: 18 months of your history distilled into demand curves by machine learning, live competitor moves from the crawler, and your true unit economics straight from Solidus, cost price and shipping included. Then it moves budget towards profit in small reversible steps. Routine moves execute themselves through the ad platform APIs; anything above your approval threshold waits for a human in the morning briefing.

Sales history

  • 18 months, per SKU

Competitor crawls

  • prices, delivery, offers

Solidus unit economics

  • cost price, your shipping

ML demand curves

  • revenue response per campaign

Profit engine

POAS = ROAS × margin
profit = m·r(b) − b

Allocator

  • maximise Σ profitᵢ(bᵢ)
  • subject to Σ bᵢ = B
  • shift until marginal profits equalise

Inside guardrails

Executes itself via the ads APIs, logged and reversible.

Above threshold

Moves above $500 a day wait for your approval in the briefing.

profit_allocator.ts

runs nightly · 03:00

// 03:00 · nightly allocation run
const signals = await Promise.all([
history.demandCurves({ lookback: '18m' }), // ML: revenue response per campaign
crawler.pressure(), // live competitor moves, 6 shops
solidus.unitEconomics(), // cost price + shipping, per SKU
])
 
const campaigns = await ads.campaigns.list({ status: 'ENABLED' })
 
for (const c of campaigns) {
const margin = signals.economics.margin(c) // after COGS and shipping
c.profit = margin * c.revenue - c.spend // what actually lands
c.marginal = signals.curves.slope(c) // profit of the next unit of spend
}
 
const plan = allocate(campaigns, {
objective: 'max_profit',
budget: account.dailyBudget,
guardrails: { maxDailyShift: 0.05, minSpend: floors, stockAware: true },
})
 
for (const move of plan.moves) {
if (Math.abs(move.delta) > thresholds.approval) {
await queue.askHuman(move) // waits in the morning briefing
continue
}
await googleAds.campaignBudgets.mutate([
{ update: { resourceName: move.campaign, amountMicros: move.next * 1e6 } },
])
}
 
log.info(`moved ${plan.total} across ${plan.moves.length} campaigns`)

Illustrative excerpt. The production engine adds seasonality, stock awareness and per campaign floors, and writes every decision to an audit log you can read in plain language.

What campaigns and budgets cover

  • Profit based measurement for every campaign and channel
  • Automatic budget reallocation in small reversible steps
  • A/B tests with automatic rollout of proven winners
  • Hidden gem detection with ready to run starter campaigns
  • Clean tracking across channels, including QR codes for offline
  • Season aware planning built on your sales history