← Blog

How to Monitor Claude API Token Costs

2026-10-28 · 5 min read · SubToAPI Team

If you're running Claude in production, token costs can swing wildly between a quiet week and a traffic spike, a prompt change, or a new feature that quietly doubles your context length. Monitoring Claude API token costs means tracking input and output tokens per request, aggregating them by user or feature, and comparing that against your pricing tier in near real time — not just checking the invoice at the end of the month.

The short answer: every Claude API response includes a usage object with input_tokens and output_tokens. Capture that on every call, store it with metadata (endpoint, model, user ID, feature), and roll it up into dashboards or alerts. Below is how to do that properly, what to watch for, and where it tends to go wrong.

Why token costs drift without warning

Token costs rarely spike because of one obvious thing. More often it's a combination of small changes:

None of these show up until you're looking at actual per-request token counts, not estimates.

Step 1: Capture usage data on every request

Every Claude Messages API response returns usage metadata alongside the completion:

{
  "id": "msg_01...",
  "model": "claude-...",
  "usage": {
    "input_tokens": 512,
    "output_tokens": 184
  }
}

Log this for every single call — success or failure, since failed-but-billed calls (e.g., a response cut off by a rate limit after tokens were generated) still matter. A minimal logging wrapper looks like this:

async function callClaude(payload, meta) {
  const res = await fetch("https://api.anthropic.com/v1/messages", {
    method: "POST",
    headers: {
      "x-api-key": process.env.ANTHROPIC_API_KEY,
      "anthropic-version": "2023-06-01",
      "content-type": "application/json",
    },
    body: JSON.stringify(payload),
  });

  const data = await res.json();

  await logUsage({
    userId: meta.userId,
    feature: meta.feature,
    model: payload.model,
    inputTokens: data.usage?.input_tokens ?? 0,
    outputTokens: data.usage?.output_tokens ?? 0,
    timestamp: Date.now(),
  });

  return data;
}

The key fields to log consistently: model name, input tokens, output tokens, which feature or endpoint triggered the call, and a user or account identifier. Without that last piece, you can see total spend but not who is driving it.

Step 2: Convert tokens into cost at the point of logging

Don't wait until the end of the pipeline to compute dollar cost — do it right after logging, using the current price per model. Keep a small lookup table in your codebase or config, since Anthropic's per-model pricing differs for input vs. output tokens:

const PRICING = {
  "claude-opus-4": { input: 15.00, output: 75.00 }, // per million tokens
  "claude-sonnet-4": { input: 3.00, output: 15.00 },
};

function estimateCost(model, inputTokens, outputTokens) {
  const rate = PRICING[model];
  return (
    (inputTokens / 1_000_000) * rate.input +
    (outputTokens / 1_000_000) * rate.output
  );
}

Store the computed cost alongside the raw token counts so you can re-aggregate by day, user, or feature without recomputing from scratch every time pricing changes.

Step 3: Aggregate and watch the right metrics

Raw per-request logs are useful for debugging, but for monitoring you want rollups. At minimum, track:

A simple SQL query against a logs table gets you most of the way:

SELECT
  DATE(timestamp) AS day,
  model,
  SUM(input_tokens) AS total_input,
  SUM(output_tokens) AS total_output,
  SUM(cost) AS total_cost
FROM claude_usage_logs
GROUP BY day, model
ORDER BY day DESC;

Run this daily and plot it. Even a basic spreadsheet beats waiting for the monthly bill.

Step 4: Set thresholds, not just dashboards

Dashboards tell you what happened. Thresholds tell you something's wrong now. Decide ahead of time what "unusual" looks like for your app — e.g., daily spend 2x the 7-day average, or a single user account exceeding 500K tokens/day — and page or Slack-notify when it's crossed. This is cheap to build on top of the logging table you already have.

Where SubToAPI fits in

If you're exposing Claude through your own product rather than calling it directly from internal services, SubToAPI adds per-key usage metadata on top of your existing Claude access — so each sub_live_... key used by a customer or team shows its own token and request history without you building that logging layer yourself. It's useful when you need to monitor costs per application or per customer, not just in aggregate. See the docs or quickstart for how usage data is returned on each call, and pricing for plan details if you're deciding between Solo, Team, and Scale seats.

Whether you build your own logging pipeline or use a layer like this, the principle is the same: capture token usage at the source, attach context to it, and aggregate often enough to catch drift before it shows up as a surprise invoice.

FAQ

Does the Claude API report token usage automatically? Yes — every Messages API response includes a usage object with input_tokens and output_tokens. You don't need to count tokens yourself; just log what's returned.

How often should I check token costs? Daily aggregation is enough for most teams, but set automated threshold alerts so you're notified immediately if spend spikes, rather than discovering it during a weekly review.

Can I monitor costs per user or per feature, not just overall? Yes, as long as you attach metadata (user ID, feature name) to each logged request. Without that tag, you'll only see total spend, not where it's coming from.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →