claude-code - 💡(How to fix) Fix [BUG] Raw SDK calls with OAuth token bill to plan allowance instead of extra usage — blocklist gap [1 participants]

Official PRs (…)
ON THIS PAGE

Recommended Tools

×6

Utilities matched from this issue’s tags and category — try them while you read without losing context.

GitHub issue graph ai analysis

Paste a GitHub issue URL. We fetch that issue, discover linked issues from bodies/comments/timeline, collect linked pull requests, and produce a structured English report.

The report is written in English Markdown for sharing and archival.

Helpful · Quick feedback

Loading…
GitHub stats
anthropics/claude-code#45380Fetched 2026-04-09 08:06:46
View on GitHub
Comments
0
Participants
1
Timeline
3
Reactions
0
Timeline (top)
labeled ×3

Direct API calls made with the public @anthropic-ai/sdk using an OAuth token from ~/.claude/.credentials.json are silently billed against the Max plan's included allowance instead of extra usage. The anthropic-ratelimit-unified-overage-utilization header stays at 0.0 despite multiple successful calls.

This appears to be because the third-party detection system is blocklist-based (flagging known tools like OpenClaw by signature) rather than allowlist-based (requiring valid cch attestation). Raw SDK calls fall into an unclassified gap — no valid attestation, but no third-party fingerprint either — and default to plan allowance.

I am reporting this because I want to be billed correctly. I am not attempting to bypass billing.

Root Cause

This appears to be because the third-party detection system is blocklist-based (flagging known tools like OpenClaw by signature) rather than allowlist-based (requiring valid cch attestation). Raw SDK calls fall into an unclassified gap — no valid attestation, but no third-party fingerprint either — and default to plan allowance.

Code Example

import Anthropic from "@anthropic-ai/sdk";
import { readFileSync } from "fs";
import { join } from "path";

const creds = JSON.parse(readFileSync(join(process.env.HOME, ".claude", ".credentials.json"), "utf-8"));
const token = creds.claudeAiOauth.accessToken;
const client = new Anthropic({ apiKey: token });

const msg = await client.messages.create({
  model: "claude-haiku-4-5-20251001",
  max_tokens: 100,
  messages: [{ role: "user", content: "Hello" }],
});

---

anthropic-ratelimit-unified-overage-status: allowed
anthropic-ratelimit-unified-overage-utilization: 0.0    ← should be >0 for third-party
anthropic-ratelimit-unified-5h-utilization: 0.37         ← plan allowance increasing
anthropic-ratelimit-unified-7d-utilization: 0.78         ← plan allowance increasing

---

accept: application/json
anthropic-version: 2023-06-01
content-type: application/json
user-agent: Anthropic/JS 0.86.0
x-api-key: sk-ant-oat01-...
x-stainless-arch: x64
x-stainless-lang: js
x-stainless-os: Linux
x-stainless-package-version: 0.86.0
x-stainless-runtime: node
x-stainless-runtime-version: v24.3.0
RAW_BUFFERClick to expand / collapse

Summary

Direct API calls made with the public @anthropic-ai/sdk using an OAuth token from ~/.claude/.credentials.json are silently billed against the Max plan's included allowance instead of extra usage. The anthropic-ratelimit-unified-overage-utilization header stays at 0.0 despite multiple successful calls.

This appears to be because the third-party detection system is blocklist-based (flagging known tools like OpenClaw by signature) rather than allowlist-based (requiring valid cch attestation). Raw SDK calls fall into an unclassified gap — no valid attestation, but no third-party fingerprint either — and default to plan allowance.

I am reporting this because I want to be billed correctly. I am not attempting to bypass billing.

Environment

  • Plan: Max x20
  • SDK: @anthropic-ai/sdk v0.86.0 (MIT license, public npm package)
  • Token: OAuth token (sk-ant-oat01-*) from ~/.claude/.credentials.json, obtained via claude auth login
  • Runtime: Bun 1.3.11 on AWS Ubuntu
  • Use case: A personal daemon that makes lightweight API calls (Haiku classification, Sonnet learning extraction) alongside Claude Code CLI sessions

Reproduction

  1. Have a Max plan with extra usage enabled
  2. Install the public SDK: npm install @anthropic-ai/sdk
  3. Read the OAuth token from ~/.claude/.credentials.json
  4. Make a direct API call:
import Anthropic from "@anthropic-ai/sdk";
import { readFileSync } from "fs";
import { join } from "path";

