Quick answer
Query the local SQLite database and write the result with SQLite's CSV mode. Export one row per assistant message with date, session, provider, model, input, cache read, cache write, output, and cost. Leave out prompts and file contents; they are not needed for a usage report.
A useful column set
| Column | Why | Sensitive |
|---|---|---|
| date | Trend and grouping | No |
| session_id | Session totals | No |
| provider | Cost split | No |
| model | Efficiency | No |
| tokens_input | Volume | No |
| tokens_output | Generation | No |
| cache_read / cache_write | Discount | No |
| cost | Spend | No |
Prompts, file paths, and tool output are the sensitive fields. A usage export does not need them.
Produce the CSV
sqlite3 -header -csv ~/.local/share/opencode/opencode.db \
"select date(created_at) as date, session_id, provider_id, model_id,
tokens_input, tokens_output, cost
from message order by created_at;" > opencode-usage.csvAdjust column names to your schema. Run .schema message first if the query fails.
Export the fields you need
Exports are for two audiences: yourself, doing a monthly review, and anyone asking what the tooling costs. Both need aggregates, not transcripts. Tokens, model, project, and date are enough; prompt text adds risk and no value.
- Query sessions and messages for the period you need.
- Group by day, model, and project.
- Write CSV with a header and an explicit unit column.
- State whether cost is reported or estimated.
- Keep the raw database out of the export.
UsageAtlas shows the same aggregates without a query, and the session history guide explains the underlying records.
Questions, answered
Does OpenCode have a built-in CSV export?
Not a general one. Use SQLite's CSV mode or a tracker's export.
Can I export cost per project?
Only if the session records a working directory you can join. Otherwise group by session.
Is it safe to share an OpenCode usage export?
Yes if it contains only aggregate token and cost fields. Never include prompts or file paths without review.