Claude Code CLI Integration
Claude Code is Anthropic's official CLI. Pointing it at AI SpendOps lets you track token usage, cost, and cache hit rates per developer across your team.
What you get
Every prompt a developer runs through Claude Code is recorded as a usage event tagged with their name. From then on, the AI SpendOps dashboard can:
- Filter and group cost by developer
- Compare Claude Code traffic against your other Anthropic traffic (apps, workers, background jobs)
- Enforce per-key model allow-lists and dimension policies
Attribution is driven by a user dimension that each developer sets on their own machine — see How user attribution works below for the trust model.
Prerequisites
- A shared team AI SpendOps key. An admin provisions one
aso_k_...secretkey withallowed_providers: ["anthropic"]and adims_policythat requires auserdimension. See How to provision the team key at the bottom of this page. - A personal Anthropic API key (
sk-ant-api03-...). Each developer needs their own — it passes through the proxy untouched. AI SpendOps never sees or stores it. - Claude Code installed and working against
api.anthropic.comfirst. Runclaude "say hi"once before touching any of the env vars below, just to confirm the baseline works.
If you log into Claude Code with a Claude Pro or Claude Max subscription instead of an API key, AI SpendOps cannot see or track your traffic. This is not a limitation of AI SpendOps — it's enforced by Anthropic.
Subscription OAuth tokens (sk-ant-oat01-...) were proxyable through third-party tools until roughly February 2026, when Anthropic blocked third-party harnesses from using subscription quota against api.anthropic.com/v1/messages. The endpoint now returns "OAuth authentication is currently not supported." for any caller that isn't first-party Claude Code. See anthropics/claude-code#28091 for the definitive thread.
Independently, Anthropic's Consumer Terms §3(7) prohibit accessing the service "through automated or non-human means" except via an Anthropic API key — which makes third-party proxying of subscription traffic a terms-of-service issue even if the technical block were lifted.
To use AI SpendOps with Claude Code, you must log in with an API key. Run claude /login, choose the "API key" option, and paste an sk-ant-api03-... key. Subscription quota is lost, but you get full cost observability and the normal per-token billing applies to your Anthropic account.
Setup
Three environment variables. Set them once in your shell profile — Claude Code picks them up automatically.
Replace:
aso_k_yourkey.secretwith the shared team key from your adminsk-ant-api03-...with your personal Anthropic API keyalicewith your own name or username (this is the string that shows up in the dashboard)
macOS / Linux (bash, zsh)
export ANTHROPIC_BASE_URL="https://proxy.aispendops.com/v1/anthropic"
export ANTHROPIC_API_KEY="sk-ant-api03-..."
export ANTHROPIC_CUSTOM_HEADERS=$'X-ASO-API-Key: aso_k_yourkey.secret\nX-ASO-Dims: user=alice'
The $'...' quoting matters — ANTHROPIC_CUSTOM_HEADERS expects headers separated by literal newline characters. $'\n' gives you a real newline; a plain "\n" gives you the two characters backslash-n, which Claude Code will not parse correctly.
Add these lines to ~/.zshrc or ~/.bashrc to make them persistent.
Windows (PowerShell)
$env:ANTHROPIC_BASE_URL = "https://proxy.aispendops.com/v1/anthropic"
$env:ANTHROPIC_API_KEY = "sk-ant-api03-..."
$env:ANTHROPIC_CUSTOM_HEADERS = "X-ASO-API-Key: aso_k_yourkey.secret`nX-ASO-Dims: user=alice"
The backtick-n (`n) is PowerShell's newline escape. Add the same lines to your $PROFILE file to make them persistent across sessions.
Windows (cmd.exe)
cmd.exe has no ergonomic way to embed newlines in environment variables. Use PowerShell, WSL, or Git Bash instead.
Verify it works
-
Run a trivial prompt:
claude "say hi in one word" -
Open the AI SpendOps dashboard and filter to the team key. You should see a new event within a few seconds, tagged with your
userdimension. -
Confirm the enforcement works. Temporarily remove
X-ASO-DimsfromANTHROPIC_CUSTOM_HEADERSand re-runclaude "hi". The proxy should reject the request with400and the error messageAI SpendOps: require_dims violation. Put the header back once you've seen the rejection — this is the safety net that prevents attribution from silently going missing.
How user attribution works
The user dimension is set by each developer in their own shell environment. There is no cryptographic binding between the user value and the human typing the prompt — technically, anyone on the team could set user=bob and charge prompts to Bob's bucket.
This is fine for small teams that already trust each other (it's the same trust model as shared document drives or team VPN credentials), and it keeps the setup zero-overhead. If that trust model ever stops being appropriate (for example, you need SSO-backed, unspoofable attribution for compliance), talk to an AI SpendOps admin about upgrading to per-developer aso_ keys — the proxy forces tenant_id and api_key_id onto every event from the authenticated key, which cannot be spoofed from the client.
Troubleshooting
If a request fails, the proxy returns a 400 or 403 with a short error message. The common ones:
| Error | Cause | Fix |
|---|---|---|
AI SpendOps: Missing X-ASO-API-Key | ANTHROPIC_CUSTOM_HEADERS isn't set, or isn't reaching the proxy | Confirm the env var is exported in the shell you're running claude from. Run echo $ANTHROPIC_CUSTOM_HEADERS and verify both headers are present, separated by a real newline. |
AI SpendOps: Invalid X-ASO-API-Key (format) | The value you pasted doesn't start with aso_ | Get the correct team key from your admin — it should start with aso_k_. |
AI SpendOps: Invalid X-ASO-API-Key (unknown) | Key format is right but it isn't in the system | The key may have been rotated or disabled. Ask an admin to verify status in the Management Plane. |
AI SpendOps: require_dims violation | You didn't include a user dimension | Add X-ASO-Dims: user=yourname to ANTHROPIC_CUSTOM_HEADERS. |
AI SpendOps: Provider not allowed by API key policy | The team key isn't scoped to anthropic | Ask an admin to add anthropic to allowed_providers on the key. |
AI SpendOps: Model not allowed by API key policy | The model you're requesting isn't in the key's allowed_models list | Either switch models or ask an admin to widen the allow-list. |
Normal Anthropic 401 / invalid_api_key | Your sk-ant-api03-... is wrong or revoked | This error comes straight from Anthropic, not the proxy — fix your personal API key. |
If you see a "OAuth authentication is currently not supported" error, you're logged into Claude Code with a subscription (sk-ant-oat01-...) rather than an API key. Re-read the subscription warning above and run claude /login to switch to an API key.
Admin: provisioning the team key
This section is for AI SpendOps admins, not end users.
In the AI SpendOps management portal, create a new API key for the team that will use Claude Code. Scope it to the Anthropic provider and add user as an allowed dimension so each developer's name is captured on every request. Hand the resulting aso_k_...secret value to the developers who will use it — they paste it into their ANTHROPIC_CUSTOM_HEADERS env var alongside X-ASO-Dims: user=<name>. The key never reaches Anthropic, only AI SpendOps.
If the shared key leaks, create a new one in the management portal and disable the old one. Developers only need to update one line in their shell profile — their personal Anthropic API keys do not need to rotate.