How to Track Claude API Spend Per Project
If you're running multiple products, clients, or internal tools on top of Claude, the native Anthropic console gives you one combined usage number. That's fine until you need to answer questions like "which project burned €400 last week" or "should we bill this client for their Claude usage." To track Claude API spend per project, you need per-project API keys, consistent request tagging, and a way to aggregate usage data without building a billing system from scratch.
The short answer: separate your API keys by project (not by environment or team member), log token usage and cost per request at the application layer, and pull that into a dashboard or spreadsheet on a schedule. The rest of this article covers how to actually set that up, including a faster path if you don't want to maintain the tracking layer yourself.
Why Project-Level Tracking Is Hard With a Single API Key
Anthropic's console shows usage tied to your account, not to how you've organized your work. If three projects share one API key, the only way to split costs after the fact is to parse logs by request metadata you added yourself — assuming you added any.
This becomes a real problem in a few common situations:
- Agencies building Claude-powered features for multiple clients who need itemized invoices
- Internal teams running several products (support bot, content generator, internal search) off one Anthropic account
- Startups with separate environments (staging, demo, production) that keep conflating spend
- Freelancers who want to know if a specific client project is actually profitable at current token usage
Without separation at the key level, you're stuck reconstructing cost allocation from timestamps and guesswork.
Method 1: One API Key Per Project
The most reliable way to track spend per project is to give each project its own API key. This works whether you're calling Claude directly or through a proxy layer.
curl https://api.subtoapi.app/v1/messages \
-H "Authorization: Bearer $SUBTOAPI_KEY_PROJECT_A" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-sonnet-4",
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Summarize this ticket."}]
}'
With a dedicated key per project, every request is automatically attributable. If you're issuing keys manually through Anthropic's console, you'll need to track key-to-project mapping yourself in a spreadsheet or internal admin panel. If you're using a layer like SubToAPI, each application key (sub_live_...) is scoped and viewable independently in the dashboard, so spend per key is already segmented without extra bookkeeping. See /docs/quickstart for how key issuance works.
Method 2: Log Usage Metadata on Every Request
Every Claude API response includes token counts in the usage field. If you're not already capturing this, start logging it alongside a project_id tag at the point where you make the request:
async function callClaude(projectId, messages) {
const res = await fetch("https://api.subtoapi.app/v1/messages", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.SUBTOAPI_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
model: "claude-sonnet-4",
max_tokens: 1024,
messages
})
});
const data = await res.json();
await logUsage({
project_id: projectId,
input_tokens: data.usage.input_tokens,
output_tokens: data.usage.output_tokens,
model: data.model,
timestamp: new Date().toISOString()
});
return data;
}
Store these rows in whatever database you already use — Postgres, a logging service, even a flat file for low volume. The key is consistency: every call that touches Claude should write a usage row with a project identifier attached. See /docs/messages for the full response schema including usage fields.
Method 3: Aggregate and Convert to Cost
Token counts alone don't tell you spend — you need to multiply by the current per-model pricing (input and output tokens are priced differently, and pricing varies by model). A simple daily aggregation job can turn your logged usage into a cost-per-project report:
SELECT
project_id,
SUM(input_tokens) AS total_input,
SUM(output_tokens) AS total_output,
SUM(input_tokens * 0.000003 + output_tokens * 0.000015) AS estimated_cost_usd
FROM claude_usage_log
WHERE timestamp >= NOW() - INTERVAL '30 days'
GROUP BY project_id
ORDER BY estimated_cost_usd DESC;
Adjust the per-token rates to match the model you're calling — rates differ across Claude model tiers. This query gives you a ranked list of which projects are driving spend, which is usually the first thing a manager or client asks for.
Method 4: Skip the Logging Layer Entirely
If building and maintaining a usage-logging pipeline isn't worth the engineering time, a gateway that already separates keys by application and tracks usage per key removes most of this work. SubToAPI issues a distinct sub_live_... key per project or app, and the dashboard shows request volume, token usage, and streaming activity broken down by key — so "spend per project" becomes "spend per key" with no custom logging required. Plans start at €9/month for solo use and scale to per-seat team pricing; see /pricing for details, or /signup to start a free trial and test it against a real project.
This doesn't replace fine-grained cost accounting if you need exact per-client invoices down to the cent, but it covers the 90% case: knowing at a glance which project, client, or environment is consuming the most Claude usage without writing a custom logging pipeline first.
Picking the Right Level of Granularity
Before building anything, decide what "per project" actually means for your case:
- Per client — separate key per client, useful for agencies that need to bill usage back
- Per environment — separate key for staging vs. production to catch runaway test scripts
- Per feature — separate key per internal feature (chatbot vs. summarizer vs. search) to see which feature is expensive to run
- Per team — separate key per team if you're on a Team or Scale plan with seat-based billing (/pricing)
Most teams start with one of these and add more granularity once the first cost report turns up something surprising.
questions
Do I need to use separate API keys to track spend per project? Not strictly — you can tag requests with a project ID in your own logs — but separate keys make attribution automatic and prevent one project's logging bug from corrupting another's data.
Can I track streaming request costs the same way as regular requests? Yes. Streaming responses still return final usage metadata once the stream completes, so you log it the same way after the stream ends. See /docs/streaming for implementation details.
How often should I aggregate and review per-project spend? Daily aggregation with a weekly review is enough for most teams. If you're billing clients directly for usage, aggregate at least daily so discrepancies are caught before the billing cycle closes.