Field notes · 2026-11-02 · RunVouch
A daily cost cap for OpenClaw in five minutes
OpenClaw shows spend but never stops it. Install one skill, set cap_day_cost, and get a Telegram alert that pauses the agent. Honest about where the number comes from.
I ran a crypto trading bot and a handful of agents unattended for two years. The bill was never the thing that broke. The thing that broke was that nothing told me the bill was growing until the invoice did. OpenClaw has the same gap, and this is the five minute fix I use for it.
RunVouch is a dead man's switch, cost cap and outcome check for unattended agents: it alerts when a scheduled run is missed, fails, loops, overspends or finishes without proof.
Does OpenClaw have a cost limit?
No, not one that stops anything. OpenClaw tracks cost well. The usage and costs reference documents /usage cost for a local cost summary, a /usage full footer on every reply, and a Usage page in the Control UI. The same page says those totals describe local session history, not a provider invoice, and that Claude CLI usage gets no dollar figure at all.
What is missing is enforcement. Issue #42475, opened in March 2026, describes per-session cost tracking as observability only and asks for daily and monthly per-agent budgets checked at the gateway before a model call. It was closed as not planned on 1 November 2026 after an inactivity notice. Issue #113481 asks for something smaller, a daily spend notification per agent, and notes that /usage cost is pull-only: it never calls you when a threshold is crossed. Closed the same way in October 2026.
So the state today is: you can look at the number whenever you want. Nothing looks at it for you, and nothing refuses the next run when it is too high. For an agent that runs while you sleep, that is the whole problem.
Install the RunVouch skill for OpenClaw
Two skills live in the RunVouch repository. verified-run wraps one scheduled task in a start and an end report, with the output file as evidence. runvouch teaches the agent to check in on its own during a long session. For a cost cap you need the first one.
git clone --depth 1 https://github.com/runvouch/runvouch mkdir -p ~/.openclaw/skills cp -r runvouch/integrations/openclaw/verified-run ~/.openclaw/skills/ export RUNVOUCH_KEY=rv_... # free key, 3 agents
The OpenClaw skills FAQ explains the lookup order: a native openclaw skills install writes into the active workspace skills/ folder, --global targets the shared directory, and skills.load.extraDirs in openclaw.json adds your own folders. The copy above goes into the shared directory, so every local agent sees it. The skill declares that it needs RUNVOUCH_KEY and curl, so it stays hidden until the key is set. The key can also go into skills.entries.verified-run.apiKey in openclaw.json.
The wrapper itself is bash plus curl. It posts a start, runs your command, and posts the exit code, the size of the evidence file and the cost. If the RunVouch API is unreachable, the task still runs and a warning goes to stderr. Monitoring never blocks the job.
Set the OpenClaw daily budget: cap_day_cost
The cap lives on the agent record, not in the cron line. One call registers the agent with a cadence and a daily cap:
rv agent openclaw-inbox --cadence 24h --grace 1h --cap-day-cost 5 --evidence
Or without the client, straight at the API:
curl -X POST https://api.runvouch.com/v1/agents \
-H "X-API-Key: $RUNVOUCH_KEY" -H "Content-Type: application/json" \
-d '{"name":"openclaw-inbox","cadence_s":86400,"grace_s":3600,"cap_day_cost":5,"evidence_required":true}'
Then the host cron line that runs the task through the wrapper:
0 7 * * * ~/.openclaw/skills/verified-run/scripts/verified-run.sh openclaw-inbox \ --every 24h --grace 1h --evidence-file ~/out/digest.md --cost 0.40 \ -- openclaw task run inbox-digest
The rule behind cap_day_cost is simple: after every finished run, RunVouch sums the reported cost of all runs of that agent in the last 24 hours. If the sum is above the cap, BUDGET_DAY fires. A sibling, --cap-run-cost, does the same for one run. I set both on anything that calls a model in a loop.
Where the cost number comes from
This is the honest part. OpenClaw does not hand the wrapper a dollar figure for the run it just did, and when the agent authenticates through the Claude CLI there is no per-message estimate to hand over. So the cost is what you report, and you have three options.
- A fixed estimate per run. Read
/usage costafter a normal day, divide by runs, and pass it as--cost. Crude, but a loop that fires the task twenty times still crosses the cap. This catches the failure mode that actually costs money: not an expensive run, but too many runs. - A measured number. Export the Usage page or the JSON from the Control UI after the task and feed the delta to
--cost. More work, exact numbers. - The agent reports it. With the
runvouchskill the agent posts cost on/v1/runs/enditself, and posts every tool call on the way, which also turns an identical call repeated eight times into a RETRY_STORM alert.
Whatever you pick, write the choice down next to the cron line. The cap is only as honest as the number you feed it.
What the OpenClaw budget alert looks like
On Telegram it is one message, no dashboard required:
RunVouch [BUDGET_DAY] openclaw-inbox 24h cost 5.60 > daily cap 5.00. Agent paused, next run is refused. Resume with: rv agent openclaw-inbox --resume
Slack and webhook get the same fields, the webhook as JSON with kind, agent, run_id and message. Three things are worth knowing about the brake.
- It never kills a running process. The run that crossed the line finishes. The next
verified-run.shasks for a run id, gets a refusal, and skips the command. Your output file is never half written by a watchdog. - Pausing is a paid feature. On the free plan the same alert goes out with the same numbers, but the agent keeps running. Refusing the next run is part of Solo at $9 and Team at $29. The free plan is for seeing whether the alerts are right.
- Resuming is one call,
rv agent openclaw-inbox --resume, or the pause endpoint withpaused=false. The cap stays in place.
Cadence and heartbeat: a cap needs a pulse
A cost cap on its own has a blind spot. If the OpenClaw gateway is down at 07:00, nothing runs, nothing is reported, the cost is zero, and the cap is happy. That is why the agent record carries a cadence. With --cadence 24h --grace 1h, no start by 08:00 is a MISSED alert. A run that starts and never ends becomes STALLED. A run that exits 0 without writing digest.md is FAILED, because the wrapper deletes the stale file before the task and reports whether a new one appeared.
For the gateway itself I keep a second, cheaper agent: a 15 minute cron line that curls the health endpoint through rv run. If anything in your stack cannot run a client, each agent also has a ping URL, /ping/<token>, with /start, /fail or the exit code appended, so a single curl reports a run.
That is the whole setup. One skill folder, one agent record with a cap, one cron line with a cost. Five minutes, and the next time an OpenClaw task decides to run itself forty times before breakfast, you get a message at run thirteen and the schedule stops.
FAQ
Can OpenClaw stop an agent when it spends too much?
Not in the core as of November 2026. /usage cost and the Control UI show spend on request. The feature requests for enforced daily or monthly budgets (#42475) and for spend notifications (#113481) were both closed as not planned.
Does the RunVouch cap kill the OpenClaw process?
No. The run that crosses the cap finishes normally. The next run is refused at start, the wrapper skips the command, and the agent stays paused until you resume it.
What if I cannot measure the cost of a run?
Pass a fixed estimate with --cost. The daily cap then works as a run counter in dollars, which is the failure it usually needs to catch. Pair it with --cadence so a run that never happens also alerts.
Related field notes
- My Claude Code cron ran up $1,800 in two nights. The watchdog that stops it at $2
- Claude Code Routine failed silently? How to know your scheduled agent actually ran
- The dead man's switch for AI agents (and why a ping isn't enough)
Try it: free for 3 agents · Docs: Claude Code · cron