Skip to content
BLACKLAKE
Cost capture + budgets▾ docs nav

Cost governance — five-minute quick start

The other axis of governance: stop runaway spend before it leaves the network. Budgets, cost-aware policies, baselines, and anomaly detection all sit on the same cost_records ledger as your evaluations.

If you've already wired bl.govern() calls (see the SDK quick start), the cost path is mostly configuration — no extra code.

What you get#

  govern() with estimate  →  budget pre-check  →  policy decision  →  upstream call
                                  │                                          │
                                  ▼                                          ▼
                          (deny if over budget)                 captureCost() updates totals
                                                                          │
                                                                          ▼
                                                         budget reconcile + threshold webhooks

Three levers: per-call cost ceilings inside policies, workspace/agent/tool/user-scoped budgets, and continuous anomaly detection.

1. Pass an estimate on every govern() call#

Without an estimate, budget pre-checks have nothing to project against — they only catch overruns after the spend lands. Pass one:

import { BlackLake } from 'blacklake';
const bl = new BlackLake({ apiKey: process.env.BLACKLAKE_API_KEY });

const estimate = await bl.cost.estimate({
  provider: 'anthropic',
  model: 'claude-opus-4-7',
  input_tokens: 1200,
  output_ceiling_tokens: 800,
});

if (!estimate.pricing_known) {
  // Model isn't priced — calls won't cost-track. See /usage/pricing.
  console.warn(estimate.warnings);
}

const decision = await bl.govern({
  agent: 'expense-bot',
  tool: 'stripe.refund',
  action: { ... },
  estimate: {
    provider: 'anthropic',
    model: 'claude-opus-4-7',
    input_tokens: 1200,
    output_ceiling_tokens: 800,
    estimated_cost_usd: estimate.total_usd,
  },
});

If the estimated spend would push any enforcing budget over its hard limit, the call denies before the LLM is hit — decision.reason leads with the headroom math.

2. Set a budget#

In the console:

  • Budgets → Create — name, scope (workspace / agent / tool / user), period (per-task / day / week / month), soft + hard limit in USD.
  • A soft_limit_usd fires budget.threshold_crossed webhooks at 50% / 80% / 100% so you get warnings before the gate engages.
  • The hard_limit_usd is what govern() pre-checks and denies against.

Or via the SDK:

await bl.budgets.create({
  name: 'expense-bot daily',
  scope_type: 'agent',
  scope_id: 'agent_xxx',
  period: 'day',
  soft_limit_usd: 25,
  hard_limit_usd: 50,
});

The Budgets page shows current spend vs limits in real time, with friendly scope names (no raw agent_xxx ids).

3. Add cost conditions to high-risk policies#

Selectors gate by what — cost conditions gate by how much. Add them to policies that need cost-aware behaviour:

{
  "agent_selector": { "name": "expense-bot" },
  "tool_selector": { "risk_classification": "high" },
  "outcome": "deny",
  "cost_conditions": {
    "estimated_cost_usd_max": 0.50
  },
  "mode": "enforce"
}

This denies any high-risk-tool call from expense-bot whose estimated cost exceeds $0.50, regardless of budget headroom. Use mode: 'monitor' to log without enforcing while you tune the threshold.

4. Verify cost coverage#

Visit Console → Usage:

  • Headline Total spend excludes any unpriced calls — and surfaces them as an amber banner: "X of Y calls were billed at $0 because the model isn't priced."
  • The By model breakdown badges any unpriced rows so you can see exactly which model strings to add to pricing.
  • Pricing coverage (linked from Usage) lists every priced model in the current snapshot.
  • Budget chips on the right show headroom against every active budget.

5. Wire alert webhooks#

Webhooks fire on:

  • budget.threshold_crossed (50% / 80% / 100% soft)
  • budget.limit_exceeded (100% hard — at-risk)
  • cost.recorded (every captured record — useful for mirroring to finance)

Register at Console → Webhooks. Each delivery is HMAC-signed; the delivery debugger (/webhooks/<id>) shows the exact base string to verify against. See the Policy guide for cost-aware policy syntax and the SDK reference for bl.cost.* and bl.budgets.*.

What's next#