News

Streamline Claude Pro/Max Billing: Use Agent SDK with OAuth Token to Avoid Double API Charges

Streamline Claude Pro/Max Billing: Use Agent SDK with OAuth Token to Avoid Double API Charges

If you're a Claude Pro or Max subscriber who also programs against Claude APIs, you might inadvertently be paying twice. Anthropic maintains distinct billing for subscriptions and API credits, and its standard SDK only recognizes the latter. However, there's an officially supported method leveraging the Claude Agent SDK to bill against your existing subscription.

Anthropic operates with two separate billing mechanisms:

  • ANTHROPIC_API_KEY: This console API key is tied to pay-as-you-go API credits.
  • CLAUDE_CODE_OAUTH_TOKEN: Obtained via claude setup-token, this OAuth token links directly to your Pro/Max subscription quota.

While the regular Anthropic SDK defaults to the API key, the Agent SDK (claude-agent-sdk for Python, @anthropic-ai/claude-agent-sdk for TypeScript) integrates with the Claude Code CLI. This CLI natively supports both billing paths, ensuring that calls made with an OAuth token are debited from your subscription.

Here’s a basic setup for using your subscription with the Agent SDK:

First, generate the OAuth token:

npm install -g @anthropic-ai/claude-code
claude setup-token   # This command opens a browser to authenticate and returns a 1-year token.

Next, add the token to your .env file:

CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...

Then, in Python, you can make calls that utilize your subscription:

import asyncio, os, sys
from dotenv import load_dotenv

load_dotenv()
if os.environ.get("ANTHROPIC_API_KEY"):
    sys.exit("ANTHROPIC_API_KEY is set — it would shadow your OAuth token. unset it.")

from claude_agent_sdk import query, ClaudeAgentOptions, AssistantMessage, TextBlock

async def main():
    async for msg in query(
        prompt="Say hello in one short sentence.",
        options=ClaudeAgentOptions(allowed_tools=[]),
    ):
        if isinstance(msg, AssistantMessage):
            for block in msg.content:
                if isinstance(block, TextBlock):
                    print(block.text)

asyncio.run(main())

This Python snippet will bill against your Claude Max/Pro subscription rather than your API credits. A companion repository at github.com/avivshaked/prototype-with-claude-max offers the same example in TypeScript, along with a WebSearch and token-by-token streaming demonstration.

Important Note on Authentication Precedence:

The Agent SDK prioritizes authentication methods in a specific order: cloud credentials, then ANTHROPIC_AUTH_TOKEN, then ANTHROPIC_API_KEY, followed by apiKeyHelper, then CLAUDE_CODE_OAUTH_TOKEN, and finally interactive login. Crucially, if ANTHROPIC_API_KEY is set in your environment (which is common for many projects), it will silently override your OAuth token. This means you might mistakenly be using and paying for API credits while believing you are utilizing your subscription. To ensure your subscription is used, always unset the ANTHROPIC_API_KEY environment variable if it's present.

↗ Read original source