Skip to main content

Configuration reference

OpenUsage stores its configuration in a single JSON file at:

  • macOS / Linux — ~/.config/openusage/settings.json
  • Windows — %APPDATA%\openusage\settings.json

The TUI reads the file on startup and writes it back when you change settings interactively. You can also edit the file directly — changes take effect on the next refresh (r) or restart.

Top-level keys

KeyTypePurpose
auto_detectboolToggle automatic detection of installed tools and API keys.
themestringName of the active theme.
uiobjectRefresh interval and gauge thresholds.
dataobjectTime window default and retention.
telemetryobjectDaemon-related settings.
dashboardobjectProvider list, view, and widget sections.
experimentalobjectOpt-in screens.
model_normalizationobjectGroup raw model ids by canonical lineage.
integrationsobjectInstall state for tool hooks.
accountsarrayManually configured provider accounts.
auto_detected_accountsarrayRead-only mirror of accounts found by the detector.

auto_detect

Whether to auto-detect installed AI tools (Cursor, Claude Code, Codex, Copilot, Gemini CLI, Aider, Ollama) and API keys from the environment.

{ "auto_detect": true }

Default: true. When false, only accounts is used.

theme

The active theme by name. Must match a built-in or external theme. See Themes.

{ "theme": "Tokyo Night" }

Default: "Gruvbox".

ui

{
"ui": {
"refresh_interval_seconds": 30,
"warn_threshold": 0.20,
"crit_threshold": 0.05
}
}
FieldTypeDefaultPurpose
refresh_interval_secondsint30How often the TUI re-fetches the read model from the daemon.
warn_thresholdfloat0.20Gauge turns yellow when remaining ratio drops below this.
crit_thresholdfloat0.05Gauge turns red below this.

Thresholds are remaining-ratio fractions, so 0.20 means "yellow when less than 20% remains."

data

{
"data": {
"time_window": "30d",
"retention_days": 30
}
}
FieldTypeDefaultPurpose
time_windowstring"30d"Default time window. One of 1d, 3d, 7d, 30d, all.
retention_daysint30Days of history to keep in the daemon's SQLite store. Older rows are pruned. Hard-capped at 90 — values above 90 are silently clamped at startup.

telemetry

{
"telemetry": {
"provider_links": {
"anthropic": "claude_code",
"google": "gemini_api",
"github-copilot": "copilot"
}
}
}
FieldTypePurpose
provider_linksmap<string,string>Map telemetry source strings to display provider IDs. Defaults shown above.

Edit interactively via the Telemetry settings tab (, then 6).

dashboard

{
"dashboard": {
"view": "grid",
"hide_sections_with_no_data": false,
"providers": [
{ "account_id": "openai-personal", "enabled": true },
{ "account_id": "anthropic-work", "enabled": true }
],
"widget_sections": [
{ "id": "top_usage_progress", "enabled": true },
{ "id": "model_burn", "enabled": true }
]
}
}

dashboard.view

ValueLayout
gridDefault — adaptive multi-column grid.
stackedSingle full-width column.
tabsFocused pane plus a tab strip.
splitTile list left / detail right.
compareTwo adjacent provider panes.

A viewport too narrow for the chosen view is auto-fallen-back to stacked.

dashboard.providers

Ordered list of accounts to render in the dashboard. Order in the array is the display order.

FieldTypePurpose
account_idstringMust match an id from accounts or auto_detected_accounts.
enabledboolShow the tile or hide it.
hide_costsnullable boolPer-account override for monetary visibility. See dashboard.hide_costs. Omitted / null falls through to the top-level setting; true force-hides costs for this account; false force-shows them.

dashboard.hide_costs

TypeDefaultPurpose
nullable boolomittedGlobal default for whether monetary metrics (cost, spend, dollars) render in tiles and detail. Omitted / null means "automatic, plan-aware"; true force-hides everywhere; false force-shows everywhere.

Resolution order, highest precedence first:

  1. dashboard.providers[].hide_costs (per-account override)
  2. dashboard.hide_costs (top-level override)
  3. Automatic, plan-aware policy

The automatic policy hides costs on fixed-rate subscription plans (Claude Code with an active subscription, Codex on Plus / Team / Enterprise, GitHub Copilot on any plan, Z.AI on glm_coding_plan*) where dollar figures would be misleading, and shows costs everywhere else.

You can also toggle the per-account override live from the dashboard with c — it cycles auto → hide → show → auto for the focused tile and persists the choice here.

dashboard.hide_sections_with_no_data

TypeDefaultPurpose
boolfalseWhen true, any widget section that produces no rows for the active provider is hidden instead of rendered as an empty card.

dashboard.widget_sections

Ordered list of widget sections shown on dashboard tiles. See Widgets.

FieldTypePurpose
idstringSection ID (provider-defined).
enabledboolRender or hide globally.

dashboard.detail_sections

Same shape as widget_sections, but applied to the detail (full-page) view rather than the tile view. Use this to control which widget sections appear when you press Enter on a tile.

FieldTypePurpose
idstringSection ID (provider-defined).
enabledboolRender or hide on the detail view.

experimental

