Usage limits
Usage limits are an in-engine business quota: cap how many chat turns or agent steps a whole deployment, or each end user, may consume within a rolling time window. When the cap is hit, chat requests are rejected until the window resets.
This is distinct from edge rate limiting, which is enforced by your reverse proxy (per-IP, returns 429). Usage limits live inside the engine, are keyed on tenant or user, and return 402.
The shape of a limit
Section titled “The shape of a limit”A usage limit is a single object:
{ "scope": "tenant", "unit": "turns", "limit_value": 500, "interval_seconds": 86400, "enabled": true}| Field | Values | Description |
|---|---|---|
scope | tenant, per_user | tenant limits the whole deployment/tenant as one bucket. per_user gives each end user their own independent counter. |
unit | turns, steps | What is counted. A turn is one chat request; a step is one reasoning/tool iteration inside a turn. Both counters are always tracked — you can switch the enforced unit without resetting the count. |
limit_value | integer | The maximum allowed within the window. |
interval_seconds | integer | The rolling window in seconds, after which the counter resets. |
enabled | boolean | When false (or when no limit is configured) the scope is unlimited. |
Configuring limits (admin REST)
Section titled “Configuring limits (admin REST)”All three endpoints require the admin scope.
# Read the current limitscurl http://localhost:8443/api/v1/admin/usage-limits \ -H "Authorization: Bearer bb_admin_token"
# Set / update limitscurl -X PUT http://localhost:8443/api/v1/admin/usage-limits \ -H "Authorization: Bearer bb_admin_token" \ -H "Content-Type: application/json" \ -d '{ "scope": "per_user", "unit": "turns", "limit_value": 50, "interval_seconds": 86400, "enabled": true }'
# Remove the limit for a scopecurl -X DELETE http://localhost:8443/api/v1/admin/usage-limits/per_user \ -H "Authorization: Bearer bb_admin_token"The {scope} path segment on DELETE is tenant or per_user.
What happens when a limit is exceeded
Section titled “What happens when a limit is exceeded”A chat request that would exceed an enabled limit is rejected with HTTP 402 Payment Required:
HTTP/1.1 402 Payment RequiredContent-Type: application/json
{"error":"[USAGE_LIMITED] usage limit reached: 500/500 turns for this tenant — bring your own model key to continue"}The error message reports the consumed count, the limit, the unit, and the scope that tripped.
When to use each scope
Section titled “When to use each scope”| Goal | Scope | Example |
|---|---|---|
| Protect a shared free tier from a single deployment burning the budget | tenant | 10,000 steps per day across the whole deployment. |
| Give every end user a fair individual allowance | per_user | 50 turns per user per day. |
| No cap | — | Leave unconfigured, or set enabled: false. |
You can configure tenant and per_user independently — a request must satisfy every enabled limit that applies to it.
What’s next
Section titled “What’s next”- Rate limiting — per-IP limits at the edge (the other kind of limit)
- BYOK — let users bring their own model key (and skip usage limits)
- API Reference