Per-User Spending Limits

Relai allows you to set dollar-based spending limits for individual end-users. This enables fine-grained cost control when building applications where multiple users consume AI resources.

How It Works

Pass the user field in your chat completion requests to identify end-users. Relai tracks spend per user and enforces quotas you configure.

{
  "model": "anthropic/claude-sonnet-4",
  "messages": [{"role": "user", "content": "Hello"}],
  "user": "user_abc123"
}

Quota Types

QuotaDescriptionResets
monthly_quota_dollarsMaximum spend per calendar month1st of each month (UTC)
daily_quota_dollarsMaximum spend per dayMidnight UTC

Setting Quotas

Organization Defaults

Set default quotas that apply to all new users in your organization via the dashboard settings or API:

PATCH /v1/orgs/{org_id}/settings
{
  "default_user_monthly_quota_dollars": 10.00,
  "default_user_daily_quota_dollars": 1.00,
  "default_alert_threshold": 0.8
}

Per-User Overrides

Override defaults for specific users:

POST /v1/users
{
  "external_id": "user_abc123",
  "monthly_quota_dollars": 50.00,
  "daily_quota_dollars": 5.00,
  "alert_threshold": 0.9
}

Soft Alerts (Warnings)

When a user exceeds their alert_threshold (default 80%), Relai adds a warning to the response. The request still succeeds.

Non-Streaming Response

Warnings appear in the relai.warnings array:

{
  "id": "gen-abc123",
  "choices": [...],
  "usage": {...},
  "relai": {
    "warnings": [
      {
        "code": "end_user_quota_soft_threshold",
        "message": "End user has reached 85% of monthly quota ($0.85 of $1.00)",
        "period": "monthly",
        "percent": 0.85
      }
    ]
  }
}

Streaming Response

Warnings are sent as a final SSE event before [DONE]:

event: relai.warning
data: {"code":"end_user_quota_soft_threshold","period":"monthly","percent":0.85}

data: [DONE]

Hard Caps (Blocking)

When a user reaches 100% of their quota, requests are rejected with HTTP 429:

{
  "error": {
    "code": "end_user_quota_exceeded",
    "message": "End user monthly quota exceeded",
    "type": "api_error"
  }
}

Important: Requests without a user field are unaffected and continue using the organization balance normally.

Checking User Spend

Get a user's current spend and quotas:

GET /v1/users/user_abc123

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "external_id": "user_abc123",
  "monthly_quota_dollars": 10.00,
  "daily_quota_dollars": 1.00,
  "alert_threshold": 0.8,
  "monthly_spend_dollars": 3.45,
  "daily_spend_dollars": 0.72,
  "created_at": "2026-05-01T10:00:00Z"
}

User Management API

MethodEndpointDescription
POST/v1/usersCreate or update a user
GET/v1/usersList all users with spend data
GET/v1/users/{external_id}Get user details and spend
PATCH/v1/users/{external_id}Update user quotas
DELETE/v1/users/{external_id}Delete a user

Best Practices

  • Set organization defaults — Configure sensible defaults so new users are protected automatically.
  • Monitor warnings — Check for relai.warnings in responses to notify users before they hit hard caps.
  • Use both quotas — Daily limits prevent runaway spend within a month; monthly limits control total cost.
  • Adjust thresholds — Lower the alert_threshold for users who need more warning time.

Example: SaaS with Tiered Plans

// Free tier: $1/month
await fetch("/v1/users", {
  method: "POST",
  headers: { "Authorization": "Bearer " + apiKey },
  body: JSON.stringify({
    external_id: user.id,
    monthly_quota_dollars: 1.00,
    daily_quota_dollars: 0.10,
  }),
});

// Pro tier: $50/month
await fetch("/v1/users", {
  method: "PATCH",
  headers: { "Authorization": "Bearer " + apiKey },
  body: JSON.stringify({
    monthly_quota_dollars: 50.00,
    daily_quota_dollars: 5.00,
  }),
});

Next Steps