const creds = JSON.parse(readFileSync(join(process.env.HOME, ".claude", ".credentials.json"), "utf-8"));
const token = creds.claudeAiOauth.accessToken;
const client = new Anthropic({ apiKey: token });

const msg = await client.messages.create({
  model: "claude-haiku-4-5-20251001",
  max_tokens: 100,
  messages: [{ role: "user", content: "Hello" }],
});
  1. Check the response headers:
anthropic-ratelimit-unified-overage-status: allowed
anthropic-ratelimit-unified-overage-utilization: 0.0    ← should be >0 for third-party
anthropic-ratelimit-unified-5h-utilization: 0.37         ← plan allowance increasing
anthropic-ratelimit-unified-7d-utilization: 0.78         ← plan allowance increasing

Outgoing request headers (what the SDK sends)

accept: application/json
anthropic-version: 2023-06-01
content-type: application/json
user-agent: Anthropic/JS 0.86.0
x-api-key: sk-ant-oat01-...
x-stainless-arch: x64
x-stainless-lang: js
x-stainless-os: Linux
x-stainless-package-version: 0.86.0
x-stainless-runtime: node
x-stainless-runtime-version: v24.3.0

No x-anthropic-billing-header, no cch attestation hash, no x-app header. These calls are not from Claude Code's binary — they're raw SDK calls from a third-party process.

Expected behavior

Per the April 4, 2026 policy change: third-party usage of OAuth tokens should bill against extra usage, not plan allowance. These raw SDK calls should be classified as third-party since they:

  • Do not include the cch attestation hash
  • Do not come from the Claude Code binary
  • Have a generic SDK user-agent (Anthropic/JS 0.86.0), not claude-cli/...

Actual behavior

Calls succeed and are billed against the plan's included allowance (5h/7d utilization increases, overage stays at 0.0). The detection system appears to only flag known third-party tools by signature rather than requiring proof of first-party origin.

Request

Please provide one of:

  1. A documented header or parameter for honest third-party clients to self-declare (e.g., x-client-type: third-party)
  2. Switch detection to allowlist-based — require valid cch attestation for plan allowance, route everything else to extra usage
  3. Guidance on the correct way to make programmatic API calls with an OAuth token that bills to the right lane

I'm happy to add whatever header or identifier is needed to ensure correct billing. The public SDK, the public API endpoint, and the OAuth token are all legitimately obtained — I just want the billing to be accurate.

extent analysis

TL;DR

To ensure correct billing, the user needs to add a specific header or parameter to their API calls to self-declare as a third-party client, or the detection system should be switched to allowlist-based.

Guidance

  • The user should consider adding a custom header to their API calls, such as x-client-type: third-party, to self-declare as a third-party client.
  • The detection system's blocklist-based approach may need to be revised to an allowlist-based approach, requiring valid cch attestation for plan allowance and routing everything else to extra usage.
  • The user should verify that their API calls are being billed correctly by checking the response headers, specifically the anthropic-ratelimit-unified-overage-utilization header.
  • The user may need to work with the API provider to determine the correct way to make programmatic API calls with an OAuth token that bills to the right lane.

Example

const client = new Anthropic({ 
  apiKey: token, 
  headers: { 
    'x-client-type': 'third-party' 
  } 
});

This example adds a custom x-client-type header to the API call, self-declaring as a third-party client.

Notes

The solution to this issue may depend on the specific requirements and implementation of the API provider's billing system. The user should work closely with the provider to determine the correct approach.

Recommendation

Apply workaround: The user should add a custom header to their API calls to self-declare as a third-party client, as this is a straightforward and immediate solution to ensure correct billing.

Vote matrix · Quick signals

Works
Did the solution work? Tap to confirm.
Easy Fix
Was it a quick fix?
Time Saver
Did it save you time?
Blocking
Was it severely blocking?
Common Issue
Are others likely hitting this too?
Flaky / Intermittent
Is it intermittent?
Verified / Reproducible
Can you reproduce it reliably?
Loading…

FAQ

Expected behavior

Per the April 4, 2026 policy change: third-party usage of OAuth tokens should bill against extra usage, not plan allowance. These raw SDK calls should be classified as third-party since they:

  • Do not include the cch attestation hash
  • Do not come from the Claude Code binary
  • Have a generic SDK user-agent (Anthropic/JS 0.86.0), not claude-cli/...

Still need to ship something?

×6

Another batch ranked right after the header list — different links, same matching logic.

Back to top recommendations

TRENDING