macOS native floating widget that shows your Claude.ai usage in real-time. Built in SwiftUI. Liquid glass design. Manual-refresh, rate-limit-aware.
Endpoint: GET https://claude.ai/api/organizations/{orgId}/usage
Auth: Full browser cookie string (no OAuth, just Cookie: header)
{
"five_hour": {
"utilization": 43.0, // % of 5-hour session used (0–100)
"resets_at": "2026-03-23T13:30:00Z"
},
"seven_day": {
"utilization": 28.5, // % of 7-day plan limit used
"resets_at": "2026-03-27T00:00:00Z"
},
"seven_day_sonnet": { // Pro plan only — absent on free tier
"utilization": 14.2,
"resets_at": "2026-03-27T00:00:00Z"
}
}Bootstrap endpoint: GET https://claude.ai/api/bootstrap
- Returns
account.lastActiveOrgIdif we can't parse it from the cookie.
| Field | Why it matters |
|---|---|
five_hour.utilization |
Most important — am I near a rate-limit right now? |
five_hour.resets_at |
Countdown timer — when can I hammer it again? |
seven_day.utilization |
Weekly burn rate — am I blowing through my plan? |
seven_day.resets_at |
Days until weekly reset |
seven_day_sonnet.utilization |
Pro users: Sonnet-specific limit |
- Per-conversation token counts (not exposed)
- Model breakdown beyond Sonnet (e.g., Opus vs Haiku)
- Historical usage data (API only returns current windows)
- Daily breakdown (only 5h and 7d windows)
Claude.ai does NOT publish rate limits for this internal API endpoint.
The ClaudeUsageBar reference app uses a 5-minute polling interval — we're going stricter.
| Trigger | Action |
|---|---|
| App opens | Fetch immediately |
| Manual refresh button tap | Fetch immediately |
| Trackpad swipe-down gesture | Fetch (touch-friendly) |
Keyboard shortcut ⌘R |
Fetch |
| Background timer | Every 15 minutes (conservative) |
| Data age indicator | Show "Updated 3m ago" so user knows staleness |
Why not constant polling?
- The endpoint is internal/undocumented — aggressive polling risks rate-limiting or cookie invalidation
- Usage windows (5h, 7d) don't change second-by-second
- Manual control respects the API and keeps it responsive
Why 15-minute background refresh vs 5-minute?
- 5h window changes meaningfully every 10–15 min of heavy use
- 7d window barely moves in 15 minutes
- Battery + network friendliness
Three concentric ring gauges — 5h outer, 7d middle, Sonnet inner. Big percentage hero center. Dynamic accent glow shifts green→red. Best for: People who love data density, ring chart fans.
Finance dashboard aesthetic. Hero number (5h %) left, arc gauge right. Three metric pill cards below. Best for: Glanceable at a distance, "Bloomberg terminal" energy.
Apple's new iOS 26 / visionOS material. True OS-level blur (NSVisualEffectView). Floating glass pills. Minimal info, maximum beauty. Best for: Desktop aesthetics, clean setups, translucent over wallpaper.
Dark with vivid neon speedometer arc. Green→yellow→red progression. High drama, perfect for noticing when you're burning through usage. Best for: Gamers, terminal nerds, high-contrast lovers.
Evolution of the Claude2x widget. Keeps the timeline bar you already love. Adds live usage rings beneath. Week calendar at bottom. Best for: Existing Claude2x users — familiar layout, more data.
ClaudeUsageWidget/
├── ClaudeUsageWidgetApp.swift ← @main entry
├── AppDelegate.swift ← Floating window config
├── Models/
│ └── UsageModel.swift ← UsageData, UsageWindow, UsageLevel
├── Services/
│ └── APIService.swift ← Fetches /usage endpoint + bootstrap
├── Views/
│ ├── ShowcaseView.swift ← 5-style comparison picker window
│ ├── Components/
│ │ ├── GlassCard.swift ← LiquidGlass modifier, backgrounds, helpers
│ │ └── CircularGauge.swift ← RingGauge, ArcGauge, UsageBar
│ └── Styles/
│ ├── Style1_OrbitalRings.swift
│ ├── Style2_CommandCenter.swift
│ ├── Style3_LiquidGlass.swift
│ ├── Style4_NeonArc.swift
│ └── Style5_TimelineUsage.swift
- Open Xcode → File › New › Project
- Platform: macOS, Template: App
- Name:
ClaudeUsageWidget, Language: Swift, Interface: SwiftUI - Uncheck "Include Tests"
- Save to:
~/Documents/Projects/claude-usage/ - Delete the default
ContentView.swiftandClaudeUsageWidgetApp.swift - Drag in all the files from
ClaudeUsageWidget/(preserve folder structure) - In project settings → Signing: set your Team
- Add
NSAppTransportSecuritytoInfo.plistif needed for HTTP (not needed — claude.ai is HTTPS) - Build & Run → the showcase window opens
Once you choose the style you like:
- Fine-tune layout, sizing, padding
- Add Settings popover (paste cookie, adjust refresh interval)
- Add menu bar icon option (tiny usage % in menu bar)
- Local history tracking (store last 7 days of API snapshots in UserDefaults)
- History mini-chart (area chart of 5h usage over time)
- Notifications: alert when 5h usage > 80%
- Launch at login support
- Option to run as menu bar item only (no floating window)
- Dropdown popover shows the chosen widget style
- Keyboard shortcut to show/hide
- If
seven_day_sonnetpresent: show Pro badge - Separate ring for Opus vs Sonnet (if API ever exposes it)
Beyond the refresh button, you can add:
| Interaction | Implementation |
|---|---|
| Swipe down on widget | DragGesture with .onEnded { if offset > 40 { refresh() } } |
| Double tap | .onTapGesture(count: 2) { refresh() } |
| Shake (trackpad Force Touch) | NSEvent pressure detection |
| Menu bar click | Clicking menu bar icon always refreshes |
| ⌘R keyboard shortcut | .keyboardShortcut("r", modifiers: .command) |
| Long press | .onLongPressGesture(minimumDuration: 0.5) { refresh() } |
Recommended for v1: Refresh button + double-tap + ⌘R.
The cookie string from .env includes:
sessionKey— the primary auth tokenlastActiveOrg— org UUID (org-bound API calls)cf_clearance— Cloudflare verification (expires every ~24h!)__cf_bm— Cloudflare bot management (short-lived)
The cf_clearance cookie WILL expire — the app will show an error.
The user must paste a fresh cookie from their browser.
Future improvement: A "Cookie expired" banner with a one-click workflow to open claude.ai and paste the new cookie.
| Token | Hex | Usage |
|---|---|---|
| Claude Orange | #C96442 |
Brand, today dot, accents |
| Claude Dark | #0F0D0B |
App background |
| Claude Card | #1A1714 |
Card fills |
| Healthy | #22C55E |
Low usage |
| Moderate | #F59E0B |
50–75% usage |
| High | #F97316 |
75–90% usage |
| Critical | #EF4444 |
>90% usage |
| Sky Blue | #38BDF8 |
7-day ring |
| Violet | #A78BFA |
Sonnet ring |
- Display numbers:
.system(size: X, weight: .black, design: .rounded) - Labels:
.system(size: X, weight: .black, design: .rounded)+ kerning - Timestamps/sub:
.system(size: X, weight: .medium, design: .monospaced)
NSVisualEffectView(.hudWindow, .behindWindow)— true OS blurColor.white.opacity(0.06)— frosted tint- Top gradient:
white 14% → white 4% → clear - Bottom gradient:
clear → black 18% - Border:
LinearGradientfromwhite 28%(top-leading) towhite 5%(bottom-trailing), 0.9pt
- API response structure documented
- APIService (fetch + parse + bootstrap)
- UsageModel (data types + levels)
- Component library (GlassCard, CircularGauge, AnimatedBackground)
- Style 1: Orbital Rings
- Style 2: Command Center
- Style 3: Liquid Glass
- Style 4: Neon Arc
- Style 5: Timeline + Usage
- ShowcaseView (comparison picker)
- AppDelegate (floating window)
- Create Xcode project + add files
- Pick winner style
- Build the final polished widget
Last updated: 2026-03-23