Skip to content

--api flag does not fetch/cache OAuth usage data despite valid credentials #228

Description

@tankz259

Summary

The --api flag (experimental Anthropic OAuth usage API, added for #202 in the v4.0.0 Usage-Ops release) does not fetch or cache anything, even when valid OAuth credentials are present. Output falls back silently to claude_code_jsonl local estimation with no indication the API call failed or was skipped.

Environment

  • claude-monitor version: 4.0.0 (installed via uv tool install claude-monitor, matches latest PyPI/GitHub release)
  • OS: macOS (Darwin 25.5.0, arm64)
  • Python: 3.11.9
  • Install method: uv tool install claude-monitor

Steps to reproduce

  1. Confirm OAuth credentials exist in macOS Keychain:

    security find-generic-password -s "Claude Code-credentials" -w

    Returns valid JSON with a claudeAiOauth.accessToken (sk-ant-oat01-...), consistent with an active Claude Code session on the same machine.

  2. Remove any stale API cache:

    rm -f ~/.claude-monitor/api/latest.json
  3. Run once with --api enabled and JSON output:

    claude-monitor --plan custom --custom-limit-tokens 1020000 --api --once --output json
  4. Inspect the source.kind and limits.five_hour.source.kind fields in the output.

Expected behavior

Per #202's design (and the --api flag's own --help description, "Enable the experimental Anthropic OAuth usage API"), this should call GET https://api.anthropic.com/api/oauth/usage using the Keychain-stored access token, and:

  • Populate ~/.claude-monitor/api/latest.json with a fresh response.
  • Set source.kind / limits.five_hour.source.kind to something indicating the API was used (e.g. anthropic_oauth_usage_api, matching the schema already used in a stale cache file from a prior/unknown successful run — see below).

Actual behavior

  • ~/.claude-monitor/api/latest.json is never created after deleting it and re-running with --api, in both --once --output json mode and live TUI mode (--refresh-rate 3, run for ~10s).
  • source.kind remains "claude_code_jsonl" and confidence remains "local_estimate" in every run, i.e. it always falls back to pure local estimation.
  • No error, warning, or log message is printed indicating the API call was attempted, skipped, or failed — the flag appears to have no observable effect on the five_hour limit in --once --output json output.
  • Note: a stale ~/.claude-monitor/api/latest.json did exist on this machine before I deleted it, with this shape:
    {"captured_at_epoch": 1783925313, "limits": {"five_hour": {"used_percentage": 27.0, "resets_at_epoch": 1783938000}, "seven_day": {"used_percentage": 23.0, "resets_at_epoch": 1784034000}, "captured_at_epoch": 1783925313, "stale": false, "source": {"kind": "anthropic_oauth_usage_api"}}}
    So the API path clearly works some of the time / under some condition — I just can't reproduce a fresh successful fetch on demand, and there's no visibility into why it isn't firing now.
  • Partial/confusing side effect: in the live TUI (not --once --output json), switching --plan between max20 and custom while --api was set changed the displayed "Cost Usage" cap ($100.27 → $140.00) and "Messages Usage" cap (928 → 2,000), suggesting some plan-tier metadata is being refreshed, but the "Token Usage" (five_hour) percentage never switched off the local token_limit constant in any configuration tested.

Suggested fix / ask

  • Surface a clear status/log line (even at default log level, or via --log-level debug) when --api is enabled indicating: attempting fetch → success/failure → reason (401, network error, rate-limited, credential file not found, etc).
  • Ensure ~/.claude-monitor/api/latest.json is written on every successful fetch, and confirm the fetch is actually attempted in both --once and live-refresh code paths.
  • Clarify in --help / docs whether --api currently only affects cost/message P90 caps (plan-tier metadata) versus the five_hour token utilization percentage itself — right now it's unclear which fields it's meant to override.

Debug log evidence

I re-ran with --log-level debug --log-file debug.log after deleting the cache. The resulting log has 72,877 lines, entirely from claude_monitor.core.data_processors (local JSONL token extraction). Searching the full log for any API/network-related activity:

grep -iE "anthropic_oauth|api_client|usage_api|urlopen|request" debug.log

returns zero matches for anything resembling an HTTP call, OAuth module, or usage-API code path — no attempt, no success, no failure, no rate-limit, nothing. This strongly suggests the API-fetch code isn't being invoked at all when --api is passed, at least not in --once --output json mode, rather than the fetch failing silently after being attempted.

Happy to provide the full debug log or test further if it helps narrow this down — let me know what additional info would be useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions