Events Export
llm-usage events streams the normalized usage events every report is built from — one record per model interaction, after source parsing, normalization, and pricing. It is the raw-data counterpart to the aggregated reports.
Command structure
Section titled “Command structure”llm-usage events [options]Examples:
llm-usage events > events.jsonlllm-usage events --format csv --since 2026-01-01 > events.csvllm-usage events --source codex --since 2026-06-01 | jq '.totalTokens'Options
Section titled “Options”--format <name>:jsonl(default) orcsv- shared filters apply:
--source,--provider,--model,--since,--until,--timezone, source-path overrides, pricing flags, and--history
events is an export stream, not a report: --json is rejected with --json is not supported for events; use --format jsonl, and --markdown/--share are not available. Diagnostics go to stderr as usual, so redirecting stdout produces a clean data file.
Export contract
Section titled “Export contract”- jsonl (default): one JSON object per line with the exact
UsageEventfield names; absent optionals (repoRoot,provider,model,costUsd) are omitted, notnull. Lines are not wrapped in the report envelope. Each line validates against events-line.v1.schema.json. - csv: a frozen header row with all 14 columns in declaration order (
source,sessionId,timestamp,repoRoot,provider,model,inputTokens,outputTokens,reasoningTokens,cacheReadTokens,cacheWriteTokens,totalTokens,costUsd,costMode), RFC 4180 quoting, empty string for absent optionals. New fields will only ever be appended as trailing columns. Cells that begin with a spreadsheet formula trigger (=,+,-,@, tab, carriage return) are prefixed with a single apostrophe to prevent formula execution, per OWASP CSV-injection guidance; use--format jsonlwhen you need raw values. - Ordering is deterministic:
timestamp, thensource, thensessionId, then original parse order.
{ "source": "codex", "sessionId": "486c3261-d87e-4971-8813-904c9e5a9009", "timestamp": "2026-06-15T12:00:00.000Z", "repoRoot": "/path/to/repo", "provider": "openai", "model": "gpt-5.2-codex", "inputTokens": 150, "outputTokens": 100, "reasoningTokens": 20, "cacheReadTokens": 50, "cacheWriteTokens": 0, "totalTokens": 300, "costUsd": 0.0017, "costMode": "estimated"}OTel mapping
Section titled “OTel mapping”No OpenTelemetry exporter is shipped or promised. The table documents how a consumer maps exported fields onto the OTel GenAI semantic conventions, so a future exporter (or your own pipeline) has a stable contract to build from:
| export field | OTel mapping |
|---|---|
model |
gen_ai.request.model |
provider |
gen_ai.provider.name |
inputTokens |
gen_ai.usage.input_tokens |
outputTokens |
gen_ai.usage.output_tokens |
cacheReadTokens |
gen_ai.usage.cache_read.input_tokens |
cacheWriteTokens |
gen_ai.usage.cache_creation.input_tokens |
reasoningTokens |
no stable semconv; suggested llm_usage.reasoning_tokens |
costUsd, costMode |
no semconv; suggested llm_usage.cost_usd, llm_usage.cost_mode |
source, sessionId, repoRoot, timestamp |
resource/span attributes (service.name-like source; session.id; VCS path; event time) |