Skip to main content

Crate ccwire_oauth

Crate ccwire_oauth 

Source
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.

§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.
AutoReload
Prepaid auto-reload, read-only.
Client
A client for the account endpoints.
ClientBuilder
Builds a Client.
ExtraUsage
Extra usage: credits spent past the plan’s limits this month.
Limit
One row of Usage::limits.
LimitModel
The model of a per-model Limit.
LimitScope
What a scoped Limit covers.
Organization
The organization a token acts for.
OverageSpendLimit
GET /api/oauth/organizations/{org}/overage_spend_limit: the extra usage (overage) monthly limit.
PrepaidCredits
GET /api/oauth/organizations/{org}/prepaid/credits: the prepaid balance.
Profile
GET /api/oauth/profile: the account and its organization.
RefreshRequest
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.
TokenSet
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::plan reads 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-beta value the OAuth endpoints require.

Type Aliases§

Extra
Fields a response carried that this crate doesn’t type, by name.