The plugin reads a small UTF-8 JSON file. By default TrafficMonitor passes a plugin config directory, and the DLL uses:
<TrafficMonitor plugin config dir>\CodexUsage\codex_usage_status.json
Set CODEX_TRAFFICMONITOR_USAGE_JSON to force a different path. The bundled
collector writes the same file. Human-facing display fields such as message,
reset_display, and reset_credits_tooltip are localized according to the
plugin language setting; the sample below uses Chinese.
{
"schema_version": 1,
"status": "ok",
"message": "正常",
"generated_at_local": "2026-06-30T17:55:00+08:00",
"plan_type": "prolite",
"rate_limits_source": "logs_2.sqlite#43744767",
"rate_limits_age_seconds": 120,
"five_hour_display": "77%",
"five_hour_used_percent": 23,
"five_hour_remaining_percent": 77,
"weekly_display": "30%",
"weekly_used_percent": 70,
"weekly_remaining_percent": 30,
"reset_display": "5h 19:05 / 周 06-25 09:12",
"today_tokens": 272601267,
"today_tokens_display": "272.6M",
"today_token_mode": "account",
"today_token_source": "app-server:account/usage/read",
"today_token_rows": 1,
"today_token_bucket_date": "2026-06-30",
"today_input_tokens": null,
"today_input_tokens_display": "--",
"today_output_tokens": null,
"today_output_tokens_display": "--",
"today_cached_input_tokens": null,
"today_cached_input_tokens_display": "--",
"today_model_usage_source": "rollouts.token_count",
"today_model_usage_rows": 1,
"today_model_usage_threads": 2,
"today_model_usage": [
{
"model": "gpt-5.6-sol",
"input_tokens": 100000,
"cached_input_tokens": 80000,
"cache_write_input_tokens": 0,
"output_tokens": 10000,
"total_tokens": 110000,
"api_cost_usd": 0.276,
"api_cost_display": "$0.28",
"priced_tokens": 110000,
"unpriced_tokens": 0,
"pricing_status": "priced"
}
],
"today_model_usage_tooltip": "本机模型统计(今日)\r\n gpt-5.6-sol: 110K Token | $0.28\r\nAPI 等价成本(本机 JSONL): $0.28(定价覆盖率 100%)\r\n公开 Standard API 文本单价快照 2026-08-24;非 OpenAI 账单或订阅额度",
"today_api_cost_currency": "USD",
"today_api_cost_catalog_as_of": "2026-08-24",
"today_api_cost_usd": 0.276,
"today_api_cost_display": "$0.28",
"today_api_cost_priced_tokens": 110000,
"today_api_cost_unpriced_tokens": 0,
"today_api_cost_coverage_percent": 100,
"reset_credits_status": "ok",
"reset_credits_message": "正常",
"reset_credits_available_count": 2,
"reset_credits": [
{
"status": "available",
"title": "Full reset (Weekly + 5 hr)",
"granted_at": "2026-06-18 08:47",
"expires_at": "2026-07-18 08:47"
},
{
"status": "available",
"title": "Full reset (Weekly + 5 hr)",
"granted_at": "2026-06-24 10:37",
"expires_at": "2026-07-24 10:37"
}
],
"reset_credits_tooltip": "重置卡: 2 张可用\r\n 1. available | Full reset (Weekly + 5 hr)\r\n 获取 2026-06-18 08:47 过期 2026-07-18 08:47\r\n 2. available | Full reset (Weekly + 5 hr)\r\n 获取 2026-06-24 10:37 过期 2026-07-24 10:37\r\n"
}today_token_mode records the actual token display mode used for this snapshot.
The default account mode reads account/usage/read from
codex app-server --listen stdio:// and selects the matching daily bucket when
available, otherwise the latest returned bucket. today_token_bucket_date stores
that app-server bucket date. In account mode, the TrafficMonitor tooltip displays
today_tokens_display.
When the plugin setting token_usage_mode=local is selected, or when app-server
account usage is unavailable, the collector falls back to local rollout JSONL
token_count.info.total_token_usage. In local mode,
today_input_tokens*, today_output_tokens*, and
today_cached_input_tokens* are displayed in the TrafficMonitor tooltip, and
today_tokens* uses input + output for backward compatibility.
today_model_usage* is always a separate local-JSONL view, even when
today_token_mode remains account. For each state-database thread updated on
the local day, the collector streams its rollout JSONL, remembers the current
turn_context.model, and attributes the delta between cumulative token_count
records to that model. today_model_usage is the complete, descending-by-token
list; today_model_usage_rows is its model count and
today_model_usage_threads is the contributing-thread count. The DLL appends
the preformatted today_model_usage_tooltip, which is limited to its first five
models for a readable hover tooltip.
today_api_cost* is a Standard API text-token price estimate for that local
model list. The embedded catalog is a 2026-08-24 public-price snapshot in USD
per 1M tokens; the collector does not make a network request for pricing.
Uncached input is calculated as input - cached input - cache write, and
reasoning is already included in output rather than charged a second time. The
current catalog contains GPT-5.6 Sol, Terra, Luna, GPT-5.5, GPT-5.4,
GPT-5.4 mini, GPT-5.3-Codex, and GPT-5.2-Codex. Cache-write tokens receive a
price only where the corresponding public model page documents one. Unknown
models, invalid category relationships, and missing cache-write prices are not
silently priced as zero: they are counted by today_api_cost_unpriced_tokens
and reduce today_api_cost_coverage_percent. These fields are neither an
OpenAI bill nor a ChatGPT/Codex subscription quota.
Rate limits are preferably read from codex app-server --listen stdio:// via
account/rateLimits/read, using rateLimitsByLimitId["codex"] as the main
Codex quota. primary.usedPercent is treated as the 5-hour quota usage and
secondary.usedPercent as weekly quota usage only for older data without window
metadata. Current app-server windows are classified from windowDurationMins:
300 minutes is the 5-hour quota and 10080 minutes is the weekly quota. This also
handles a lone 7-day primary window when the 5-hour limit is unavailable.
Display fields show remaining percentage, so app-server usedPercent is
converted to 100 - usedPercent before writing this snapshot. If app-server is
unavailable, the collector falls back to Codex session JSONL rate_limits and
then legacy codex.rate_limits logs. Session JSONL payloads may expose
remaining_percent; if they only expose used_percent, the collector converts
that value to remaining percentage before writing this snapshot. Both used and
remaining numeric fields are preserved for compatibility.
When the newest rate-limit event is older than 6 hours, the collector marks the
snapshot as stale and appends a localized stale suffix to quota display text
(旧 in Chinese, stale in English). The reset display still shows the last
recorded reset timestamps, prefixed with localized stale text, for example
旧: 5h 06-23 19:05 / 周 06-25 09:12 or
Stale: 5h 06-23 19:05 / wk 06-25 09:12.
rate_limits_recorded_at_local is the ISO timestamp of the selected quota
record, or null when no record exists. It is separate from the collection time
in generated_at_local; re-reading an old local record does not make it fresh.
app_server_rate_limits and app_server_token_usage independently describe
each live query. status is ok, error, or skipped. Attempted queries include
attempted_at_local, and a resolved binary adds binary_source (override,
path, or desktop) and binary_path. Errors include a fixed localized
message and error_code: not_found, invalid_override, launch_failed,
timeout, api_error, or invalid_response. Numeric system_error_code or
rpc_error_code is included when available. Raw exception/RPC messages and
response bodies are never copied into diagnostics. Skips carry a reason:
disabled, custom_codex_home, or local_mode; intentional skips are not failures.
collection_diagnostics_tooltip contains localized query-failure warnings and,
when using a local quota record, its original timestamp. The DLL displays these
warnings even if the fallback is recent. A failed live query changes an otherwise
ok snapshot to partial; already stale snapshots keep that status. The
existing message field also includes the warnings for older consumers.
Structured query diagnostics are appended to the log passed as --log-path,
defaulting to codex_usage_plugin.log alongside the output JSON.
reset_credits* fields come from %USERPROFILE%\.codex\auth.json
tokens.access_token plus the ChatGPT reset-credit endpoint. They are omitted
from the tooltip when auth is missing, credentials are unauthorized, or the
request fails. The snapshot only stores the sanitized available_count and each
credit's status, title, granted_at, and expires_at; token values,
cookies, and credit IDs are never written. granted_at and expires_at are
display strings converted from UTC into the current computer timezone.
The plugin can disable reset-credit collection through reset_credits_enabled=0
in codex_usage_plugin.ini. When disabled, the collector writes stable empty
reset_credits* fields with reset_credits_status set to disabled and does
not read auth.json. When enabled, the collector may reuse a sanitized local
cache for about one hour; the cache stores only language-neutral safe fields and
the tooltip is rebuilt for the current UI language.