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.

  1. 1Request arrives at Proxide with x-proxide-client-id: user-123
  2. 2Proxide looks up the configured budget for user-123 and checks current spend
  3. 3If within budget: request is forwarded to the LLM provider, token cost is recorded
  4. 4If over budget: Proxide returns 402 Payment Required immediately — 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.

TypeScript
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"
    },
  }
);
Python
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

curl
# 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:

JSON response
{
  "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

TypeScript
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:

Response headers
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.00

You can also query current spend programmatically via the GET /v1/budgets/{client_id}/spend endpoint.