← Blog

Claude API Budget Alerts: Slack Notification Setup

2026-10-22 · 5 min read · SubToAPI Team

If you're searching for a built-in way to get a Slack ping when your Claude API spend crosses a threshold, the short answer is: Anthropic's console doesn't offer native Slack alerting. There's no toggle in the dashboard that says "notify #billing when I hit $500." You have to build the tracking and the notification yourself, or use a layer on top of the API that exposes usage data you can act on.

This guide shows both paths: a DIY approach using token usage from API responses plus a Slack webhook, and a faster setup if you're already routing Claude calls through a proxy that reports per-key usage.

Why this is harder than it sounds

Claude's API bills by tokens, not by a running dashboard figure you can poll in real time. Anthropic shows usage in the console with a delay, and there's no public "current spend" endpoint you can query every five minutes. That means any budget alert system you build has to:

  1. Capture token usage from every response (usage.input_tokens, usage.output_tokens)
  2. Convert tokens to cost based on the model's per-million-token pricing
  3. Accumulate that cost somewhere (database, Redis counter, log aggregator)
  4. Compare the running total against a threshold
  5. Fire a Slack message when the threshold is crossed

Most teams skip step 2 and 3 because they require maintaining a pricing table that changes whenever Anthropic ships a new model tier.

DIY: tracking cost and posting to Slack

Every Claude response includes a usage object. You can extract it and log it alongside a cost calculation:

const PRICING = {
  "claude-opus-4": { input: 15, output: 75 },   // $ per million tokens
  "claude-sonnet-4": { input: 3, output: 15 },
};

function calculateCost(model, usage) {
  const rate = PRICING[model];
  const inputCost = (usage.input_tokens / 1_000_000) * rate.input;
  const outputCost = (usage.output_tokens / 1_000_000) * rate.output;
  return inputCost + outputCost;
}

Store the running total (Redis INCRBYFLOAT works well) and check it after every call:

const spend = await redis.incrbyfloat("daily_spend", cost);

if (spend >= DAILY_BUDGET && !alreadyAlertedToday) {
  await fetch(process.env.SLACK_WEBHOOK_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      text: `:rotating_light: Claude API daily spend hit $${spend.toFixed(2)}, budget is $${DAILY_BUDGET}.`,
    }),
  });
  await redis.set("alerted_today", "1", "EX", 86400);
}

This works, but you're now maintaining a pricing table, a cost calculator, a counter reset job (daily/monthly), and dedup logic so you don't spam the channel on every request once you're over budget. It's a reasonable weekend project — but it's infrastructure you own forever, and it breaks silently if Anthropic updates pricing and nobody updates the constant.

Per-key and per-team budgets

If multiple services or team members share one Anthropic key, this gets worse: you have no way to isolate whose calls caused the spike. You'd need to tag every request with a service name before it hits the API, then key your Redis counters by that tag.

The simpler path: usage metadata per application key

A cleaner way to get budget visibility without rebuilding billing math is to put a layer between your app and Claude that already issues per-application API keys and reports usage per key. That's what SubToAPI does: it turns your existing Claude access into an HTTPS API with sub_live_... keys you can hand out per project, per team, or per environment, and each key's usage shows up in one dashboard.

With usage already split by key, your Slack alert logic shrinks to a single check instead of a whole cost-tracking pipeline:

curl https://api.subtoapi.app/v1/messages \
  -H "Authorization: Bearer $SUBTOAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-sonnet-4",
    "max_tokens": 1024,
    "messages": [{"role": "user", "content": "Summarize this ticket."}]
  }'

Every response still returns the standard usage block, so you can keep the same Slack webhook code above — you just no longer need to maintain the pricing table or worry about losing counters on a redeploy, because usage is tracked server-side per key. If you're running a team, you can give each engineer or service their own key under Team (€19/seat) or Scale (€49/seat) and watch spend per key instead of one undifferentiated number. Solo plans start at €9 for a single key. See /pricing for the full breakdown, and /docs/messages for the exact shape of the usage object returned on every call.

Building the actual Slack alert, either way

Regardless of where your usage numbers come from, the Slack side is identical:

  1. Create an Incoming Webhook in your Slack workspace (Slack app settings → Incoming Webhooks → Add New Webhook).
  2. Store the webhook URL as an environment variable, never in code.
  3. Pick thresholds that matter: a soft warning at 75% of budget, a hard alert at 100%, and optionally a "spend velocity" alert if you burn 50% of a monthly budget in the first week.
  4. Dedup alerts so a loop or retry storm doesn't flood the channel — gate each threshold to fire once per period.
  5. Include actionable context in the message: which key/service triggered it, current total, and a link to your dashboard.
function buildSlackMessage(service, spend, budget) {
  const pct = Math.round((spend / budget) * 100);
  return {
    text: `*${service}* Claude API spend: $${spend.toFixed(2)} (${pct}% of $${budget} budget)`,
  };
}

If you're prototyping this quickly, start with /docs/quickstart to get a working key and a first call in minutes, then wire the Slack webhook on top once you see real usage numbers flowing in.

Don't forget streaming and tool calls

If part of your traffic uses streaming responses, usage data arrives in the final SSE event rather than a single JSON body — make sure your cost calculator reads from the message_stop event, not an earlier chunk. Details are in /docs/streaming. Similarly, if your Claude calls include tool use, token counts include the tool schema and tool results, which can be a bigger share of cost than people expect — see /docs/tools if you want to measure that overhead separately.

questions

Does Anthropic's Claude console support native Slack alerts? No. The console has no built-in Slack or webhook integration for budget thresholds. You have to track usage yourself from API responses or use a proxy layer that reports it per key.

How do I calculate Claude API cost from a response? Use the usage.input_tokens and usage.output_tokens fields returned with every response, multiply by the model's per-million-token input/output rates, and accumulate the result in a counter you control.

Can I get separate budget alerts per team member or project? Yes, if each one calls Claude through its own API key with usage reported per key — either by tagging requests yourself in a DIY tracker or by issuing separate keys through a service like SubToAPI, which shows usage per key in the dashboard.

Turn your Claude access into an HTTPS API

SubToAPI gives you application API keys, streaming, tool use and usage insights on top of your existing Claude access — set up in minutes.

Start free  Read the quickstart →