Skip to content

moshi-hook 0.1.6 returns stale capturedAt — Anthropic /api/oauth/usage requires new anthropic-beta header #1

Description

@appvoraFR

Symptom

The Moshi mobile app's "Utilisation" tab shows Claude Max usage data that hasn't updated for 18+ hours, even though the daemon reports usage poller: synced count=1 every poll cycle and Claude Code is being actively used.

moshi-hook usage consistently returns the same capturedAt timestamp from a previous successful poll, regardless of how recently the daemon ran.

Reproduction

$ moshi-hook version
moshi-hook 0.1.6

$ moshi-hook usage
[
  {
    "accountId": "claude:73dd89e1aa7c",
    "accountLabel": "Max 5x",
    "agent": "claude-code",
    "hostName": "ov-214601",
    "capturedAt": "2026-05-03T15:01:43.006526991+02:00",
    "windows": [
      { "label": "5h", "usedPercentage": 0, "resetsAt": "2026-05-04T07:10:00Z" },
      { "label": "7d", "usedPercentage": 8, "resetsAt": "2026-05-10T06:00:00Z" }
    ]
  }
]

capturedAt is from May 3, 15:01 — never refreshes despite the daemon running and the OAuth token being valid (Claude Code itself works fine).

Root cause

Anthropic's /api/oauth/usage endpoint now requires the beta header anthropic-beta: oauth-2025-04-20. Without it, the endpoint returns 401:

$ TOKEN="$(jq -r .claudeAiOauth.accessToken ~/.claude/.credentials.json)"

# Without the beta header → 401:
$ curl -i -H "Authorization: Bearer $TOKEN" https://api.anthropic.com/api/oauth/usage
HTTP/1.1 401 Unauthorized
{"type":"error","error":{"type":"authentication_error",
 "message":"OAuth authentication is currently not supported."}}

# With anthropic-beta: oauth-2025-04-20 → 200:
$ curl -H "Authorization: Bearer $TOKEN"        -H "anthropic-beta: oauth-2025-04-20"        https://api.anthropic.com/api/oauth/usage
{
  "five_hour":  {"utilization": 8.0,  "resets_at": "2026-05-04T09:49:59.888578+00:00"},
  "seven_day":  {"utilization": 15.0, "resets_at": "2026-05-10T06:00:00.888597+00:00"},
  "seven_day_oauth_apps": null,
  "seven_day_opus": null,
  "seven_day_sonnet":  {"utilization": 0.0, "resets_at": null},
  "seven_day_omelette":{"utilization": 0.0, "resets_at": null},
  ...
}

So moshi-hook likely calls /api/oauth/usage with a different (older?) anthropic-beta value, gets a silent 401, then falls back to the last successfully cached snapshot.

Suggested fix

Update the anthropic-beta request header used in internal/usage/claude_poll.go (or wherever the OAuth usage call lives) to include oauth-2025-04-20.

If multiple beta features are needed, the API accepts a comma-separated list, e.g. anthropic-beta: oauth-2025-04-20,<other>.

It would also be helpful if a 401 from this endpoint either:

  • logged a clear error at WARN/ERROR (currently the daemon log just says usage poller: synced count=1), or
  • bumped capturedAt to the actual poll time so the UI surfaces "stale data, last successful sync at X".

Environment

  • moshi-hook 0.1.6 (Linux x86_64, installed from https://cdn.getmoshi.app/hook/v0.1.6/moshi-hook_Linux_x86_64.tar.gz, sha256 verified)
  • Claude Code 2.1.126
  • Linux 6.12.85+deb13-amd64
  • Account plan: Max 5x

Workaround

None local — the anthropic-beta header is hard-coded in the binary. Either patch the binary or wait for an upstream release.

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