Back to KB

Readers will learn how to configure the Claude Agent SDK to authenticate via OAuth, enabling personal scripts to bill against their Claude Pro/Max subscription instead of API credits, thereby eliminating double-payment for individual development workflows.

Difficulty
Beginner
Read Time
8 min

Eliminating Double-Billing: Integrating Claude Subscriptions with the Agent SDK

By Codcompass Team··8 min read

Current Situation Analysis

Many developers maintain a Claude Pro or Max subscription for interactive use while simultaneously writing automation scripts, local tools, or prototypes that interact with Claude via code. A common architectural oversight leads to financial inefficiency: these scripts often utilize the standard ANTHROPIC_API_KEY, which bills against pay-as-you-go API credits. Consequently, developers effectively pay twice for the same model access—once for the subscription and again for the API calls generated by their own tooling.

The root cause lies in Anthropic's billing architecture, which strictly segregates subscription access from API access. The standard anthropic SDK is designed exclusively for the API billing relationship and lacks the capability to authenticate via subscription credentials. This creates a fragmentation where personal automation scripts cannot natively benefit from the flat-rate subscription model, forcing developers to either abandon code-based workflows or absorb the marginal cost of API credits.

However, Anthropic provides an officially supported pathway to unify these workflows. The Claude Agent SDK wraps the Claude Code CLI, which possesses native support for OAuth-based authentication. By utilizing this SDK, developers can authenticate scripts using the same credentials as their desktop subscription, ensuring that all programmatic requests consume the subscription quota rather than depleting API credits. This approach is particularly valuable for local development, personal assistants, and prototyping, where usage patterns align with individual consumption limits.

WOW Moment: Key Findings

The following comparison highlights the operational and economic differences between the two authentication models available to developers.

Authentication MethodBilling SourceRate Limit ProfilePrimary Use CaseCost Efficiency
API Key (ANTHROPIC_API_KEY)Pay-as-you-go CreditsHigh throughput; ScalableProduction applications; Multi-user servicesLow for personal scripts; High for scale
OAuth Token (CLAUDE_CODE_OAUTH_TOKEN)Subscription QuotaShared; Personal limitsLocal scripts; Prototypes; Personal toolsHigh for personal usage; Zero marginal cost

The breakthrough insight is that the Agent SDK acts as a bridge between code and subscription billing. Unlike the standard SDK, the Agent SDK delegates authentication to the underlying CLI environment, which recognizes the OAuth token generated via claude setup-token. This allows developers to retain the programmatic benefits of an SDK—such as structured streaming, tool definitions, and async iteration—while routing traffic through the subscription pipeline.

Furthermore, the Agent SDK maintains feature parity with the standard SDK for core interactions. Developers can still access streaming responses, tool use, and message parsing. The only significant constraint is the authentication vector; the SDK does not support hybrid billing. It is imperative to ensure that environment variables do not conflict, as the presence of an API key will silently override the OAuth token, reverting billing to the pay-as-you-go model without warning.

Core Solution

To implement subscription-based billing for your scripts, follow this implementation workflow. This example demonstrates a Python-based setup using the Agent SDK with robust environment validation.

Step 1: Install Dependencies

Install the Claude Code CLI globally to manage token generation, and install the Agent SDK in your project environment.

# Install CLI for token management
npm install -g @anthropic-ai/claude-code

# Install Agent SDK in your project
pip install claude-agent-sdk python-dotenv

Step 2: Generate and Configure OAuth Token

Generate a long-lived OAuth token and store it securely in your environment configuration.

# Launch browser authentication flow
claude setup-token

Copy the resulting token and add it to your .env file:

CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-<your_token_here>

Step 3: Implement Subscription-Aware Script

The following Python example demons

trates a safe implementation. It includes a validation step to prevent API key shadowing and utilizes the Agent SDK for streaming responses.

import os
import asyncio
from dotenv import load_dotenv
from claude_agent_sdk import query, ClaudeAgentOptions
from claude_agent_sdk.messages import AssistantMessage, TextBlock

load_dotenv()

def ensure_subscription_auth():
    """Validate that API keys are not shadowing the OAuth token."""
    if os.environ.get("ANTHROPIC_API_KEY"):
        raise RuntimeError(
            "Authentication Conflict: ANTHROPIC_API_KEY is detected. "
            "This variable overrides subscription billing. "
            "Please unset this variable to use your Pro/Max quota."
        )
    if not os.environ.get("CLAUDE_CODE_OAUTH_TOKEN"):
        raise RuntimeError(
            "Missing OAuth Token: CLAUDE_CODE_OAUTH_TOKEN is not set. "
            "Run 'claude setup-token' to generate credentials."
        )

