Expand description
A typed async client for the Claude account endpoints an OAuth login can call: usage, profile, token validation, roles, prepaid credits and the overage limit, and the refresh-token grant.
Everything is read-only. Nothing here spends money, changes a setting
or mints a key; the only POSTs are the token check
(Client::validate) and the refresh grant (Client::refresh).
This crate is not affiliated with or endorsed by Anthropic. The
endpoints are undocumented: they are the ones Claude Code itself calls.
Their shapes can change without notice, so nearly every field is an
Option that reads as None when it is missing or of an unexpected
type, and each type keeps whatever else the response carried in its
extra map.
Client: one method per endpoint. It holds no token: each call takes the one it acts with.Secret: a token. It never prints and its own buffer is zeroed on drop (copies made along the way may not be: seeSecret).Error:Error::Unauthorized(re-login),Error::Forbidden(a good token without the scope or role),Error::RateLimited(withRetry-After),Error::Http,Error::Decode(with a scrubbed body snippet), and the rest.
§Read usage
Add ccwire-oauth = "0.1" and Tokio to your application. Obtain an
access token through an existing Claude OAuth login; this crate does
not perform browser login or persist credentials.
use ccwire_oauth::{Client, Secret};
let token = Secret::new(std::env::var("CLAUDE_ACCESS_TOKEN")?);
let usage = Client::new()?.usage(&token).await?;
if let Some(window) = usage.five_hour {
println!("utilization: {:?}%", window.utilization);
}§Refresh and inspect a profile
use ccwire_oauth::{Client, RefreshRequest, Secret};
let client = Client::new()?;
let stored = Secret::new("stored-refresh-token");
// Don't cancel a refresh once it's sent (see `Client::refresh`).
let tokens = client.refresh(&RefreshRequest::new(stored)).await?;
// Store tokens.refresh_token only if the stored one is still the one
// posted (compare-and-swap); it has been spent either way.
let profile = client.profile(&tokens.access_token).await?;
if let Some(org) = &profile.organization {
let limit = client.overage_spend_limit(&tokens.access_token, &org.uuid).await?;
println!("{:?} {:?}", limit.is_enabled, limit.used_credits);
}§License
Licensed under the Apache License, Version 2.0 (LICENSE).
Structs§
- Account
- The user behind a token.
- Auto
Reload - Prepaid auto-reload, read-only.
- Client
- A client for the account endpoints.
- Client
Builder - Builds a
Client. - Extra
Usage - Extra usage: credits spent past the plan’s limits this month.
- Limit
- One row of
Usage::limits. - Limit
Model - The model of a per-model
Limit. - Limit
Scope - What a scoped
Limitcovers. - Organization
- The organization a token acts for.
- Overage
Spend Limit GET /api/oauth/organizations/{org}/overage_spend_limit: the extra usage (overage) monthly limit.- Prepaid
Credits GET /api/oauth/organizations/{org}/prepaid/credits: the prepaid balance.- Profile
GET /api/oauth/profile: the account and its organization.- Refresh
Request - What to refresh: a refresh token, plus the client and scopes to post with it.
- Roles
GET /api/oauth/claude_cli/roles: the user’s roles in the token’s organization.- Secret
- An access or refresh token.
- Token
Set - A refreshed login: what to store in place of the old tokens.
- Usage
GET /api/oauth/usage: the subscription’s rate-limit windows and its extra (paid) usage.- Window
- One rate-limit window.
Enums§
- Error
- Why a call failed.
- Plan
- A consumer subscription, as
Profile::planreads it.
Constants§
- CLAUDE_
CODE_ CLIENT_ ID - Claude Code’s public OAuth client id, the one its logins are issued to. A refresh must name the client the token was issued to.
- DEFAULT_
BASE_ URL - The API’s base URL.
- DEFAULT_
SCOPES - The scopes a refresh asks for when the caller names none: Claude Code’s defaults for a subscription login.
- DEFAULT_
TIMEOUT - The default request timeout.
- DEFAULT_
TOKEN_ URL - The OAuth token endpoint.
- DEFAULT_
USER_ AGENT - The default
User-Agent:ccwire-oauth/<version>. - MAX_
BODY - The largest response body read; a larger one is
Error::TooLarge. - OAUTH_
BETA - The
anthropic-betavalue the OAuth endpoints require.
Type Aliases§
- Extra
- Fields a response carried that this crate doesn’t type, by name.