Enforcement
Handling blocks
When a budget is configured with action: "block" and a user hits their limit, the SDK throws a LLMBudgetExceededError. This page covers how to catch it, what information it contains, and how to return a graceful response to your user.
Start with warn, not block. The warn action lets calls proceed while still logging enforcement events and firing your callback. It's the safer default while you're getting set up — upgrade to block once you've added the error handling below.
Catching the error
Wrap your trackedCall() in a try/catch and check for LLMBudgetExceededError specifically. This lets you handle budget blocks differently from other errors.
import { trackedCall, LLMBudgetExceededError } from '@llmcosttracker/sdk'try {const response = await trackedCall({client, params, apiKey, userId: session.userId, tier: session.plan,})return response} catch (err) {if (err instanceof LLMBudgetExceededError) {// Return a graceful response to your userreturn {error: 'monthly_limit_reached', message: 'You have reached your monthly AI usage limit.',}}// Re-throw anything elsethrow err}Error properties
The LLMBudgetExceededError instance contains everything you need to build a useful response:
Telling the user when their limit resets
Use err.windowStart and err.windowType to calculate the reset date and surface it in your UI:
import { LLMBudgetExceededError } from '@llmcosttracker/sdk'function getResetDate(err: LLMBudgetExceededError): Date {const start = new Date(err.windowStart)if (err.windowType === 'day') {start.setUTCDate(start.getUTCDate() + 1)} else if (err.windowType === 'week') {start.setUTCDate(start.getUTCDate() + 7)} else {start.setUTCMonth(start.getUTCMonth() + 1)}return start}// In your catch block:if (err instanceof LLMBudgetExceededError) {const resetDate = getResetDate(err)return {error: 'monthly_limit_reached', message: `Your AI usage limit resets on ${resetDate.toLocaleDateString()}`,}}Using onBudgetWarning as an early signal
Even with action: "block", you can use the onBudgetWarning callback to get notified when a user hits your alert threshold — before they're blocked. Use this to show an in-app warning or send a notification proactively.
await trackedCall({client, params, apiKey, userId: session.userId, tier: session.plan, onBudgetWarning: (result) => {
// Fires at alert threshold (default 80%) — before the block
notifyUser(result.budgetConfig.userId, {
message: `You've used $${result.spendUsd.toFixed(2)} of your $${result.limitUsd} limit`,
})},})Testing enforcement locally
Use action: "dry_run" while developing. The call always proceeds, but the SDK logs a console warning whenever it would have blocked. This lets you validate your budget config and error handling before flipping to block in production.
// dashboard config: action = dry_run// console output when limit would be hit:// [llmcosttracker] dry_run: would have blocked user "user_123"// ($5.0023 of $5.00 month limit)Back to: Enforcement overview