async def run_subscription_query(prompt: str) -> str:
    """Execute a query against the subscription quota."""
    ensure_subscription_auth()
    
    full_response = ""
    
    # Stream response tokens
    async for message in query(
        prompt=prompt,
        options=ClaudeAgentOptions(allowed_tools=[])
    ):
        if isinstance(message, AssistantMessage):
            for block in message.content:
                if isinstance(block, TextBlock):
                    full_response += block.text
                    
    return full_response

async def main():
    try:
        result = await run_subscription_query("Explain the difference between OAuth and API key authentication in one paragraph.")
        print("Response:", result)
    except RuntimeError as e:
        print(f"Configuration Error: {e}")

if __name__ == "__main__":
    asyncio.run(main())

This implementation ensures that your script explicitly checks for authentication conflicts before execution, providing immediate feedback if the environment is misconfigured. The streaming loop captures the response efficiently while billing against your subscription.

Pitfall Guide

  1. Silent API Key Shadowing

    • Issue: If ANTHROPIC_API_KEY is present in the environment, the SDK prioritizes it over the OAuth token. This results in API credit consumption without any error message.
    • Fix: Always unset ANTHROPIC_API_KEY in scripts intended for subscription billing. Use the validation function shown in the Core Solution to enforce this.
  2. Production Multi-User Deployment

    • Issue: Using OAuth tokens in a production application serving multiple users violates Anthropic's Terms of Service and exposes your subscription to abuse.
    • Fix: Reserve OAuth tokens for personal, local scripts. For production applications, switch to ANTHROPIC_API_KEY and implement proper usage metering.
  3. Token Expiration Management

    • Issue: OAuth tokens generated via claude setup-token have a limited lifespan (typically one year). Scripts may fail silently or with authentication errors after expiration.
    • Fix: Implement token rotation procedures or set calendar reminders to regenerate tokens annually. Monitor authentication errors in logs.
  4. Environment Variable Pollution

    • Issue: Global environment variables from other projects may leak into your script's context, causing unexpected billing behavior.
    • Fix: Use project-specific .env files and load them explicitly. Avoid exporting credentials in shell profiles unless necessary.
  5. Incorrect SDK Selection

    • Issue: Developers may install the standard anthropic package, which does not support OAuth authentication.
    • Fix: Ensure you install claude-agent-sdk (Python) or @anthropic-ai/claude-agent-sdk (TypeScript). Verify the package name in your dependency manager.
  6. Rate Limit Violations

    • Issue: Subscription quotas have different rate limits compared to API credits. Aggressive looping in scripts may trigger rate limit errors.
    • Fix: Implement backoff strategies and throttle request rates in your scripts. Monitor for 429 responses and adjust concurrency accordingly.
  7. Security Leakage

    • Issue: Committing the OAuth token to version control exposes your subscription to unauthorized access.
    • Fix: Add .env to your .gitignore file. Never hardcode tokens in source files. Use secret management tools for sensitive credentials.

Production Bundle

Action Checklist

  • Install @anthropic-ai/claude-code globally via npm.
  • Run claude setup-token and copy the generated OAuth token.
  • Create a .env file with CLAUDE_CODE_OAUTH_TOKEN.
  • Verify ANTHROPIC_API_KEY is unset in the script environment.
  • Install claude-agent-sdk in the project dependencies.
  • Run a test query to confirm billing against subscription quota.
  • Add .env to .gitignore to prevent token leakage.

Decision Matrix

ScenarioRecommended AuthSDK ChoiceNotes
Personal Automation ScriptOAuth TokenAgent SDKCost-effective; Uses subscription quota.
Local Prototype / HackathonOAuth TokenAgent SDKRapid setup; No credit card required.
Production Web ApplicationAPI KeyStandard SDKScalable; Compliant with ToS.
CI/CD PipelineAPI KeyStandard SDKSecure; Isolated from personal quota.
Multi-User SaaSAPI KeyStandard SDKMandatory; OAuth prohibited for multi-tenancy.

Configuration Template

Create a .env.example file to document required variables:

# Subscription Authentication (Personal Use Only)
# Generate via: claude setup-token
CLAUDE_CODE_OAUTH_TOKEN=sk-ant-oat01-...

# API Authentication (Production Use)
# Generate via: console.anthropic.com
# ANTHROPIC_API_KEY=sk-ant-api03-...

Quick Start Guide

  1. Initialize: Run claude setup-token to generate your OAuth credentials.
  2. Configure: Add the token to your .env file as CLAUDE_CODE_OAUTH_TOKEN.
  3. Code: Import query from claude_agent_sdk and execute your prompt.
  4. Verify: Ensure ANTHROPIC_API_KEY is not set to avoid billing conflicts.
  5. Run: Execute your script; requests will now consume your subscription quota.