DOCS /AGENTS & BUDGETS

Agents & budgets

Your spend controls have two sides. Approvals decide which services money may flow to — the per-service toggles that shape your grant's allowlist. Agents decide which apps may spend on your behalf — and on Yeetful, an agent is an API key.

An agent is an API key

Anything paying through the yeetful SDK authenticates with a yf_… key minted at yeetful.com/dashboard/keys. That key is the agent's identity: every receipt it syncs is attributed to it in the ledger, and the Agents tab shows each key with a spent-today meter built from exactly those rows. One app, one key — revoke the key and the agent is disconnected.

Per-day budgets — and who can change them

Each key takes an optional per-day USD budget, set on the Agents tab. Budgets are edited with PATCH /api/keys/[id], which is SIWE-session-only — the same gate as minting. The Bearer key itself is deliberately not accepted there: an agent must never be able to raise its own budget with the key it holds.

The pre-flight: GET /api/agent/policy

The SDK's standing question — "may I still pay, and how much?" — has one endpoint. It is Bearer-only(the agent asks with its own key; there is no browser surface) and returns both sides of the policy: the key's budget and the owner's active grant.

GET /api/agent/policy
Authorization: Bearer yf_…

{
  "agent": {
    "keyId": "cmq…",
    "label": "travel-agent",
    "perDayUsd": 5,            // null = no daily budget
    "spentTodayUsd": 1.23,
    "remainingTodayUsd": 3.77, // null when perDayUsd is null
    "overBudget": false
  },
  "grant": {                   // null if the owner has no active grant
    "id": "cmq…",
    "label": "Expense account",
    "allow": ["tripadvisor.x402.paysponge.com"],
    "perCallUsd": 0.05,
    "perDayUsd": 5,
    "totalUsd": null,
    "spentTodayUsd": 1.23,
    "spentTotalUsd": 9.41,
    "expiresAt": "2026-07-12T00:00:00.000Z",
    "signed": true
  }
}

The echo: budgets ride along on every receipt sync

The SDK doesn't poll. When it syncs a receipt with a Bearer key, the response carries a slim agent echo — the updated budget after that very row landed — so the agent's local picture stays fresh for free:

POST /api/grants/[id]/ledger   →  201
{
  …ledger entry…,
  "agent": { "perDayUsd": 5, "spentTodayUsd": 1.24, "overBudget": false }
}

What the SDK does with it

The snippet below is SDK 0.4— merged, not yet on npm (which has 0.3.1). Until it's published, budgets show on the dashboard but the SDK won't enforce them.

const pay = yeetful({ wallet, grant: { id: 'your-grant-id', /* … */ }, apiKey: process.env.YEETFUL_API_KEY })

pay.agentBudget() // { keyId, label, perDayUsd, spentTodayUsd, remainingTodayUsd, overBudget }

// Over budget — or a call whose quoted price exceeds remainingTodayUsd —
// throws GrantError('OVER_AGENT_BUDGET') BEFORE any payment is signed,
// and the denial receipt syncs, so the refusal shows in your audit feed.

0.4 fetches the policy once at startup (a failed fetch degrades open — payments proceed under the grant alone), refreshes from the agent echo on every sync, and re-fetches on flushLedger() so mid-run dashboard edits get picked up.

Where enforcement actually lives

Budgets are advisory at the rails: the agent pays x402 challenges from its own wallet, so Yeetful cannot block a payment in flight. The SDK is the enforcement point — it reads the policy and refuses locally, the same trust model as the grant itself. That's the right tool for governing your own agents (runaway loops, bugs, prompt-injected tool calls). Hard, adversarial enforcement arrives with Coinbase Spend Permissions, where an on-chain allowance caps spend regardless of what the SDK does.

Approvals vs. agents, side by side

  • Approvals (dashboard): per-service toggles. They re-derive your grant's allow[] — which hosts money may flow to. Off by default.
  • Agents (dashboard/agents): per-key budgets. Which apps may spend for you, and how much per day.

Both feed the same hosted ledger; together they answer "who spent what, where, and was it allowed?" for every call your agents make.

Working with a team? Organizations put shared agent keys, approvals, and an org-level daily cap above these per-key budgets — one expense account for the whole company.