Enterprise Claude Cost Chargebacks by Team

Written by Michael Lip · Solo founder of Zovo · $400K+ on Upwork · 100% JSS Join 50+ builders · More at zovo.one

When Claude API costs sit on a shared budget, nobody owns the optimization. A company spending $15,000/month on Claude discovered that the data team consumed $8,000 (53%) while the product team used $2,000 (13%). Under the shared model, both teams got the same “reduce Claude spend” mandate. After implementing chargebacks – billing each team for their actual usage – the data team found and fixed an inefficient batch pipeline, cutting their spend to $3,000. The product team, now unburdened by the data team’s waste, actually increased their usage to $3,500 for a new feature. Total spend dropped from $15,000 to $11,500 while output increased.

The Setup

Chargebacks assign API costs to the teams or business units that generate them. This requires three capabilities: cost attribution (tagging every request with a team identifier), cost calculation (computing exact costs per request from the usage object), and cost reporting (aggregating and distributing monthly invoices per team). The Claude API charges at specific per-million-token rates: Opus 4.7 at $5.00/$25.00, Sonnet 4.6 at $3.00/$15.00, and Haiku 4.5 at $1.00/$5.00 for input/output respectively. Web searches add $0.01 each, and batch processing gets a 50% discount. All of these need to be captured in the chargeback system.

The Math

Enterprise with 5 teams and $15,000/month total Claude spend:

Before chargebacks (shared budget):

Team Actual Spend Perceived Spend Optimization Incentive
Data $8,000 $3,000 (equal share) Low
Product $2,000 $3,000 (equal share) Negative (subsidizing)
Engineering $3,000 $3,000 (equal share) None
Support $1,500 $3,000 (equal share) Negative
Research $500 $3,000 (equal share) Negative

After chargebacks:

Team Charged Action New Spend
Data $8,000 Fixed batch pipeline $3,000
Product $2,000 Invested in new feature $3,500
Engineering $3,000 Moved tests to Haiku $1,200
Support $1,500 Added caching $800
Research $500 No change $500
Total $15,000   $9,000

Savings: $6,000/month (40%) from accountability alone

The Technique

Build a chargeback system that produces monthly invoices per team.

import anthropic
import json
from dataclasses import dataclass, field
from collections import defaultdict
from datetime import datetime, timedelta

PRICING = {
    "claude-opus-4-7": {
        "input": 5.00, "output": 25.00,
        "cache_read": 0.50, "cache_write": 6.25,
        "batch_input": 2.50, "batch_output": 12.50,
    },
    "claude-sonnet-4-6": {
        "input": 3.00, "output": 15.00,
        "cache_read": 0.30, "cache_write": 3.75,
        "batch_input": 1.50, "batch_output": 7.50,
    },
    "claude-haiku-4-5": {
        "input": 1.00, "output": 5.00,
        "cache_read": 0.10, "cache_write": 1.25,
        "batch_input": 0.50, "batch_output": 2.50,
    },
}

@dataclass
class ChargebackRecord:
    timestamp: str
    team: str
    department: str
    model: str
    input_tokens: int
    output_tokens: int
    is_batch: bool
    web_searches: int
    cost: float

