← Blog

How to Build a Claude API Usage Alert System

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

What a Usage Alert System Actually Does

A Claude API usage alert system watches your token consumption, request volume, and error rates in real time, then notifies you — via Slack, email, or a webhook — when something crosses a threshold you define. The goal isn't just cost control. It's catching a runaway prompt loop, a misbehaving key, or an approaching rate limit before it becomes an outage or a surprise invoice.

Building one requires three things: a reliable source of usage data per request, a rule engine that compares that data against thresholds, and a delivery mechanism that gets the alert to a human fast. Below is a practical way to build this yourself, whether you're calling Claude directly or routing through a gateway like SubToAPI that already exposes usage metadata per key.

Why This Matters More Than It Looks

Token usage on LLM APIs doesn't fail loudly. A bug that causes a prompt to loop or balloon in context size won't throw an error — it'll just quietly burn through tokens and money until someone notices the bill. Teams with multiple API keys (staging, production, per-customer, per-feature) are especially exposed, because nobody is watching all of them at once.

The fix isn't "check the dashboard more often." It's automated thresholds that page someone when behavior deviates from normal.

What to Track

Before writing any code, decide what actually matters for your product:

You don't need all five on day one. Token volume and error rate cover most real incidents.

Step 1: Capture Usage Data on Every Call

Every Claude response includes a usage object with input_tokens and output_tokens. The cheapest, most reliable way to build an alert system is to log this on every call rather than polling a separate endpoint later.

async function callClaude(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({
    keyId: process.env.SUBTOAPI_KEY_ID,
    inputTokens: data.usage.input_tokens,
    outputTokens: data.usage.output_tokens,
    timestamp: Date.now(),
    status: res.status
  });

  return data;
}

logUsage can write to Postgres, a Redis counter, or even a flat log file — the important part is that it happens on every call, synchronously with the request, so you never lose a data point.

Step 2: Define Thresholds as Code, Not Memory

Hardcode your thresholds somewhere versioned, not in your head:

const ALERT_RULES = {
  hourlyTokenLimit: 500_000,
  dailyCostLimitEUR: 50,
  errorRatePercent: 5,
  requestSpikeMultiplier: 3 // vs. same hour yesterday
};

Cost estimates don't need to be exact — a rough tokens-to-cost multiplier based on your plan is enough to catch a 10x anomaly. Precision matters far less than speed of detection here.

Step 3: Run a Checker on a Schedule

A simple cron job (every 5–15 minutes) that queries your usage log and compares against ALERT_RULES is enough for most teams — you don't need a streaming anomaly detector for this.

async function checkUsageAlerts() {
  const stats = await getUsageLastHour();

  if (stats.totalTokens > ALERT_RULES.hourlyTokenLimit) {
    await sendAlert(`Token usage spike: ${stats.totalTokens} tokens in the last hour`);
  }

  if (stats.errorRate > ALERT_RULES.errorRatePercent) {
    await sendAlert(`Error rate at ${stats.errorRate}% over the last hour`);
  }

  if (stats.requestCount > stats.yesterdaySameHour * ALERT_RULES.requestSpikeMultiplier) {
    await sendAlert(`Request volume ${stats.requestCount}, 3x yesterday's baseline`);
  }
}

Run this via a scheduled job (cron, a serverless scheduled function, or a worker queue tick) rather than inside your API request path — alert checks should never add latency to real user traffic.

Step 4: Deliver the Alert Somewhere People Actually See It

Email gets ignored. Slack and PagerDuty don't.

async function sendAlert(message) {
  await fetch(process.env.SLACK_WEBHOOK_URL, {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ text: `🚨 Claude usage alert: ${message}` })
  });
}

For anything cost-related, route to a channel someone checks daily. For error-rate or rate-limit alerts, route to wherever your on-call engineer already gets paged — those need faster response times.

Per-Key Alerts Matter More Than Global Ones

A single global "total tokens this month" number tells you something is wrong but not what. If you issue separate keys per environment, per customer, or per feature — which you should — attribute every usage log entry to a keyId and run the same threshold checks per key, not just in aggregate. This is how you catch "customer X's integration is in a retry loop" instead of just "spend is up 40% this month, no idea why."

If you're already running your Claude traffic through SubToAPI, each sub_live_... application key gets its own usage metadata on every response and its own line item in the dashboard, so the per-key attribution step is already done for you — you're just adding the threshold and delivery layer on top. See /docs/messages for the full response shape, including the usage object, and /pricing for how plans map to seats and keys if you're scaling this across a team.

Avoiding Alert Fatigue

A usage alert system that fires constantly gets muted within a week. Start with wide thresholds (2–3x your normal baseline) and tighten them once you've watched a week of real data. Separate "informational" alerts (daily cost summary) from "actionable" alerts (error spike, hard limit approaching) into different channels so the urgent ones don't get buried.

Questions

Do I need a database to track usage, or can I just use logs? Logs are fine to start. A simple append-only log file or table with timestamp, token counts, and key ID is enough to compute hourly/daily rollups. Move to a real time-series store only once you're running aggregate queries often enough that log parsing gets slow.

Should alerts be based on tokens or dollar cost? Track both, but alert on tokens first — token counts are exact and immediate, while cost is a derived estimate. Use cost alerts for daily/weekly budget summaries and token alerts for real-time anomaly detection.

Can I get usage alerts without building this myself? Some gateways expose usage dashboards and per-key metadata out of the box, which removes the data-capture step described above. If you're using SubToAPI, you can pull usage metadata directly from the API responses or the dashboard and skip straight to Step 2 — defining thresholds — rather than building the logging layer from scratch. Start with a free trial if you want to test this against real traffic.

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 →