#[derive(Debug, Clone, serde::Serialize, serde::Deserialize)]
pub struct UsageLimitsData {
pub five_hour_pct: f64,
pub seven_day_pct: f64,
pub five_hour_resets_at: String, pub seven_day_resets_at: String, #[serde(default)]
pub five_hour_resets_at_epoch: Option<u64>,
#[serde(default)]
pub seven_day_resets_at_epoch: Option<u64>,
}
#[derive(serde::Deserialize)]
struct ApiResponse {
five_hour: UsagePeriod,
seven_day: UsagePeriod,
}
#[derive(serde::Deserialize)]
struct UsagePeriod {
utilization: f64,
resets_at: Option<String>,
}
pub fn fetch_usage_limits(token: &str) -> Result<UsageLimitsData, String> {
use std::time::Duration;
let agent = ureq::Agent::new_with_config(
ureq::config::Config::builder()
.timeout_global(Some(Duration::from_secs(5)))
.build(),
);
let mut response = agent
.get("https://api.anthropic.com/api/oauth/usage")
.header("Authorization", &format!("Bearer {token}"))
.header("anthropic-beta", "oauth-2025-04-20")
.call()
.map_err(|e| format!("network error: {e}"))?;
if response.status() != 200 {
return Err(format!("API returned {}", response.status()));
}
let api: ApiResponse = response
.body_mut()
.read_json()
.map_err(|e| format!("unexpected response format: {e}"))?;
Ok(UsageLimitsData {
five_hour_pct: api.five_hour.utilization,
seven_day_pct: api.seven_day.utilization,
five_hour_resets_at: api.five_hour.resets_at.unwrap_or_default(),
seven_day_resets_at: api.seven_day.resets_at.unwrap_or_default(),
five_hour_resets_at_epoch: None,
seven_day_resets_at_epoch: None,
})
}