Compare AI coding tool spend before and after a migration -- Cursor vs Claude Code, real numbers pulled from each vendor's own admin API, one command, zero runtime dependencies.
Project description
teamspend (Python)
Compare AI coding tool spend before and after a migration -- Cursor vs Claude Code, real numbers pulled from each vendor's own admin API, one command.
Why this exists
More teams are running more than one AI coding tool at once, or moving between them, than ever before. Cursor's Admin API reports Cursor spend. Anthropic's Claude Enterprise Analytics API reports Claude Code spend. Neither has a reason to show a competitor's number next to its own, so a team mid-migration is left opening two dashboards and doing the subtraction by hand. teamspend pulls both sides through the same normalized schema and prints one honest delta. This package is the Python distribution -- a genuine, independent port, not a wrapper around the Node binary.
Install
pip install teamspend
or with uv:
uv add teamspend
Zero runtime dependencies: the standard library's urllib handles every
admin-API call. The complementary JS/TS distribution installs the same way
on the npm side: npm install -g teamspend (or npx teamspend ... to run
it once without installing) -- see the
project README for
that package. Both are first-class, maintained together; neither is
deprecated in favor of the other.
Quickstart
export TEAMSPEND_CURSOR_TOKEN=<your Cursor Admin API key>
export TEAMSPEND_CLAUDE_CODE_TOKEN=<your Anthropic Admin/Analytics API key>
teamspend --tools cursor,claude-code \
--before 2026-04-01:2026-04-30 \
--after 2026-06-01:2026-06-30
Both credentials need org-admin-level access on their platform. If you can already see billing for your org, you have what you need.
Output (shape shown below; your real numbers come from your own org's API data):
teamspend snapshot -- migration cost comparison
Tools: cursor -> claude-code
BEFORE (cursor)
Total spend: $2140.00 (exact, usage-based)
Active users: 14
AFTER (claude-code)
Total spend: $1860.00 (exact, usage-based)
Active users: 14
DELTA: -$280.00 (-13.1%)
Full report: ./teamspend-snapshot-2026-07-16T2031.json
Exit code 0 means both periods fetched successfully, 1 means at least
one side failed (auth, a vendor API window limit, or a CLI argument
error) -- see DATA UNAVAILABLE in the terminal output and the error
field of the JSON report for the reason.
Using the library instead of the CLI
Both packages export a programmatic API for scripts and CI gates that want to call teamspend in-process instead of shelling out to a CLI binary.
TypeScript:
import { fetchCursorSpend, fetchClaudeCodeSpend, buildComparison } from 'teamspend';
Python:
from teamspend import fetch_cursor_spend, fetch_claude_code_spend, build_comparison, DateWindow, PeriodOutcome
before_window = DateWindow("2026-04-01", "2026-04-30")
after_window = DateWindow("2026-06-01", "2026-06-30")
before_result = fetch_cursor_spend(before_window, cursor_api_key)
after_result = fetch_claude_code_spend(after_window, claude_api_key)
report = build_comparison(
PeriodOutcome("before", "cursor", before_result, None),
PeriodOutcome("after", "claude-code", after_result, None),
)
print(report.delta_usd, report.delta_percent)
Both return the same shape of normalized data (total_cost_usd/
totalCostUsd, users, is_estimated/isEstimated) -- see
docs/concepts.md
for the full data model.
CSV import, for the history a live API can't reach
teamspend --tools cursor,claude-code \
--before 2025-11-01:2025-11-30 \
--after 2026-06-01:2026-06-30 \
--before-csv ./before.csv
CSV schema: date,user_email,cost_usd,is_estimated, one row per user per
day. Rows are aggregated per user_email.
Good to know before you run it
- This is a snapshot tool, not a running dashboard. It answers one question well and stops.
- The output includes real emails and dollar amounts, printed to your
terminal and saved to a report file (
0600permissions, auto-added to.gitignore). If you wire this into a scheduled CI job on a public repo, that data lands in your build logs, so check your CI provider's log visibility first. - Flat-seat and per-seat billing tiers (Cursor plans without usage overage, Claude.ai Team/Enterprise seats) don't expose true per-user cost through the vendor's own Admin API. When teamspend sees a user with real token or request activity but a reported cost of exactly $0, it marks that user's number, and the whole report, as estimated rather than showing a misleading exact-looking $0.
- Claude Code's Analytics API has no data before 2026-01-01. A window that
starts earlier raises
DataUnavailableErrorand, if--before-csv/--after-csvwas passed, falls back to the CSV import path for that side automatically.
Development
cd python
python3 -m venv .venv && source .venv/bin/activate
pip install -e ".[dev]"
pytest
Source lives under python/src/teamspend/, laid out to mirror the
TypeScript module structure 1:1 (adapters/, compare.py, output.py,
cli.py, types.py, errors.py, http_client.py) so a change in one
codebase has an obvious counterpart to check in the other. See
CONTRIBUTING.md.
License
Apache 2.0.
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file teamspend-0.1.0.tar.gz.
File metadata
- Download URL: teamspend-0.1.0.tar.gz
- Upload date:
- Size: 25.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
95c55fb8bd3e8347fb7fce8585dac676e0f9d45ed4e77c270e9f20abd3d20036
|
|
| MD5 |
cf0b9999384244fc509daa4c1ea041f1
|
|
| BLAKE2b-256 |
ea329a63c22abbbcd06fca73f05c349c1c0883a4ae4bedd5ac99f610a138cd6d
|
File details
Details for the file teamspend-0.1.0-py3-none-any.whl.
File metadata
- Download URL: teamspend-0.1.0-py3-none-any.whl
- Upload date:
- Size: 25.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.14.6
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
7daca1e135589571df7843a312a75cb597a89d44e8a14b57a8b68bee8db07b79
|
|
| MD5 |
95f5bd163e3fc28a690c2e99b98e2e38
|
|
| BLAKE2b-256 |
b4d0569c6cb0be72adb501c5a53c99035d3ea409569be61adac381d3cabf26db
|