How to Build a Claude API Usage Dashboard for Clients
If you resell Claude access, run an agency, or build products on top of Claude for multiple clients, you eventually hit the same wall: Anthropic's console shows you total usage, but it doesn't break anything down by client, project, or application key. You need a Claude API usage dashboard for clients that answers "how much did Client X use this month, and what did it cost?" — and the raw API doesn't give you that out of the box.
There are two ways to get there: build the tracking layer yourself on top of the Claude API, or use a layer that already separates usage by key, like SubToAPI. This article covers both, including what data you actually need to capture, how to structure it, and the fastest path if you don't want to maintain billing infrastructure.
What a Client-Facing Usage Dashboard Actually Needs
Before writing any code, define what "usage" means for your business. Most teams end up tracking the same core fields:
- Requests per client — how many calls each client/project made
- Input and output tokens — these are billed separately and at different rates
- Cost estimate — tokens converted to a dollar/euro figure per client
- Model used — if you let clients choose between models, cost varies a lot
- Time range — daily, weekly, monthly rollups for invoicing
- Rate limit headroom — so you can warn a client before they hit a cap
If you're billing clients individually, cost estimate and time range are non-negotiable. If you're just monitoring internal usage per project, requests and tokens are usually enough.
Option 1: Build It Yourself on the Raw Claude API
If you're calling the Claude API directly, usage data comes back in the response body of every request, not from a separate dashboard endpoint. A typical response includes an usage object with input_tokens and output_tokens. To build a per-client dashboard, you need to:
- Tag every outgoing request with a client identifier (in your own database, not in Claude's API)
- Store the
usageobject from every response against that client ID - Aggregate and multiply by your pricing to get cost
- Expose that aggregation through your own dashboard or API endpoint
A minimal logging wrapper looks like this:
async function callClaude(clientId, messages) {
const response = 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({
model: "claude-3-5-sonnet-20241022",
max_tokens: 1024,
messages,
}),
});
const data = await response.json();
await db.usageLogs.insert({
clientId,
inputTokens: data.usage.input_tokens,
outputTokens: data.usage.output_tokens,
model: data.model,
createdAt: new Date(),
});
return data;
}
This works, but it means you own the database schema, the aggregation queries, the pricing table (which changes), and the dashboard UI itself. For a single internal project that's fine. For a multi-client product, it becomes a maintenance burden fast — especially once you need per-client API keys, rate limits, and seat-based team access on top of usage tracking.
Option 2: Use Per-Client API Keys with Built-In Usage Metadata
A cleaner pattern is to issue each client (or each internal project) its own API key, and have the layer in front of Claude track usage per key automatically. This is exactly what SubToAPI does: it turns your Claude access into an HTTPS API where every request already returns usage metadata, and every key's consumption is visible in one dashboard.
Instead of building the logging table yourself, you create a key per client at /signup, give it to the client (or your own backend), and query usage by key:
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY" \
-H "content-type: application/json" \
-d '{
"model": "claude-3-5-sonnet-20241022",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Summarize this ticket."}]
}'
Every response from this endpoint includes usage data alongside the completion, so you don't need a separate polling job to reconcile numbers — the dashboard reflects what each sub_live_... key actually consumed. For teams managing multiple clients, this means:
- One key per client, so usage is naturally segmented without extra tagging logic
- A single dashboard showing requests, tokens, and cost per key
- Team seats (on the Team and Scale plans) if multiple people need to see or manage client keys
- No separate billing table to maintain for internal cost tracking
The full request/response format is documented at /docs/messages, and streaming responses — useful if clients are watching live output — follow the same usage-reporting pattern, covered in /docs/streaming. If your clients' workflows involve tool calls (function calling), those are tracked the same way and documented at /docs/tools.
Choosing Between the Two Approaches
| | Build it yourself | Per-client API keys (SubToAPI) | |---|---|---| | Setup time | Days to weeks | Minutes | | Maintenance | You own schema, pricing updates, UI | Dashboard maintained for you | | Per-client isolation | Manual tagging required | Native via separate keys | | Team access | Custom auth needed | Built-in seats | | Cost | Dev time + hosting | €9–€49/seat depending on plan (/pricing) |
If you're already deep into a custom billing system and usage tracking is a small add-on, building it yourself is reasonable. If usage-per-client is core to your product — you're reselling access, running an agency, or billing by consumption — a dashboard that's already built around per-key usage saves you from reinventing invoicing logic. Getting started takes about as long as reading the /docs/quickstart page.
Questions
Does the Claude API itself provide a per-client usage dashboard? No. Anthropic's console shows account-wide usage, not usage broken down by individual client or project. You need to either tag requests yourself and build aggregation, or use a layer like SubToAPI that separates usage by API key.
What's the minimum data I need to bill clients accurately? Input tokens, output tokens, and the model used per request, aggregated by client over a billing period. Token counts are returned in the usage field of every Claude API response, so you need to capture that value against a client identifier at request time.
Can I give each client their own API key instead of sharing one? Yes, and it's the simplest way to get automatic per-client usage separation. With SubToAPI you can create a distinct sub_live_... key per client from the dashboard, so usage, rate limits, and cost tracking are isolated per key without extra code.