Skip to content
SpendByTeam

Install SpendByTeam

Two minutes per developer, or one file for the whole org. Nothing is proxied: your coding agent keeps talking to its provider directly and sends usage metrics to us on the side.

1. Requirements

  • Claude Code 2.1.269 or newer for per-repository attribution out of the box. Older versions still work — projects are then attributed through the hook instead.
  • git, jq and curl on the developer’s machine (used by the context hook). The installer checks for them.
  • macOS, Linux or Windows via WSL.
  • An ingest token from Settings → Ingest tokens in the dashboard. It starts with sbt_ing_ and can only write data, never read it.

2. Install on one machine

Run this in any terminal. It doesn’t need to be inside a repository.

terminalbash
npx spendbyteam init --token=sbt_ing_xxxxxxxxxxxxxxxx

That’s the whole install. Start a new coding session and spend shows up in the dashboard within about a minute.

3. What the installer changes

Nothing is overwritten. The installer merges into your existing settings and keeps a backup first.

  1. Checks your agent version and warns if it’s older than 2.1.269.
  2. Backs up ~/.claude/settings.json to settings.json.bak, then merges in an env block (metrics on, logs and traces off) and two async hooks.
  3. Writes ~/.spendbyteam/config.json with your token and endpoint, readable only by you (chmod 600).
  4. Copies the context hook to ~/.spendbyteam/hook.sh.
  5. Sends a test ping so the dashboard can show the machine as connected.

The hooks it registers:

~/.claude/settings.json (excerpt)json
{
  "hooks": {
    "SessionStart": [
      { "hooks": [{ "type": "command", "command": "~/.spendbyteam/hook.sh", "async": true, "timeout": 10 }] }
    ],
    "CwdChanged": [
      { "hooks": [{ "type": "command", "command": "~/.spendbyteam/hook.sh", "async": true, "timeout": 10 }] }
    ]
  }
}

The hook only sends session ID, repository URL, branch and ticket. See the full payload. Repository-level .claude/settings.json files can’t configure OpenTelemetry exporters, which is why the install happens at user or managed level.

4. Verify the connection

terminalbash
npx spendbyteam status   # token, endpoint, last successful send
npx spendbyteam doctor   # checks version, git/jq/curl, settings and network

In the dashboard, new developers appear automatically the first time they send data, with a prompt to assign them to a team.

5. Org-wide rollout with managed settings

On Team and Enterprise plans of your coding agent, an admin can push settings to every developer at once. Generate the file withnpx spendbyteam print-managed --token=…, or copy this and replace the token:

managed-settings.jsonjson
{
  "env": {
    "CLAUDE_CODE_ENABLE_TELEMETRY": "1",
    "OTEL_METRICS_EXPORTER": "otlp",
    "OTEL_LOGS_EXPORTER": "none",
    "OTEL_TRACES_EXPORTER": "none",
    "OTEL_EXPORTER_OTLP_PROTOCOL": "http/json",
    "OTEL_EXPORTER_OTLP_ENDPOINT": "https://ingest.spendbyteam.com",
    "OTEL_EXPORTER_OTLP_HEADERS": "Authorization=Bearer sbt_ing_xxxxxxxx",
    "OTEL_METRICS_INCLUDE_SESSION_ID": "true",
    "OTEL_METRICS_INCLUDE_REPOSITORY": "true",
    "OTEL_METRICS_INCLUDE_VERSION": "true",
    "OTEL_METRIC_EXPORT_INTERVAL": "60000"
  }
}

Two things worth knowing:

  • When the endpoint and headers come from managed settings, the agent ignores any endpoint a developer sets locally — data can’t be redirected elsewhere.
  • Set OTEL_LOGS_EXPORTER and OTEL_TRACES_EXPORTER to none explicitly. Unlike the endpoint, they aren’t locked implicitly.

Managed settings cover usage metrics, which is enough for per-project spend. For branch and ticket breakdowns, developers also run npx spendbyteam init once to install the hook.

6. Assign teams

The simplest way is in the dashboard: Developers → Assign team. If you’d rather manage it in config, add a static resource attribute to the managed settings for each group:

managed-settings.json (env)json
"OTEL_RESOURCE_ATTRIBUTES": "team.id=mobile"

The value is static — shell expressions like $(…) are not expanded.

7. Cloud sessions

Sessions running in the provider’s cloud don’t read your local ~/.claude/settings.json. To include them, set the same env block through server-managed settings in your organization’s admin console. Repository attribution works the same way; branch context depends on hooks being available in that environment.

8. Uninstall

terminalbash
npx spendbyteam uninstall

Removes the env block and hooks it added, deletes ~/.spendbyteam, and leaves every other setting untouched. Revoke the token in the dashboard to stop ingestion server-side as well.

9. Troubleshooting

SymptomLikely cause
No data after 5 minutesThe session was started before install. Start a new one. Then run npx spendbyteam doctor.
Spend shows as “Unattributed”Agent older than 2.1.269 and the hook isn’t installed, or the session ran outside a git repository.
No branch / ticketjq missing, or the branch name has no ABC-123 pattern.
401 in doctorToken revoked or mistyped. Create a new one in Settings → Ingest tokens.
Numbers differ from the invoiceMetric cost is an estimate. Business plans can reconcile against the provider’s cost API.

Still stuck? [email protected] — include the output of doctor, which contains no secrets.