Budget Controls
AI agents consume LLM tokens on every request, and token consumption translates directly to cost. Without budget controls, a single agent caught in a reasoning loop or processing unexpectedly large inputs can exhaust thousands of dollars in minutes. VeraID provides multi-tier budget enforcement that checks spend limits before tokens are consumed, preventing runaway costs at the source.
Budget Types
Every AI agent identity supports four budget controls, each independently configurable.
| Budget Type | Description | Example |
|---|---|---|
| Daily limit | Maximum spend per UTC day. Resets at midnight UTC. | $50.00/day |
| Monthly limit | Maximum spend per calendar month. Resets on the 1st of each month at midnight UTC. | $1,000.00/month |
| Per-request limit | Maximum spend for a single LLM call. Prevents individual requests from consuming disproportionate budget. | $2.00/request |
| Warning threshold | Percentage of any limit at which alerts are triggered. Does not block requests. | 80% |
Action on Exceed
When a budget limit is reached, VeraID takes one of three configurable actions.
Block
The request is rejected immediately with a 429 Budget Exceeded response. The agent receives a structured error indicating which limit was exceeded and when the budget resets. This is the default and recommended action.
{ "error": "BUDGET_EXCEEDED", "message": "Daily budget limit exceeded", "details": { "limit": 50.00, "spent": 49.87, "estimatedCost": 0.45, "resetsAt": "2026-03-20T00:00:00Z" }}Throttle
Requests are queued rather than rejected. The gateway holds the request and retries it after the budget resets or after an administrator manually increases the limit. Throttled requests have a configurable timeout (default: 30 minutes) after which they are dropped.
Alert Only
The request is allowed to proceed, but an alert is sent to configured notification channels (email, Slack, webhook). Use this action during initial rollout to understand spending patterns before enforcing hard limits.
Rate Limiting
In addition to cost-based budgets, VeraID enforces request rate limits to prevent agents from overwhelming LLM providers or consuming budget through high-frequency low-cost calls.
| Rate Limit | Description | Default |
|---|---|---|
| Requests per minute | Maximum LLM API calls per 60-second sliding window | 60 |
| Requests per hour | Maximum LLM API calls per 60-minute sliding window | 1,000 |
Rate limits are enforced independently of budget limits. A request can be within budget but still rate-limited, or within rate limits but over budget.
{ "agentConfig": { "tokenBudget": { "daily": 50.00, "monthly": 1000.00, "perRequest": 2.00 }, "rateLimits": { "requestsPerMinute": 30, "requestsPerHour": 500 } }}Creating an Agent with Budget Controls
API
curl -X POST https://app.veraid.io/api/v1/identities \ -H "Authorization: Bearer $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "research-assistant", "type": "AI_AGENT", "description": "Summarizes research papers and answers questions from the knowledge base", "tags": ["research", "production"], "agentConfig": { "provider": "anthropic", "modelIdentifier": "claude-sonnet-4", "capabilities": ["chat-completion", "retrieval"], "dataAccess": { "allowed": ["knowledge-base", "public-papers"], "denied": ["financial-records", "hr-data"] }, "monitoring": { "logAllRequests": true, "logResponses": false, "requireApproval": false }, "tokenBudget": { "daily": 25.00, "monthly": 500.00, "perRequest": 1.50, "warningThreshold": 0.80, "onExceed": "block" }, "rateLimits": { "requestsPerMinute": 20, "requestsPerHour": 300 } } }'SDK
import { VeraIDClient } from '@veraid/sdk';
const client = new VeraIDClient({ apiKey: process.env.VERAID_API_KEY, agentId: process.env.VERAID_AGENT_ID,});
const agent = await client.identities.create({ name: 'research-assistant', type: 'AI_AGENT', description: 'Summarizes research papers and answers questions from the knowledge base', tags: ['research', 'production'], agentConfig: { provider: 'anthropic', modelIdentifier: 'claude-sonnet-4', capabilities: ['chat-completion', 'retrieval'], dataAccess: { allowed: ['knowledge-base', 'public-papers'], denied: ['financial-records', 'hr-data'], }, monitoring: { logAllRequests: true, logResponses: false, requireApproval: false, }, tokenBudget: { daily: 25.0, monthly: 500.0, perRequest: 1.5, warningThreshold: 0.8, onExceed: 'block', }, rateLimits: { requestsPerMinute: 20, requestsPerHour: 300, }, },});Checking Budget at Runtime
Check Before Spending
Use checkBudget before making an LLM call to verify that the estimated cost is within limits. This prevents wasted computation on requests that would be rejected at the gateway.
// Estimate the cost of the upcoming requestconst estimatedCost = 0.03;
const budgetCheck = await client.agents.checkBudget(estimatedCost);
if (!budgetCheck.allowed) { console.error(`Budget check failed: ${budgetCheck.reason}`); console.error(`Resets at: ${budgetCheck.resetsAt}`); // Gracefully degrade or queue for later return;}
// Proceed with the LLM callconst response = await client.agents.complete({ model: 'claude-sonnet-4', messages: [{ role: 'user', content: userInput }],});The checkBudget response:
{ "allowed": true, "estimatedCost": 0.03, "daily": { "limit": 25.00, "spent": 12.47, "remaining": 12.53 }, "monthly": { "limit": 500.00, "spent": 187.23, "remaining": 312.77 }}Get Budget Status
Use getBudgetStatus to retrieve the current budget state without performing a check against a specific cost.
const status = await client.agents.getBudgetStatus();
console.log(`Daily: $${status.daily.spent} / $${status.daily.limit}`);console.log(`Monthly: $${status.monthly.spent} / $${status.monthly.limit}`);console.log(`Requests today: ${status.daily.requestCount}`);console.log(`Warning triggered: ${status.warningTriggered}`);{ "daily": { "limit": 25.00, "spent": 12.47, "remaining": 12.53, "requestCount": 142, "resetsAt": "2026-03-20T00:00:00Z" }, "monthly": { "limit": 500.00, "spent": 187.23, "remaining": 312.77, "requestCount": 4218, "resetsAt": "2026-04-01T00:00:00Z" }, "warningThreshold": 0.80, "warningTriggered": false, "onExceed": "block"}Cost Tracking
The gateway automatically tracks cost data for every LLM call made through a governed agent identity.
Per-Request Tracking
Each request records:
| Field | Description |
|---|---|
inputTokens | Number of tokens in the prompt |
outputTokens | Number of tokens in the response |
totalTokens | Sum of input and output tokens |
model | Model identifier used for the request |
costUsd | Calculated cost in USD based on model pricing |
timestamp | ISO 8601 timestamp of the request |
operation | Operation type (e.g., chat-completion, embedding, image-generation) |
Cumulative Tracking
VeraID maintains running totals at multiple granularities:
- Per-request — Individual cost for each LLM call
- Hourly — Aggregated spend per clock hour (for trend analysis)
- Daily — Aggregated spend per UTC day (for daily budget enforcement)
- Monthly — Aggregated spend per calendar month (for monthly budget enforcement)
- Lifetime — Total spend since the agent identity was created
Cost Analytics API
# Get cost breakdown for an agent over a time rangecurl -G https://app.veraid.io/api/v1/identities/{agentId}/costs \ -H "Authorization: Bearer $API_KEY" \ -d "startDate=2026-03-01" \ -d "endDate=2026-03-19" \ -d "granularity=daily"{ "agentId": "idt_9c3a8b7e-4f21-4d6a-b8e1-a2c5d9f07e3b", "period": { "start": "2026-03-01T00:00:00Z", "end": "2026-03-19T23:59:59Z" }, "totalCost": 187.23, "totalRequests": 4218, "totalTokens": 2847392, "byDay": [ { "date": "2026-03-01", "cost": 8.42, "requests": 198, "inputTokens": 52340, "outputTokens": 31204 } ], "byModel": [ { "model": "claude-sonnet-4", "cost": 142.18, "requests": 3102, "percentage": 75.9 }, { "model": "gpt-4o", "cost": 45.05, "requests": 1116, "percentage": 24.1 } ]}What’s Next
- Prompt Injection Detection — Protect agents from adversarial inputs
- Approval Workflows — Require human review for high-cost operations
- Agent Gateway — Understand the full request pipeline