@dataclass
class ChargebackSystem:
    records: list[ChargebackRecord] = field(default_factory=list)
    overhead_rate: float = 0.10  # 10% platform overhead markup

    def record_usage(self, team: str, department: str,
                      model: str, usage,
                      is_batch: bool = False,
                      web_searches: int = 0):
        """Record a single API call for chargeback."""
        prices = PRICING.get(model, PRICING["claude-sonnet-4-6"])

        if is_batch:
            input_price = prices["batch_input"]
            output_price = prices["batch_output"]
        else:
            input_price = prices["input"]
            output_price = prices["output"]

        cost = (
            usage.input_tokens * input_price / 1_000_000
            + usage.output_tokens * output_price / 1_000_000
            + web_searches * 0.01
        )

        cache_read = getattr(usage, "cache_read_input_tokens", 0) or 0
        cache_write = getattr(usage, "cache_creation_input_tokens", 0) or 0
        cost += cache_read * prices["cache_read"] / 1_000_000
        cost += cache_write * prices["cache_write"] / 1_000_000

        self.records.append(ChargebackRecord(
            timestamp=datetime.utcnow().isoformat(),
            team=team,
            department=department,
            model=model,
            input_tokens=usage.input_tokens,
            output_tokens=usage.output_tokens,
            is_batch=is_batch,
            web_searches=web_searches,
            cost=cost,
        ))

    def generate_invoice(self, team: str,
                          month: str = None) -> dict:
        """Generate monthly invoice for a team."""
        team_records = [
            r for r in self.records if r.team == team
        ]

        by_model = defaultdict(lambda: {
            "requests": 0, "input_tokens": 0,
            "output_tokens": 0, "cost": 0.0
        })

        for r in team_records:
            m = by_model[r.model]
            m["requests"] += 1
            m["input_tokens"] += r.input_tokens
            m["output_tokens"] += r.output_tokens
            m["cost"] += r.cost

        subtotal = sum(m["cost"] for m in by_model.values())
        overhead = subtotal * self.overhead_rate
        total = subtotal + overhead

        search_cost = sum(r.web_searches * 0.01 for r in team_records)

        return {
            "team": team,
            "period": month or datetime.utcnow().strftime("%Y-%m"),
            "line_items": dict(by_model),
            "web_search_cost": round(search_cost, 2),
            "subtotal": round(subtotal, 2),
            "platform_overhead": round(overhead, 2),
            "total": round(total, 2),
            "total_requests": len(team_records),
        }

    def generate_all_invoices(self) -> list[dict]:
        """Generate invoices for all teams."""
        teams = set(r.team for r in self.records)
        return [self.generate_invoice(team) for team in sorted(teams)]

    def print_summary(self):
        """Print chargeback summary across all teams."""
        invoices = self.generate_all_invoices()
        grand_total = sum(inv["total"] for inv in invoices)

        print("=" * 60)
        print("CLAUDE API CHARGEBACK SUMMARY")
        print("=" * 60)
        for inv in sorted(invoices,
                           key=lambda x: x["total"], reverse=True):
            pct = inv["total"] / grand_total * 100 if grand_total else 0
            print(f"  {inv['team']:20s} | "
                  f"{inv['total_requests']:6,d} requests | "
                  f"${inv['total']:8.2f} ({pct:.1f}%)")
        print("-" * 60)
        print(f"  {'TOTAL':20s} | "
              f"{sum(i['total_requests'] for i in invoices):6,d} requests | "
              f"${grand_total:8.2f}")


# Usage
chargebacks = ChargebackSystem(overhead_rate=0.10)
client = anthropic.Anthropic()

# Data team request
response = client.messages.create(
    model="claude-opus-4-7",
    max_tokens=4096,
    messages=[{"role": "user", "content": "Analyze this dataset"}]
)
chargebacks.record_usage("data-team", "analytics",
                          "claude-opus-4-7", response.usage)

# Support team request
response = client.messages.create(
    model="claude-haiku-4-5",
    max_tokens=256,
    messages=[{"role": "user", "content": "Classify: billing issue"}]
)
chargebacks.record_usage("support-team", "customer-success",
                          "claude-haiku-4-5", response.usage)

chargebacks.print_summary()

The Tradeoffs

Chargebacks create perverse incentives if implemented poorly. Teams might avoid using Claude for legitimate tasks to keep their internal bill low, or they might game the system by running requests through another team’s tag. Clear policies are essential: define what’s chargeable, what’s shared infrastructure (and allocated proportionally), and how to handle cross-team projects. The 10% platform overhead covers the infrastructure cost of running the chargeback system itself, API key management, and shared monitoring. Adjust this rate based on your actual overhead costs.

Implementation Checklist

Measuring Impact

Compare total Claude spend in the 3 months before chargebacks to the 3 months after. The accountability effect typically produces 20-40% cost reduction as teams optimize their own usage. Track per-team optimization actions (model downgrades, caching improvements, request deduplication) that result from chargeback visibility. The most successful chargeback implementations also track value metrics alongside cost: cost per feature shipped, cost per customer interaction resolved, cost per analysis completed. This prevents the perverse incentive of cost minimization at the expense of output quality.