Documentation
Budget limits
Proxide lets you set hard spending limits per agent or user. When a limit is exceeded, requests are blocked and a 402 response is returned — before the request ever reaches the LLM provider.
How it works
Each request can include an x-proxide-client-id header that identifies the agent or user making the call. Proxide tracks cumulative spend per client ID and enforces limits you configure per-client or globally.
- 1Request arrives at Proxide with
x-proxide-client-id: user-123 - 2Proxide looks up the configured budget for
user-123and checks current spend - 3If within budget: request is forwarded to the LLM provider, token cost is recorded
- 4If over budget: Proxide returns
402 Payment Requiredimmediately — the LLM is never called
Identifying agents with client IDs
Pass the x-proxide-client-id header with any string that identifies the agent or user. This can be a user ID, tenant ID, agent name, or any other identifier meaningful to your application.
const response = await client.chat.completions.create(
{
model: "gpt-4o",
messages: [{ role: "user", content: userMessage }],
},
{
headers: {
"x-proxide-client-id": `user-${user.id}`,
// Examples: "agent-summarizer", "tenant-acme", "user-12345"
},
}
);response = client.chat.completions.create(
model="gpt-4o",
messages=[{"role": "user", "content": user_message}],
extra_headers={
"x-proxide-client-id": f"user-{user.id}",
}
)Requests without an x-proxide-client-id header are tracked under a default __default__ client and can have their own budget rule.
Configuring budget limits
Via the dashboard
Go to Agents → Budget Rules in your Proxide dashboard. You can set:
- Per-client rules: Set different limits for specific client IDs
- Global default: A fallback limit applied to all client IDs without a specific rule
- Daily limit: Resets at midnight UTC each day
- Monthly limit: Resets on the 1st of each month
Via the API
# Set a budget rule for a specific client
curl -X POST https://api.proxide.ai/v1/budgets \
-H "Authorization: Bearer prox-your-key-here" \
-H "Content-Type: application/json" \
-d '{
"client_id": "user-12345",
"daily_limit_usd": 0.50,
"monthly_limit_usd": 5.00,
"action": "block"
}'
# Set a global default budget
curl -X POST https://api.proxide.ai/v1/budgets \
-H "Authorization: Bearer prox-your-key-here" \
-H "Content-Type: application/json" \
-d '{
"client_id": "__default__",
"daily_limit_usd": 1.00,
"monthly_limit_usd": 10.00,
"action": "block"
}'The action field supports block (returns 402) or alert (logs a warning but allows the request through).
Handling budget exceeded (402)
When a client exceeds its budget, Proxide returns a 402 Payment Required response with a structured error body:
{
"error": {
"type": "budget_exceeded",
"message": "Daily budget of $0.50 exceeded for client user-12345",
"client_id": "user-12345",
"limit_type": "daily",
"limit_usd": 0.50,
"spent_usd": 0.52,
"resets_at": "2026-03-16T00:00:00Z"
}
}Handling the error in your app
import OpenAI from "openai";
async function chat(userId: string, message: string) {
try {
const response = await client.chat.completions.create(
{
model: "gpt-4o",
messages: [{ role: "user", content: message }],
},
{
headers: { "x-proxide-client-id": `user-${userId}` },
}
);
return response.choices[0].message.content;
} catch (error) {
if (error instanceof OpenAI.APIError && error.status === 402) {
const detail = error.error as {
type: string;
limit_type: string;
resets_at: string;
};
if (detail.type === "budget_exceeded") {
const resetTime = new Date(detail.resets_at).toLocaleString();
return `You've reached your ${detail.limit_type} AI usage limit. \
It resets at ${resetTime}.`;
}
}
throw error;
}
}Checking current spend
Every response includes headers showing the current spend for the client ID:
x-proxide-client-id: user-12345
x-proxide-daily-spend-usd: 0.38
x-proxide-daily-limit-usd: 0.50
x-proxide-monthly-spend-usd: 2.15
x-proxide-monthly-limit-usd: 5.00You can also query current spend programmatically via the GET /v1/budgets/{client_id}/spend endpoint.