Data & storage
Exports#
The store is yours. Several ways to get data out of it, in rough order of how often people want them.
The query API#
The most flexible route, and the one to reach for first. Every shape returns JSON you can pipe.
# every session in a window, as newline-delimited JSON
curl -s localhost:8900/api/local/query -X POST \
-H 'content-type: application/json' \
-d '{"shape":"sessions","args":{"since":"2026-08-01T00:00:00Z","limit":2000}}' \
| jq -c '.rows[]' > sessions.ndjson
# per-day cost as CSV
curl -s localhost:8900/api/local/aggregates \
| jq -r '.rows[] | [.day, .total_tokens, .cost_usd] | @csv' > cost.csvSession and trace exports#
curl -s 'localhost:8900/api/export/traces' | jq
curl -s 'localhost:8900/api/export/events' | jqThe Conversations tab also exports an individual session — its transcript, tool timeline and cost breakdown — for sharing or archiving.
The reports browser#
Drop a Markdown file in ~/.clawmetry/reports/ and it becomes a page, with SQL
results rendered inline and a CSV download.
clawmetry reports
curl -s localhost:8900/api/reports | jq
curl -s localhost:8900/reports/<slug>/export.csvThis is the right answer for a recurring question that is not worth a dashboard tab. Write the query once, and it is a page with a CSV link forever.
Push to your observability stack#
Rather than pulling, push. ClawMetry can export its own metrics over OTLP:
export CLAWMETRY_OTEL_EXPORT_ENDPOINT=https://otlp.example.com/v1/metrics
export CLAWMETRY_OTEL_EXPORT_HEADERS='{"x-api-key":"…"}'
export CLAWMETRY_OTEL_EXPORT_INTERVAL=60curl -s localhost:8900/api/otel/export | jq
curl -s localhost:8900/api/otel-status | jqAgent cost and activity then sit next to the rest of your infrastructure telemetry, in whatever you already use. → OpenTelemetry
Tier: otel_export is a Pro feature.
SIEM export#
For security tooling, a stream shaped for a SIEM rather than a metrics backend.
| Variable | Effect |
|---|---|
CLAWMETRY_SIEM_HOST | Destination host |
Tier: siem_export is Enterprise.
Microsoft Sentinel#
With the Pro extension 0.7.28 or later, the sync daemon can also write governance records straight into a Microsoft Sentinel workspace through the Azure Monitor Logs Ingestion API, with no syslog forwarder in between. It runs beside the syslog exporter above; use either or both.
Everything arrives in one custom table, ClawMetryGovernance_CL, one row per
record:
| RecordType | What it is | Sent |
|---|---|---|
GuardIncident | a Guard detector finding | once per occurrence, again if its severity changes |
GateDecision | a pre-tool gate approval that was decided | once, when decided |
PolicyDecision | a Guard policy decision, enforced or dry run | once per ladder rung |
AuditLog | an entry in the audit log | once per entry |
ConnectionCheck | the setup check below | on demand |
Free text (Summary, Detail, Target, Properties) passes through the same
secret redaction as every other export before it leaves the node.
FrameworkIds lists the Compliance Pack controls a record is evidence for, as
framework:control. It supports an assessment; it is not a certification.
Policy decisions map to no control yet and carry an empty list, and the OWASP
and MITRE ATLAS references on Guard findings are not copied into these records.
Setup, in outline.
- Register an application in Microsoft Entra ID and create a client secret.
- Create the table and a direct-ingestion data collection rule whose stream has the connector's columns, and give the application the Monitoring Metrics Publisher role on that rule. The Azure Resource Manager template for this is not part of the installed package; ask enterprise@clawmetry.com for it.
- Set these for the sync daemon, then restart it.
| Variable | Effect |
|---|---|
CLAWMETRY_SENTINEL_ENDPOINT | Logs ingestion endpoint of the rule, or of your data collection endpoint |
CLAWMETRY_SENTINEL_DCR_ID | Immutable ID of the data collection rule, dcr-… |
CLAWMETRY_SENTINEL_STREAM | Optional, default Custom-ClawMetryGovernance |
CLAWMETRY_SENTINEL_TENANT_ID | Directory (tenant) ID; AZURE_TENANT_ID also works |
CLAWMETRY_SENTINEL_CLIENT_ID | Application (client) ID; AZURE_CLIENT_ID also works |
CLAWMETRY_SENTINEL_CLIENT_SECRET | Client secret; AZURE_CLIENT_SECRET also works |
CLAWMETRY_SENTINEL_CLOUD | Optional: public (default), usgov or china |
CLAWMETRY_SENTINEL_INTERVAL_SECS | Optional, default 60, minimum 10 |
CLAWMETRY_SENTINEL_BACKFILL_HOURS | Optional, history sent on first start, default 24 |
Endpoints must be HTTPS; the connector refuses to send credentials over plain HTTP. Check the setup before relying on it:
python -m clawmetry_pro.lib.sentinel checkIt sends one ConnectionCheck record and prints OK or the reason Azure gave.
Delivery. Records go up in gzip-compressed batches under the API's 1 MB
call limit. On HTTP 429 the connector waits for Retry-After; on any failure
records stay queued. Delivery positions are kept in
~/.clawmetry/sentinel_state.json, so a restart neither loses records nor
resends accepted ones. A record Azure rejects as malformed on its own is
dropped and logged. The client secret and access token are never logged.
Limits. The connector has not yet been run against a live Azure tenant by us. No Sentinel content hub solution is published.
Tier: Enterprise. The connector starts only when the node's entitlement
allows siem_export.
Copying the store itself#
For a full backup, copy the DuckDB file — but stop the daemon first, or you may capture an inconsistent state.
clawmetry sync --restart
cp ~/.clawmetry/local_store.duckdb ~/backups/clawmetry-$(date +%F).duckdbYou can then open it with any DuckDB client:
duckdb ~/backups/clawmetry-2026-09-05.duckdb -c "SELECT count(*) FROM events"Exports contain your transcripts
Session content includes whatever your agents read and wrote, which can include secrets that ended up in a tool result. Treat an export with the same care as the sessions themselves, and see Hardening for redaction options.
Before uninstalling#
clawmetry uninstall removes the store. Export anything you want to keep first
— the rollups in particular, since they hold long-term cost history that
survived your retention window.
curl -s localhost:8900/api/local/runtimes | jq '.rows' > runtime-history.json
curl -s localhost:8900/api/local/models | jq '.rows' > model-history.json
curl -s localhost:8900/api/local/aggregates | jq '.rows' > daily-history.json