Cost Optimization & FinOps

Tagging Claude Requests for Cost Attribution

"Which team spent that $40,000?" is unanswerable unless every request carried its answer with it. Attribution has to be designed in at the request layer.

Claude 3P 101 · Updated July 2026 · Unofficial guide

Claude bills by token, not by team. The invoice — whether from Anthropic or through a cloud marketplace — tells you what the organization spent, but not which application, feature, or business unit drove it. To slice cost by any dimension later, each request must be tagged with those dimensions when it is made. There are three layers where tags can live, and mature setups use all three.

Layer 1: the platform's native boundaries

On the Claude API, the coarse-grained attribution primitives are workspaces and API keys. Workspaces separate projects, environments, or teams while keeping billing and administration centralized; every API key is scoped to exactly one workspace. The Admin Usage API (GET /v1/organizations/usage_report/messages) breaks token consumption down by model, workspace, and service tier, and can filter or group by API key — and the Cost API (GET /v1/organizations/cost_report) reports USD amounts groupable by workspace_id. So the free attribution you get is: one workspace per team or product, one API key per application. An organization can have up to 100 workspaces, which is enough granularity for most team-level chargeback.

The limitation is dimensionality. A workspace answers "which team," but not "which feature inside the app" or "which customer tier." For that you need the next layers.

Layer 2: tags in your own request pipeline

The most flexible tags are the ones you attach yourself. Wrap your SDK client so every call records an attribution context alongside the response's usage object, then emit both to your logging pipeline:

from anthropic import AnthropicBedrockMantle

client = AnthropicBedrockMantle(aws_region="us-east-1")

def tagged_call(tags: dict, **kwargs):
    resp = client.messages.create(**kwargs)
    log_usage_event(
        tags=tags,  # {"app": "support-bot", "team": "cx", "feature": "triage"}
        model=kwargs["model"],
        input_tokens=resp.usage.input_tokens,
        output_tokens=resp.usage.output_tokens,
    )
    return resp

Because the tags never leave your infrastructure, this works identically on every platform — first-party, Bedrock, Vertex AI, Foundry — and supports unlimited dimensions. The discipline required: make the tag dictionary mandatory in your internal client, with a small controlled vocabulary (application, team, feature, environment), so ad-hoc callers can't create untagged spend. Many organizations enforce this in a central gateway service rather than in each codebase.

Layer 3: cloud-native metadata

The cloud platforms add their own hooks. On Amazon Bedrock, model invocation logging records caller-supplied requestMetadata along with per-call inputTokenCount and outputTokenCount, so tags you pass at invocation time land in CloudWatch Logs or S3 ready for analysis (note this covers the bedrock-runtime endpoint; bedrock-mantle calls are not currently captured by invocation logging). On Microsoft Foundry, cost appears as a single Claude Consumption Unit (CCU) line in Azure Cost Management, with per-model token and request detail in the Foundry portal's Monitoring tab — so per-feature attribution there depends on your own layer-2 tags or on separate deployments per application. Check your cloud provider's documentation for its current tagging and cost-allocation mechanisms.

Design rule: tag at the finest grain you might ever report on. You can always aggregate feature-level data up to teams; you can never disaggregate a monthly workspace total down to features after the fact.

Making the three layers agree

Reconcile monthly: your layer-2 event store, summed by workspace or account, should match the platform's own usage report within a small tolerance. Where they diverge, you have untagged traffic — usually a script someone ran with a raw API key. Workspace-scoping keys tightly (and treating the Default Workspace, which reports as workspace_id: null, as a red flag in reports) makes stray spend easy to spot.

Where to go next

Continue with logging token counts for FinOps for the event-capture side, and separating dev, staging, and production costs for the environment dimension specifically.

Sources