Documents

token-ledger

Try it

Audit-grade SQLite ledger that records every model call's token usage and cost from OpenClaw sessions.

What it does

Records per-call usage (input, output, cache read/write, cost) into `~/.openclaw/ledger.db` from OpenClaw session JSONL files, cron runs, and DGX Spark local inference logs. Includes a watcher daemon installable as a macOS LaunchAgent, plus Spark token sync via API Hub. Supports low-token SQL-first finance reports with preset daily queries and source_kind breakdowns (interactive, cron, subagent, spark). Versioned pricing stored in `price_versions` table; deleted threads handled via `.jsonl.deleted*` detection.

When to use it

  • Recording per-call token usage and cost into a SQLite ledger
  • Installing the watcher daemon as a macOS LaunchAgent
  • Querying daily cost, cached vs uncached mix, or Spark local usage
  • Backfilling source_kind metadata onto existing records

The skill document

Token Ledger (SQLite)

Install with:

openclaw skills install @jonathanjing/token-ledger

What this skill provides

  • A SQLite ledger at ~/.openclaw/ledger.db with per-call usage rows
  • A watcher daemon that tails OpenClaw session JSONL files and writes usage into SQLite (near-real-time)
  • Spark token sync - pulls DGX Spark local inference logs via API Hub
  • Deterministic, low-token SQL-first finance reports (no JSONL rescans)

Canonical usage definitions

  • input_tokens: uncached input tokens for the call
  • cache_write_tokens: tokens written to cache
  • cache_read_tokens: tokens read from cache
  • output_tokens: generated tokens
  • total_context_tokens = input_tokens + cache_write_tokens + cache_read_tokens

Files & paths

FilePath
SQLite DB~/.openclaw/ledger.db
Checkpoint~/.openclaw/ledger-checkpoint.json
Spark Checkpoint~/.openclaw/ledger-spark-checkpoint.json
Sessions JSONL~/.openclaw/agents/main/sessions/*.jsonl
Cron Runs~/.openclaw/cron/runs/**/*.jsonl
Spark Token Log (NFS)~/spark-nfs/.spark/token-ledger.jsonl

Standard operations

One-shot backfill (safe)

python3 "{baseDir}/scripts/ledger_watcher.py" --once

Backfill source_kind for existing records

python3 "{baseDir}/scripts/ledger_watcher.py" --backfill

Sync Spark tokens only

python3 "{baseDir}/scripts/ledger_watcher.py" --sync-spark

Install / start daemon (macOS LaunchAgent)

python3 "{baseDir}/scripts/render_plist.py" \
  > ~/Library/LaunchAgents/com.openclaw.token-ledger-watcher.plist
launchctl load ~/Library/LaunchAgents/com.openclaw.token-ledger-watcher.plist
launchctl list | rg token-ledger-watcher

Stop daemon

launchctl unload ~/Library/LaunchAgents/com.openclaw.token-ledger-watcher.plist

Quick sanity query

sqlite3 ~/.openclaw/ledger.db \
  "SELECT provider, model, COUNT(*) calls, ROUND(SUM(cost_total),4) cost FROM calls WHERE ts >= date('now') GROUP BY 1,2 ORDER BY cost DESC LIMIT 20;"

How to build low-token Finance reports

Preferred flow:

  1. Run SQL queries directly against ledger.db
  2. Format results with a deterministic template (no long reasoning)
  3. Only if numbers look anomalous: drill into calls for the specific session/model

For daily reports, use:

  • per-model totals
  • cached vs uncached mix
  • top sessions by cost
  • source_kind breakdown (interactive | cron | spark)

Notes / caveats

  • Provider billing can still exceed ledger totals due to retries/timeouts/streaming interruptions. Ledger is auditable, not magical.
  • Keep pricing versioned. Do not retroactively reprice historical calls unless explicitly requested.
  • Deleted threads: Watcher handles .jsonl.deleted* files
  • Spark local tokens: Spark local calls are logged via spark-token-ledger.jsonl. API Hub provides /spark/token-log endpoint for the watcher to pull (unidirectional sync).
  • Model normalization: Cloud models (Claude/GPT/Gemini) are normalized from provider/model format. Local Spark models are normalized to qwen-spark-35b or qwen-spark-27b.

Architecture

Use the bundled scripts as the source of truth; do not assume a separate workspace-specific reference file exists.

Data Flow

OpenClaw Sessions          Cron Jobs               DGX Spark
      ↓                        ↓                        ↓
