Guardrails
A guardrail is a refusal with a number behind it. It is not a permission — who may ask for a change is a matter of roles and scopes — and it is not an approval rule. It is the set of limits a budget-bearing change has to satisfy before Tempio will send it to a platform, whoever approved it and however it was approved.
Checked more than once
The budget guardrails run when the draft is written. Every guardrail, the kill switch included, runs again when it is approved, and once more inside the apply, immediately before the platform is called.
More than once because a draft can sit at the gate while real time passes. The account it targets can spend, a sibling draft can land, the connection can be paused. The last check is the one that decides, and it reads current state rather than the state the draft was written against.
The same functions run at all three points, so the answer cannot differ between the sentence you read at the gate and the decision made at the apply.
The kill switch
A connection whose status is anything but active blocks every apply written against it. Pausing a connection on Connections is the one control that stops Tempio writing to those accounts — whatever is queued, whatever rule would otherwise have cleared it, and whoever approves it after.
The refusal names the connection and its state. Nothing is rejected: the drafts stay where they are, and setting the connection active again lets them run.
The account's daily cap
Every ad account carries its own ceiling, derived from what that account has actually done:
three times the highest single-campaign daily spend in its last 28 days, floored at the default cap for its currency.
The peak is taken over one campaign's day rather than the account's total, because that is the shape of the number a draft is asking for: what one campaign was trusted to spend in a day. The multiple gives enough headroom to scale a winner and not enough to double an account by accident.
An account with no history — a new connection, a test account — gets the floor, which is the conservative answer rather than an unlimited one. The cap is computed on the first draft that needs it and refreshed by the weekly deep re-read, so it follows the account as the account grows.
This is the number a workspace override replaces — see Who can change them below. The derivation keeps running underneath either way.
The floor itself is stated per currency, in the currency's own money:
| Currency | Daily floor | First-budget cap |
|---|---|---|
| Most currencies | 1,000 | 500 |
| JPY | 150,000 | 75,000 |
| KRW | 1,300,000 | 650,000 |
Those are launch heuristics, not conversions. Scaling a dollar cap by the minor-unit factor alone would hand a yen account a guardrail a hundred times tighter than a dollar one, so the two currencies whose major unit is nowhere near a dollar state their own. Everything else takes the default, which is honest for the dollar-ish majority and errs tight elsewhere.
A lifetime budget is checked as its daily equivalent over the flight it states. A lifetime amount with no readable flight is checked as-is, which is the tight reading.
The movement rule
A budget may not move more than 100% from what the entity spends today, in either direction. Upward that makes doubling the most a single change may do. Downward, 100% of the current figure is the whole of it, so a single change can take a budget all the way to zero — pulling spend back is not what this rule is for.
This one needs a pre-image — the mirror's record of the entity's current budget. Where there is none, the first-budget cap applies instead.
The percentage itself is overridable per scope, so a workspace that wants a tighter brake than doubling can write one.
The first budget
An entity with no budget yet is held to the initial cap for its currency, from the table above. Once an account's own derived cap has risen above the currency's default — which only happens on the strength of the account's own 28 days — that derived cap becomes the ceiling for a first budget too. A real account's first campaign should not be blocked by a number picked to be safe for an empty one.
The 24-hour aggregate
Applied budget increases on one connection are summed over the last 24 hours. The sum, plus the raise being approved, must stay under the account's daily cap.
This is the only check that can refuse a change every earlier check allows. Ten individually legal increases are still a doubled account by dinner, and this is what stops the loop — including a loop driven by an agent that is doing exactly what it was asked.
Decreases contribute nothing to the sum. The cap exists to stop spend running away, not to stop it being pulled back. The sum is per connection, per currency: a connection holding a US account and a Japanese one keeps two sums, because adding them would not be a number.
Money never converts
Every comparison here happens in one currency: the account's. Caps are stated in it, budgets are stamped with it from the account rather than read from whatever asked for the change, and no rate is ever applied. The currency estimates on the reading side are a labelled convenience; nothing on the writing side has one.
The platform's own answer
Where a platform offers a dry run, Tempio asks it while the draft is being written and records the verdict on the row. A refusal arrives with the platform's own message and the fields it names, at the gate, rather than after the change was approved. A draft the platform's dry run refused is also one no approval rule may clear.
Said before the refusal
A guardrail is not only a wall at the end. An account whose busiest
campaign-day already sits at 80% of its own daily cap or more carries a
near_daily_cap warning — class budget_guardrail, with the account as its
subject — on reads that return that account. An agent planning a raise is told
the ceiling is close before it drafts against it, rather than at the refusal.
The warning changes no value and refuses nothing; it only says what is near.
Who can change them
Two of the checks above are Tempio's and no setting moves them: the 24-hour aggregate, and the kill switch. Everything else is a number your workspace can write, under Settings → Guardrails, on Plus and up.
An override replaces one or more of the three caps — the daily cap, the first-budget cap and the movement rule — at one of three scopes:
| Scope | Applies to |
|---|---|
| Workspace | every account in the workspace |
| Connection | every account on that connection |
| Ad account | that one account |
The most specific scope that has an override wins, and it wins per number. A workspace override that sets only a movement rule leaves the daily cap and the first-budget cap where they were; an account override that sets only a daily cap still takes its movement rule from the connection or workspace above it. A number nobody has overridden falls through to the account's own derived cap, and under that to the default for its currency.
An override can raise a cap as well as lower one. The derived cap is three times a 28-day peak, and a workspace launching a new account or running a seasonal push has a real reason to want more room — as a workspace that wants a tighter ceiling than Tempio's has a reason to want less. What a raise cannot do is get past the 24-hour aggregate or the kill switch, which is why those two are not on the page as fields.
Caps are money, so a cap is stated in one currency: the account's for an
account override, and the connection's accounts' single currency for a
connection override. A connection holding accounts in two currencies cannot
carry one cap for both, and the page says so rather than picking one. A cap
whose currency does not match the account being checked is ignored — never
converted — and the read that skipped it carries a guardrail_override_currency
warning saying why.
The movement rule is a percentage, so it has no currency at all. An override that sets only a movement rule is stored with no currency and applies to every account under its scope whatever each one bills in; an override that sets both has its caps skipped on an account in another currency and its movement rule still applied. Nothing is ever converted either way.
The first-budget cap never sits above the daily cap under it. If the daily cap is lowered below the first-budget cap that would otherwise apply, the first-budget cap comes down with it — the daily check would refuse first, so a higher number would be a ceiling nobody could reach.
The derivation never stops running underneath. Turning an override off, or removing it, returns the account to its own 28-day number immediately, with nothing to recompute.
Writing one is an owner's or an admin's act. Each write leaves an audit row —
guardrail.set, guardrail.disabled or guardrail.removed — carrying the old
numbers beside the new ones, so the record answers "what was it before, and who
moved it" and not only "what is it now".
Whether an override is switched on is its own decision, with its own audit row. Saving an override that is switched off leaves it switched off; turning it back on is the switch in the list, not a side effect of editing the numbers.
Agents read these caps and never write them. list_guardrails returns the
effective three per account with the scope each came from, so an agent planning
a raise knows the ceiling before it drafts against one; there is no tool at any
scope that changes a guardrail. A person changes the rules; an agent works
inside them.
Which cap a draft was checked against
Every budget-bearing draft records the caps it was measured against and where each came from, at the moment it was written and again at the moment it was approved — the approval's check is the authoritative one, and it is the one the row ends up carrying. It is a snapshot of the numbers, not a pointer at the override: editing or removing the override afterwards never changes what a draft says it was checked against. The draft page states it in a sentence:
Checked against the workspace cap of A$800.00 set by Priya on Sep 2, 9:14 AM UTC.
A draft that carries no money has no cap to name and says nothing.
The approval rules and chains under Approvals are a different thing again: they decide who clears a change, and a guardrail decides whether the change is allowed at all. A rule can never approve past a guardrail.
What a refusal looks like
Every guardrail refusal is one sentence carrying the number that failed: the
amount, the cap it exceeded, and the currency both are in. It is a
guardrail_blocked code at the tool layer and the same sentence in the app.
Nothing is applied and nothing is rejected. The draft stays at the gate, and it is fixable in place — edit the payload with an amount that passes and it goes back to waiting, re-validated and re-guarded, which is also how a stopped batch is resumed. Drafts has that path.
Drafts
How a change request is written, batched, guarded, approved by you or by a rule you wrote, applied, and undone.
Plans
Media plans — the working document where a quarter is shaped before anything is drafted, what materializing one turns it into, and the planner around it — the timeline, pacing, phases, the allocator and scenarios.