{
"experimental": {
"analytics": true
}
}
FieldTypeDefaultPurpose
analyticsboolfalseEnables the Analytics screen (Tab from dashboard).

model_normalization

Groups raw model strings (gpt-4o-2024-08-06, gpt-4o, chatgpt-4o-latest) under a single canonical lineage so charts and breakdowns aggregate cleanly.

{
"model_normalization": {
"enabled": true,
"group_by": "lineage",
"min_confidence": 0.80,
"overrides": [
{
"provider": "cursor",
"raw_model_id": "claude-4.6-opus-high-thinking",
"canonical_lineage_id": "anthropic/claude-opus-4.6"
}
]
}
}
FieldTypeDefaultPurpose
enabledbooltrueMaster switch.
group_bystring"lineage"Currently only lineage is supported.
min_confidencefloat0.80Heuristic confidence threshold for automatic grouping.
overridesarray[]Manual mappings that bypass the heuristic.

Each override:

FieldPurpose
providerProvider id the raw model belongs to.
raw_model_idRaw string from the provider's API.
canonical_lineage_idCanonical lineage to map it to (e.g. anthropic/claude-opus-4.6).

integrations

Install state for tool hook integrations. Managed by openusage integrations — usually you don't edit this by hand.

{
"integrations": {
"claude_code": {
"installed": true,
"version": "1.0.0",
"installed_at": "2025-01-15T10:30:00Z"
},
"cursor-rules": {
"installed": false,
"declined": true
}
}
}
FieldTypePurpose
installedboolTrue when the integration is currently active.
versionstringVersion of the installed template.
installed_atRFC3339Timestamp of last install.
declinedboolIf true, the install prompt is suppressed.

accounts

Manually configured provider accounts. Account id must be unique across accounts and auto_detected_accounts.

{
"accounts": [
{
"id": "openai-personal",
"provider": "openai",
"api_key_env": "OPENAI_API_KEY",
"probe_model": "gpt-4.1-mini"
},
{
"id": "anthropic-work",
"provider": "anthropic",
"api_key_env": "ANTHROPIC_API_KEY"
},
{
"id": "moonshot-cn",
"provider": "moonshot",
"api_key_env": "MOONSHOT_API_KEY",
"base_url": "https://api.moonshot.cn"
},
{
"id": "ollama-cloud",
"provider": "ollama",
"auth": "api_key",
"base_url": "https://ollama.com",
"api_key_env": "OLLAMA_API_KEY"
},
{
"id": "copilot",
"provider": "copilot",
"binary": "gh"
}
]
}

Account fields

FieldTypePurpose
idstringStable unique identifier. Used in dashboard.providers and account-id tags.
providerstringProvider plugin id (e.g. openai, anthropic, cursor, claude_code).
api_key_envstringName of the env var that holds the API key. The key is never persisted — only the var name is.
authstringOptional auth mode override (api_key, oauth, etc., where supported).
base_urlstringOverride the provider's base URL. Common for self-hosted Ollama or alternate Moonshot endpoints.
binarystringFor non-API providers, the path or name of the local binary or file (e.g. gh for Copilot, the Gemini CLI binary, the Claude state file path).
probe_modelstringFor header-probing providers, the model to send a minimal request against.

:::warning API keys are never stored The api_key_env field stores the name of the environment variable, not its value. The TUI reads the value from your shell at runtime. Don't put plaintext API keys in settings.json. :::

auto_detected_accounts

Read-only mirror of accounts the detector found at startup. Format is identical to accounts. When the same id appears in both, the manually configured entry wins.

Full annotated example

{
"auto_detect": true,
"theme": "Gruvbox",
"ui": {
"refresh_interval_seconds": 30,
"warn_threshold": 0.20,
"crit_threshold": 0.05
},
"data": {
"time_window": "7d",
"retention_days": 30
},
"telemetry": {
"provider_links": {
"anthropic": "claude_code",
"google": "gemini_api",
"github-copilot": "copilot"
}
},
"experimental": {
"analytics": false
},
"model_normalization": {
"enabled": true,
"group_by": "lineage",
"min_confidence": 0.80,
"overrides": []
},
"dashboard": {
"view": "grid",
"hide_costs": null,
"providers": [
{ "account_id": "openai-personal", "enabled": true },
{ "account_id": "anthropic-work", "enabled": true, "hide_costs": true },
{ "account_id": "openrouter", "enabled": false }
],
"widget_sections": [
{ "id": "top_usage_progress", "enabled": true },
{ "id": "model_burn", "enabled": true },
{ "id": "client_burn", "enabled": true },
{ "id": "other_data", "enabled": true },
{ "id": "daily_usage", "enabled": false }
]
},
"integrations": {
"claude_code": {
"installed": true,
"version": "1.0.0",
"installed_at": "2025-01-15T10:30:00Z"
}
},
"accounts": [
{
"id": "openai-personal",
"provider": "openai",
"api_key_env": "OPENAI_API_KEY",
"probe_model": "gpt-4.1-mini"
},
{
"id": "anthropic-work",
"provider": "anthropic",
"api_key_env": "ANTHROPIC_API_KEY"
}
],
"auto_detected_accounts": []
}

See also