How to set a daily spending limit for an AI agent's API key
Set it on the key's row at withruntime.com/account/keys, or make the key with runtime keys create --daily-limit 25.
On Runtime the limit is enforced on the server, per key, over any 24 hours, so an agent that loops cannot spend past it and no key can raise its own limit. A $25 limit buys a lot of agent time at Runtime's rates: 800 hours of a waiting 2 vCPU, 4 GiB sandbox at $0.03125 an hour, or 312 fully busy hours at $0.08 (rates checked 25 September 2026, pricing). There is no plan fee on top.
Set the limit
Two ways, both through a person:
- On the website. At API keys, set a limit when you create a key, or later from its row. Change or remove it there too.
- From a terminal, for a new key.
runtime keys createasks for a key in the browser, with the limit on the approval page:
Terminalruntime keys create --name support-agent --daily-limit 25 # dollarsruntime keys create --name ci --daily-limit 10 | gh secret set RUNTIME_API_KEYThe key is printed once, alone on standard output, so it pipes into a secret store (keys for CI). The member who made the key, or an owner or admin, can change its limit later, and only on the website.
What the limit counts
| Counted | Detail |
|---|---|
| Settled charges | Everything the key's sandboxes cost in the window |
| Money still on hold | A running lease's reservation counts before it settles |
| Renewals | A persistent sandbox renewing its lease |
| Parked storage | Paused sandboxes, charged as they are kept |
| Window | Any 24 hours; room comes back as older spending leaves it |
What happens at the limit
A create, wake, extension or renewal that would pass the limit fails with HTTP
402 spending_limit_reached, and nothing is charged. The SDKs do not retry it.
- Running sandboxes keep their current lease. One that needs a renewal past
the limit stops or pauses when its lease ends, and its
stopReasonreadsspending_limit. - Paused sandboxes keep costing storage. If that storage cannot be paid for, you are notified, and after seven days unpaid it is deleted. Set the limit above what the agent's paused sandboxes cost in a day (security).
Let the agent see what is left
Any key can read its own access and limit, and none can change it. An agent that checks before a large job can stop politely instead of failing halfway.
TypeScriptimport { Runtime, RuntimeError } from "withruntime";const runtime = new Runtime();const { daily } = await runtime.limits.get();console.log(daily.limitMicros, daily.usedMicros, daily.remainingMicros);try { await using sbx = await runtime.sandboxes.create(); await sbx.exec("python3 job.py");} catch (error) { if (error instanceof RuntimeError && error.code === "spending_limit_reached") { console.log("Daily limit reached; ask a person to raise it.", error.hint); } else throw error;}Pythonfrom withruntime import Runtime, RuntimeErrorwith Runtime() as runtime: daily = runtime.limits.get()["daily"] print(daily["limitMicros"], daily["usedMicros"], daily["remainingMicros"]) try: with runtime.sandboxes.create() as sbx: sbx.exec("python3 job.py") except RuntimeError as error: if error.code != "spending_limit_reached": raise print("Daily limit reached; ask a person to raise it.", error.hint)Terminalruntime limitsMoney is in microdollars, as strings: "25000000" is $25, and limitMicros
is null when no limit is set. runtime.limits needs withruntime 0.3.1 or
later. Over HTTP it is GET /v1/limits, and an agent on MCP calls
runtime_limits_get.
Mistakes to avoid
- Making replacements in a loop. A refused create costs nothing, but a loop that retries it wastes the agent's turn: the limit counts the last 24 hours, so the answer stays the same until spending ages out.
- Asking the agent to lift it. No key can raise, remove or set a limit, and no key can create another key. That is the point: tell the person the agent works for.
- One key for every agent. A limit is per key. Give each agent or application its own key, so a limit and the audit log both say which one spent.
- A limit below parked storage. An agent that keeps many paused sandboxes needs room for their storage every day, or they are deleted after seven unpaid days.
Other controls
A daily limit bounds a key. To bound one sandbox, use maxTotalCostMicros or
maxCostMicros (cap a sandbox's cost).
To give a dashboard a key that cannot spend at all, use a
read-only key. For an agent's full setup, see
Claude Code in a sandbox.
Facts on this page were checked on 25 September 2026.