Budgets
Budgets allow you to set spending and usage limits per user, team, or any Eloquent model in your application. When a limit is reached, Spectra can either block the request outright (hard limit) or fire a warning event while allowing the request to proceed (soft limit). This gives you fine-grained control over AI costs at the entity level, whether you need strict enforcement for billing compliance or gentle notifications for internal monitoring.
Setup
To enable budget tracking on a model, add the HasAiUsage trait. This is most commonly applied to your User model, but it can be added to any Eloquent model — teams, organizations, projects, or any other entity you want to budget:
use Spectra\Traits\HasAiUsage;
class User extends Authenticatable
{
use HasAiUsage;
}The trait provides methods for creating budgets, checking budget status, and querying remaining allowances. It uses a polymorphic relationship, so a single budget table supports any number of different model types.
Defining Budgets
Create a budget by calling setAiBudget() on any model that uses the HasAiUsage trait. All fields are optional — only set the limits you need. You can combine cost limits, token limits, and request-count limits in any combination:
$user->setAiBudget([
// Cost limits (in cents)
'daily_limit' => 1000, // $10/day
'weekly_limit' => 5000, // $50/week
'monthly_limit' => 20000, // $200/month
// Token limits
'daily_token_limit' => 500000,
'weekly_token_limit' => 2000000,
'monthly_token_limit' => 5000000,
// Request count limits
'daily_request_limit' => 200,
'weekly_request_limit' => 1000,
'monthly_request_limit' => 5000,
// Behavior
'hard_limit' => true, // Block requests when exceeded
'warning_threshold' => 80, // Fire event at 80% usage
'critical_threshold' => 95, // Fire event at 95% usage
// Optional: restrict to specific providers or models
'allowed_providers' => ['openai', 'anthropic'],
'allowed_models' => ['gpt-4o', 'claude-sonnet-4-20250514'],
]);The warning_threshold and critical_threshold values are percentages. When usage reaches these levels, Spectra fires events that you can listen to for notifications, logging, or any other action. Setting either threshold to 0 disables it.
Checking Budget Status
You can programmatically check whether a user or entity has exceeded their budget, retrieve detailed status information, or query remaining allowances:
// Has the user exceeded their budget?
if ($user->hasExceededBudget('openai', 'gpt-4o')) {
// Handle exceeded budget
}
// Get detailed budget status
$status = $user->getBudgetStatus('openai', 'gpt-4o');
// Get remaining budget
$remaining = $user->getRemainingBudget();Middleware Enforcement
For automatic enforcement on specific routes, Spectra provides the spectra.budget middleware. When a user's budget is exceeded and hard_limit is true, the middleware throws a BudgetExceededException, which results in a 429 Too Many Requests response. This prevents any AI requests from proceeding until the budget resets or is increased.
// Enforce budget for a specific provider and model
Route::middleware(['auth', 'spectra.budget:openai,gpt-4o'])
->post('/ai/chat', ChatController::class);
// Enforce budget using the default provider and model from config
Route::middleware(['auth', 'spectra.budget'])
->post('/ai/generate', GenerateController::class);When hard_limit is false, the middleware allows the request to proceed but still fires budget events, enabling you to implement soft warning behaviors such as sending notifications or displaying banners to the user.
Events
Spectra dispatches events when budget thresholds are reached, giving you the opportunity to send notifications, trigger alerts, or take any other action in response to budget pressure:
use Spectra\Events\BudgetThresholdReached;
use Spectra\Events\BudgetExceeded;
// Fired when usage reaches the warning or critical threshold
Event::listen(BudgetThresholdReached::class, function ($event) {
// $event->budget — the SpectraBudget model
// $event->threshold — 'warning' or 'critical'
// $event->percentage — current usage percentage
Notification::send($event->budget->budgetable, new BudgetWarning($event));
});
// Fired when the budget is fully exceeded
Event::listen(BudgetExceeded::class, function ($event) {
Log::warning("Budget exceeded for user {$event->budget->budgetable_id}");
});Budget Limits Reference
| Limit | Type | Description |
|---|---|---|
daily_limit | Cost (cents) | Maximum daily spend |
weekly_limit | Cost (cents) | Maximum weekly spend |
monthly_limit | Cost (cents) | Maximum monthly spend |
total_limit | Cost (cents) | Maximum lifetime spend |
daily_token_limit | Tokens | Maximum daily token usage (prompt + completion) |
weekly_token_limit | Tokens | Maximum weekly token usage |
monthly_token_limit | Tokens | Maximum monthly token usage |
total_token_limit | Tokens | Maximum lifetime token usage |
daily_request_limit | Requests | Maximum daily request count |
weekly_request_limit | Requests | Maximum weekly request count |
monthly_request_limit | Requests | Maximum monthly request count |
Configuration
Set global budget defaults in config/spectra.php. These values apply when individual budgets do not specify their own thresholds or behavior:
'budget' => [
'enabled' => true,
'default_provider' => 'openai',
'default_model' => 'gpt-4',
'warning_threshold' => 80,
'critical_threshold' => 95,
'hard_limit' => true,
],