*.jsonl               cron/runs/*.jsonl      spark-token-ledger.jsonl
      ↓                        ↓                        ↓
      └────────────────────┬──────────────────────────┘
                           ↓
                ledger_watcher.py
                           ↓
                    ledger.db (SQLite)
                           ↓
               SQL Queries / Reports

Key Tables

  • calls - Per-call usage records
  • turns - Aggregated turn-level metrics (60s window)
  • price_versions - Historical pricing for audit

Source Kind Detection

SourceDetection
InteractiveDefault, or from sessions.json
CronPath contains cron/runs OR session_key contains :cron:
SubagentSession key contains :subagent: or :run:
SparkRecords from Spark token log sync

Preset queries

# Today
today() {
  sqlite3 ~/.openclaw/ledger.db "SELECT provider, model, COUNT(*) calls, SUM(input_tokens) input, SUM(output_tokens) output, ROUND(SUM(cost_total),4) cost FROM calls WHERE ts >= date('now') GROUP BY 1,2 ORDER BY cost DESC;"
}

# By source kind
today_by_source() {
  sqlite3 ~/.openclaw/ledger.db "SELECT source_kind, COUNT(*) calls, ROUND(SUM(cost_total),4) cost FROM calls WHERE ts >= date('now') GROUP BY 1;"
}

# Spark usage (local models)
spark_usage() {
  sqlite3 ~/.openclaw/ledger.db "SELECT model, COUNT(*) calls, SUM(input_tokens + output_tokens) tokens FROM calls WHERE provider = 'local-dgx-spark' GROUP BY model;"
}

Pricing integrity

Use the versioned price_versions table. The watcher persists every bundled rate, its effective timestamp, and the provider pricing-page URL when the database opens. Provider pricing changes over time; do not copy a current price table into reports without recording its effective date and source.

Questions people ask

Where is the SQLite database stored?
The default database path is `~/.openclaw/ledger.db`, with checkpoints at `~/.openclaw/ledger-checkpoint.json` and `~/.openclaw/ledger-spark-checkpoint.json`.
Which token fields are recorded per call?
The `calls` table records `input_tokens` (uncached), `cache_write_tokens`, `cache_read_tokens`, `output_tokens`, and a `cost_total` derived from the versioned `price_versions` table.
Does it automatically sync DGX Spark local inference usage?
Yes. The watcher pulls `~/spark-nfs/.spark/token-ledger.jsonl` via the API Hub `/spark/token-log` endpoint, and writes those rows with `source_kind = spark` and `provider = local-dgx-spark`.

Related skills

Stores durable facts in a categorized, plain-markdown vault on disk, alongside your agent's built-in memory.

by Iván559 installs18 stars

Join a video meeting as an AI bot with voice, avatar, and screenshare across four operating modes.

by johnpatternai22 installs8 stars

Find why your productivity system keeps failing, then apply the smallest fix — capacity math, bottleneck routing, durable local notes.

by Iván855 installs69 stars

Generate and edit Draw.io, Mermaid, and Excalidraw diagrams from natural language using a structured JSON spec.

by nssa.io1.0k installs47 stars

Fetch raw ad creative, app, ranking, and revenue data from AdMapix as structured JSON.

by fly0pants4.3k installs296 stars

More from jonathanjing

Browse all skills

Operate and extend the read-only OpenClaw dashboard backend, frontend tabs, and security model.

by jonathanjing176 installs9 stars

Monitor OpenClaw gateway health and report incidents to Discord with read-only checks and cooldown dedupe.

by jonathanjing41 installs

Multi-stage deep intelligence pipeline (Search → Filter → Fetch → Synthesize). Turns a query into a structured research report with full source citations.

by jonathanjing27 installs

Route user-selected photos from Meta Ray-Ban glasses or another camera through a configured messaging ingress to an approved specialist and destination. Use only for explicit, opt-in photo routing with allowlisted destinations and confirmation before cross-session forwarding or persistent writes.

by jonathanjing39 installs1 stars

Audit a named ClawHub skill or skill URL before installation by combining OpenClaw verification with bounded static analysis. Use when the user explicitly asks whether a skill is safe or requests a pre-install review; report evidence and uncertainty instead of treating a score as proof.

by jonathanjing39 installs

Develop, test, or integrate the OpenClaw Tally Node.js library for task-level cost, complexity, and efficiency analytics. Use when working on Tally's detector, SQLite ledger, analytics engine, or an explicit plugin/hook integration; installing this skill alone does not register hooks or slash commands.

by jonathanjing27 installs