usage-costs
by @netanel-abergel
Report AI token usage and estimated costs. Use when: owner asks about costs today/yesterday/this week, per session, or per model. Shows main session, cron jo...
clawhub install usage-costsπ About This Skill
name: usage-costs version: "1.0.0" description: "Report AI token usage and estimated costs. Use when: owner asks about costs today/yesterday/this week, per session, or per model. Shows main session, cron jobs, and subagents. Answers: 'how much did today cost?', 'how much was this session?', 'what was last week's spend?'"
Usage Costs Skill
Reports token usage and estimated costs from OpenClaw sessions.
Load Local Context
CONTEXT_FILE="/opt/ocana/openclaw/workspace/skills/usage-costs/.context"
[ -f "$CONTEXT_FILE" ] && source "$CONTEXT_FILE"
Provides: $OWNER_PHONE, $PRICING_INPUT, $PRICING_OUTPUT, $PRICING_CACHE_READ
Data Sources
1. Live sessions β openclaw status --deep (current token counts per session)
2. Cron run history β /opt/ocana/openclaw/cron/runs/*.jsonl (usage field per run)
3. Token history β /opt/ocana/openclaw/workspace/data/token-history.jsonl (daily aggregates)
Pricing (claude-sonnet-4-6, as of 2026-04)
| Type | Price | |---|---| | Input | $3.00 / 1M tokens | | Output | $15.00 / 1M tokens | | Cache read | $0.30 / 1M tokens | | Cache write | $3.75 / 1M tokens |
Step 1 β Live Session Report
# Get current session token counts
openclaw status --deep 2>/dev/null | grep -E "agent:main|direct|cached" | head -20
Parse output: each row has session_key | kind | age | model | tokens.
Step 2 β Cron History Report
#!/usr/bin/env python3
import json, glob, os
from datetime import datetime, timezone, timedeltadef get_cron_usage(days_back=1):
cutoff = datetime.now(timezone.utc) - timedelta(days=days_back)
cutoff_ts = cutoff.timestamp() * 1000
total_input = 0
total_output = 0
runs = []
for f in glob.glob('/opt/ocana/openclaw/cron/runs/*.jsonl'):
job_name = os.path.basename(f).replace('.jsonl', '')
with open(f) as fh:
for line in fh:
try:
d = json.loads(line)
if d.get('ts', 0) >= cutoff_ts and 'usage' in d:
inp = d['usage'].get('input_tokens', 0)
out = d['usage'].get('output_tokens', 0)
total_input += inp
total_output += out
runs.append({
'job': d.get('name', job_name),
'input': inp,
'output': out,
'ts': d['ts']
})
except:
pass
return total_input, total_output, runs
inp, out, runs = get_cron_usage(days_back=1)
cost = (inp / 1_000_000 * 3) + (out / 1_000_000 * 15)
print(f"Cron tokens (last 24h): {inp:,} in / {out:,} out")
print(f"Estimated cost: ${cost:.2f}")
print(f"Runs: {len(runs)}")
Report Formats
"How much did today cost?"
π Cost Report β 2026-04-04Main session: ~276K tokens (100% cached)
Cron runs: 25 runs | X in / Y out tokens
Subagents: N sessions | X tokens
Estimated total: ~$Z
(Cron: $A | Subagents: $B | Main session: estimated $C)
Note: Main session cost is estimated β cache reduces actual cost by ~90%.
"How much this week?"
/opt/ocana/openclaw/workspace/data/token-history.jsonl"How much was this session?"
openclaw status --deepagent:main:main row β tokens fieldSave Daily Report
Append to /opt/ocana/openclaw/workspace/data/token-history.jsonl:
{"date": "2026-04-04", "input": 133, "output": 17376, "cache_read": 900000, "cost_usd": 0.54, "cron_runs": 25, "subagent_runs": 4}
Cost Extraction Script (from session jsonl files)
This is the authoritative method for extracting real costs β works for Anthropic/Claude models:
python3 -c "
import json, glob, os
from datetime import datetime, timezonesessions_dir = '/opt/ocana/openclaw/agents/main/sessions'
files = glob.glob(f'{sessions_dir}/*.jsonl')
today = datetime.now(timezone.utc).date()
total_cost = 0
total_cache_write = 0
total_cache_read = 0
sessions_today = 0
for fpath in files:
mtime = datetime.fromtimestamp(os.path.getmtime(fpath), tz=timezone.utc).date()
if mtime != today:
continue
sessions_today += 1
with open(fpath) as f:
for line in f:
try:
l = json.loads(line)
if l.get('type') == 'message' and l.get('message',{}).get('role') == 'assistant':
u = l['message'].get('usage',{})
total_cost += u.get('cost',{}).get('total',0)
total_cache_write += u.get('cacheWrite',0)
total_cache_read += u.get('cacheRead',0)
except: pass
print(f'Today: {sessions_today} sessions β \${total_cost:.2f}')
print(f'Cache writes: {total_cache_write:,} tokens')
print(f'Cache reads: {total_cache_read:,} tokens')
"
β οΈ Provider compatibility: