Monitoring Claude Pro Usage with a Bash Script

If you run Claude Code heavily, you've probably stared at the usage bar wondering how much of your 5-hour block is gone — and whether your extra credits are quietly draining. I built a small bash script to stop guessing and start logging.

The problem

Claude Pro has three usage dimensions worth tracking:

None of this is exposed in a machine-readable way by default. It turns out there is an undocumented OAuth endpoint that exposes exactly that data.

The endpoint

Claude Code stores an OAuth access token in ~/.claude/.credentials.json. The same token works against the usage API:

GET https://api.anthropic.com/api/oauth/usage
Authorization: Bearer <token>
anthropic-beta: oauth-2025-04-20

The response looks like this:

{
  "five_hour": { "utilization": 7.0, "resets_at": "..." },
  "seven_day": { "utilization": 19.0, "resets_at": "..." },
  "extra_usage": {
    "is_enabled": true,
    "monthly_limit": 1700,
    "used_credits": 190.0,
    "utilization": 11.18,
    "currency": "EUR"
  }
}

Note: monthly_limit and used_credits are in eurocents. Divide by 100 for the actual euro amounts.

The script

The script reads the token, hits the endpoint, optionally queries ccusage blocks for remaining block time, and appends a single JSON line to a log file — ready for Loki to scrape and Grafana to visualise.

#!/usr/bin/env bash
# Dependencies: jq, curl, ccusage (npm install -g ccusage)

LOGFILE="/var/log/ccusage.log"
CREDENTIALS_FILE="${HOME}/.claude/.credentials.json"
ANTHROPIC_USAGE_URL="https://api.anthropic.com/api/oauth/usage"

log() { echo "[$(date '+%d-%b-%Y %H:%M:%S')] $*" >&2; }

TOKEN=$(jq -r '.claudeAiOauth.accessToken // empty' "$CREDENTIALS_FILE" 2>/dev/null)
if [[ -z "$TOKEN" ]]; then
    log "No credentials available, aborting"
    exit 1
fi

USAGE=$(curl -s \
    -H "Authorization: Bearer $TOKEN" \
    -H "anthropic-beta: oauth-2025-04-20" \
    "$ANTHROPIC_USAGE_URL")

if ! echo "$USAGE" | jq -e '.five_hour' > /dev/null 2>&1; then
    log "Invalid API response"
    exit 1
fi

BLOK=$(echo "$USAGE"         | jq '(.five_hour.utilization   // 0) | round')
WEEK=$(echo "$USAGE"         | jq '(.seven_day.utilization   // 0) | round')
CREDITS_PCT=$(echo "$USAGE"  | jq '(.extra_usage.utilization // 0) * 100 | round / 100')
CREDITS_USED=$(echo "$USAGE" | jq '(.extra_usage.used_credits  // 0) / 100')
CREDITS_MAX=$(echo "$USAGE"  | jq '(.extra_usage.monthly_limit // 0) / 100')

REMAINING=$(ccusage blocks --json 2>/dev/null | jq '
    if (.blocks // []) | length > 0
       and (.blocks[-1].projection.remainingMinutes // null) != null
    then (.blocks[-1].projection.remainingMinutes / 60 * 10 | round / 10)
    else 0
    end' 2>/dev/null || echo 0)

printf '{"timestamp":"%s","blok_pct":%s,"week_pct":%s,"credits_pct":%s,"credits_used":%s,"credits_max":%s,"blok_remaining_hours":%s}\n' \
    "$(date -u '+%Y-%m-%dT%H:%M:%SZ')" \
    "$BLOK" "$WEEK" "$CREDITS_PCT" "$CREDITS_USED" "$CREDITS_MAX" "$REMAINING" \
    >> "$LOGFILE"

log "ccusage logged: block=${BLOK}% week=${WEEK}% credits=${CREDITS_PCT}%"

Install

Dependencies:

apt install jq curl
npm install -g ccusage

Deploy:

cp ccusage_log.sh /usr/local/sbin/ccusage_log
chmod +x /usr/local/sbin/ccusage_log

Cron — every 5 minutes:

*/5 * * * * /usr/local/sbin/ccusage_log

Output

Each run appends one line to /var/log/ccusage.log:

{"timestamp":"2026-05-23T19:26:17Z","blok_pct":7,"week_pct":19,"credits_pct":11.18,"credits_used":1.9,"credits_max":17,"blok_remaining_hours":0}

Point a Loki scrape job at that file and you have time-series data for all six metrics. Setting up Loki and Grafana for this is a topic for a separate post.

Notes


Written with assistance from Claude.


Want to reach out? Contact me.