Skip to main content

Budgets API

Manage the same spend, request and token budgets that the Policy Engine's Budgets & Usage Limits card configures, from scripts and internal tools. For what a budget counts, how it resets and what happens at the limit, see Rate, token and budget limits.

Budgets
Limit, metric, window
Who it applies to
Usage & subjects
Used vs limit per subject
Tightest budget first
Grants
Time-boxed per-subject limit
Up to the budget ceiling
Pricing & exemptions
Model rates for spend
Skip budgets for some users
Alerts
Webhook destinations
Fired alerts and events
QuilrAI
ResourceWhat you can doScope
BudgetsList, read, create, update and delete budgets; apply up to 100 changes as one batch.budgets:read, budgets:policy
Usage and subjectsRead usage per subject in the current or a past calendar window, a per-budget summary, and every budget that counts a user, app, key or smart group.budgets:read
GrantsGive one subject (or every member of a smart group) a temporary limit, then change or revoke it.budgets:read, budgets:grant
PricingRead the effective price of every configured model, set or remove tenant-wide rates, and choose how unpriced models are charged.budgets:read, budgets:policy
ExemptionsList, add and remove exemptions for users, apps or smart groups.budgets:read, budgets:policy
Alerts and eventsRead and replace alert webhooks, list fired alerts, and poll grant and budget change events.budgets:read, budgets:policy

Try every operation with your own key in the Management API playground.

Before you start​

  • The Policy Engine must be on for the LLM Gateway. Budgets live in the active policy. With it off, GET /budgets returns an empty list with note: "policy_engine_disabled", and writes are refused.
  • Issue a key with budget scopes. In Settings > AI Gateway > LLM Gateway > Management API, pick the scopes below. Budget scopes are independent of read: a key with only budgets:read can read budgets but not apps.
Console scopeAPI scopeGrants
Read budgetsbudgets:readRead budgets, usage, subjects, grants, pricing, exemptions, alerts and events.
Manage budget grantsbudgets:grantIssue, change and revoke budget grants.
Configure budgetsbudgets:policyEdit budgets, pricing, exemptions and alert destinations. Each budget, pricing or exemption edit publishes a policy revision.

GET /budgets also returns caller, describing what the calling key may do, so a tool can hide actions it cannot perform.

How writes work​

WriteEffect
Budget, pricing and exemption editsValidated like a console publish, then published as one new policy revision. Policy text outside the edited budget is kept as is.
Batch (POST /budgets/_batch)Up to 100 budget, rate and exemption operations published as one revision, all or nothing.
GrantsStored outside the policy. Issuing, changing or revoking a grant never publishes a revision.
Alert destinationsReplaces the whole webhook list. Stored targets are redacted on read; send the redacted value back to keep a stored URL.
  • Preview first. Budget, pricing and exemption writes accept ?dry_run=true and return the policy diff, diagnostics and the impact on current usage (subjects newly over the limit, newly blocked or unblocked) without publishing. Grant and alert-destination writes do not support dry_run.
  • Versions. Read a budget or grant to get its ETag, then send it quoted in If-Match. Budget ETags look like "r<revision>-<budget_id>", so any publish can make them stale (412).
  • Creates take an Idempotency-Key. Budget, batch, exemption and grant creation replay the original result for the same key.
  • API-managed vs hand-written. Budgets created here go into an API-managed policy. Budgets written by hand in the policy editor can have their limit, label, mode, alerts and adjustments changed, but cannot be deleted or re-scoped (409 budget_not_api_managed). The same applies to exemptions (409 exemption_not_api_managed).
  • Identity fields are fixed. id, metric, grouping (per) and window cannot change (422 identity_field_immutable), because usage is tracked against them. Create a new budget instead.

Usage, grants and prices​

  • Amounts. Spend amounts are decimal USD strings such as "12.50". Request and token amounts are numbers.
  • Usage is a snapshot. Usage responses carry as_of and stale; the snapshot refreshes periodically. period selects current (default), previous or the start of a past calendar window. Rolling and lifetime windows only show the current period.
  • Row state. Each usage row is blocked (at the hard stop), overflow (in the soft band), alerting (past the lowest alert threshold), granted or ok.
  • Grants need an adjustable budget. A budget accepts grants only when it has an adjustments ceiling (409 budget_not_adjustable otherwise), and a grant cannot exceed that ceiling (422 grant_above_ceiling). A new grant for the same subject supersedes the active one; the response returns it as superseded.
  • Subjects. Name a grant subject by user (email), app, smart_group or model, or by the budget's grouping field. Every grouping field of the budget must be supplied (422 subject_unresolved).
  • Prices. GET /budget-pricing shows where each price comes from: policy (a tenant-wide rate set here), provider (the provider's model costs), catalog (QuilrAI catalog), mixed or unpriced. A tenant-wide rate wins over the provider's cost, which wins over the catalog.

Endpoints​

PUT/budget-alert-destinations

Replace budget alert destinations

Replaces the whole destination list. Omit `target` (or send the redacted read value) to keep a stored URL. Optional If-Match with the etag from the read.

REQUIRESbudgets:policy
Path, query & header parameters 1
If-Match (header)stringoptional

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

destinationsarray<object>required
max items: 20
Array item specification
enabledbooleanoptional
default: true
idstringrequired
pattern: ^[A-Za-z0-9_.-]{1,64}$
kindobjectrequired
"webhook"
targetstring | nulloptional

https URL; omit, null or the redacted read value to keep the stored target

Unknown fields are rejected in this object.

Unknown fields are rejected in this object.

curl --request PUT \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-alert-destinations' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"' \
--header 'Content-Type: application/json' \
--data '{
"destinations": [
{
"enabled": true,
"id": "ops-webhook",
"kind": "webhook",
"target": "https://hooks.example.com/services/budget"
}
]
}'

Authentication, errors & retry rules Try it in the playground

GET/budget-alerts

List budget alerts

Alerts that fired, newest first. Filter by since, until, subject and quota_id (budget id).

REQUIRESbudgets:read
Path, query & header parameters 6
limit (query)integeroptional

Page size.

min: 1max: 500default: 100
cursor (query)stringoptional

Opaque cursor from the previous page's next_cursor.

since (query)stringoptional

ISO timestamp (default: 30 days before until).

until (query)stringoptional

ISO timestamp (default: now).

subject (query)stringoptional

Subject bucket or a value inside it.

quota_id (query)stringoptional

Budget id.

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-alerts?limit=50' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

GET/budget-events

List budget events

Grant changes and budget policy edits made through the API, oldest first after `after` (a next_cursor or an ISO timestamp), so a client can poll for new events. Filter by type, budget_id, grant_id and subject.

REQUIRESbudgets:read
Path, query & header parameters 6
limit (query)integeroptional

Page size.

min: 1max: 500default: 100
after (query)stringoptional

next_cursor of the previous page, or an ISO timestamp.

type (query)stringoptional

Event type, for example grant.created.

budget_id (query)stringoptional

Budget id.

grant_id (query)stringoptional

Grant id.

subject (query)stringoptional

Subject bucket or a value inside it.

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-events?limit=50' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

POST/budget-exemptions

Create a budget exemption

Exempts users, apps or smart groups from all or listed budgets, optionally until expires_at. Publishes a policy revision (201; 200 with dry_run).

REQUIRESbudgets:policy
Path, query & header parameters 3
dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
If-Match (header)stringoptional

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Idempotency-Key (header)stringrequired

Unique per logical write. A retry with the same key and body replays the original result for 24 hours; the same key with a different body is a 409. Not needed with dry_run=true.

min length: 1max length: 200
Full request body specification application/json

applies_toobjectoptional
Object fields
appsarray<string>optional
max items: 100
Array item specification
string
smart_groupsarray<string>optional
max items: 100
Array item specification
string
usersarray<string>optional
max items: 100
Array item specification
string

Unknown fields are rejected in this object.

expires_atstringoptional

Any RFC 3339 instant; stored as rule.expires_at in UTC second precision (YYYY-MM-DDTHH:MM:SSZ), fractional seconds rounded up.

format: date-time
familiesarray<string>optional
Array item specification
string
kindsarray<object>optional
Array item specification
object

Values: "budget""rate"

messagestringoptional
max length: 500
quotasone of 2 variantsrequired
Variant 1 "all"
"all"
Variant 2 array<string>
array<string>
min items: 1max items: 64
reasonstringrequired
min length: 1max length: 300

Unknown fields are rejected in this object.

curl --request POST \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-exemptions' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"' \
--header 'Idempotency-Key: create-support-bot-001' \
--header 'Content-Type: application/json' \
--data '{
"applies_to": {
"users": [
"ceo@example.com"
]
},
"expires_at": "2026-12-31T23:59:59Z",
"quotas": "all",
"reason": "Executive access"
}'

Authentication, errors & retry rules Try it in the playground

DELETE/budget-exemptions/{exemption_id}

Delete a budget exemption

Removes an exemption and publishes a policy revision.

REQUIRESbudgets:policy
Path, query & header parameters 3
exemption_id (path)stringrequired
dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
If-Match (header)stringoptional

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

messagestringoptional

Recorded with the policy revision.

max length: 500

Unknown fields are rejected in this object.

curl --request DELETE \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-exemptions/ex_3e1f0a9b8c7d' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"'

Authentication, errors & retry rules Try it in the playground

GET/budget-grants

List budget grants

Grants across budgets. Filter by budget_id, bucket, status, expires_before and subject.

REQUIRESbudgets:read
Path, query & header parameters 10
limit (query)integeroptional

Page size.

min: 1max: 500default: 100
cursor (query)stringoptional

Opaque cursor from the previous page's next_cursor.

budget_id (query)stringoptional

Budget id.

bucket (query)stringoptional

Canonical subject bucket.

status (query)stringoptional

active, revoked, superseded or expired.

expires_before (query)stringoptional

ISO timestamp.

subject.user (query)stringoptional

User email.

subject.app (query)stringoptional

App name.

subject.smart_group (query)stringoptional

Smart group name.

subject.model (query)stringoptional

Model id.

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-grants?limit=50' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

DELETE/budget-grants/{grant_id}

Revoke a budget grant

Revokes a grant; the subject returns to the base limit. A reason may be sent in the body or the reason query parameter. Requires the grant etag in If-Match.

REQUIRESbudgets:grant
Path, query & header parameters 3
grant_id (path)stringrequired
reason (query)stringoptional

Why the grant is revoked.

If-Match (header)stringrequired

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

reasonstringoptional
max length: 1000

Unknown fields are rejected in this object.

curl --request DELETE \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-grants/grt_4f9a2c1b7e3d' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"'

Authentication, errors & retry rules Try it in the playground

GET/budget-grants/{grant_id}

Read a budget grant

One grant and its etag, used as If-Match on grant writes.

REQUIRESbudgets:read
Path, query & header parameters 1
grant_id (path)stringrequired

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-grants/grt_4f9a2c1b7e3d' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

PATCH/budget-grants/{grant_id}

Update a budget grant

Changes the limit, expiry or reason of an active grant. Requires the grant etag in If-Match.

REQUIRESbudgets:grant
Path, query & header parameters 2
grant_id (path)stringrequired
If-Match (header)stringrequired

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

expires_atstringoptional
format: date-time
limitone of 2 variantsoptional
Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
reasonstringoptional
max length: 1000

Unknown fields are rejected in this object.

curl --request PATCH \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-grants/grt_4f9a2c1b7e3d' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"' \
--header 'Content-Type: application/json' \
--data '{
"limit": "30",
"reason": "Extended surge"
}'

Authentication, errors & retry rules Try it in the playground

GET/budget-pricing

Read budget pricing

Every provider and model configured for the tenant with its effective price and where it comes from (policy rate, provider cost, Quilr catalog, mixed or unpriced), the tenant-wide rate items and how unpriced models are charged. Use it to render a full price table.

REQUIRESbudgets:read

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-pricing' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

PATCH/budget-pricing

Update unpriced model handling

Sets how requests to models with no known price are treated: `zero` (count as free) or `block`; null removes the setting. Publishes a policy revision.

REQUIRESbudgets:policy
Path, query & header parameters 2
dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
If-Match (header)stringoptional

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

unpriced_modelsstring | nullrequired
"zero""block"null

Unknown fields are rejected in this object.

curl --request PATCH \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-pricing' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"' \
--header 'Content-Type: application/json' \
--data '{
"unpriced_models": "block"
}'

Authentication, errors & retry rules Try it in the playground

DELETE/budget-pricing/rates/{provider}/{model}

Remove a model rate

Removes a tenant-wide rate; the model falls back to provider or catalog pricing. provider_label selects a label-specific rate.

REQUIRESbudgets:policy
Path, query & header parameters 5
provider (path)stringrequired
model (path)stringrequired

Model id; may contain `/`.

dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
provider_label (query)stringoptional

Remove the rate of one provider label only.

If-Match (header)stringoptional

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

messagestringoptional

Recorded with the policy revision.

max length: 500

Unknown fields are rejected in this object.

curl --request DELETE \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-pricing/rates/openai/gpt-4.1-mini' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"'

Authentication, errors & retry rules Try it in the playground

PUT/budget-pricing/rates/{provider}/{model}

Set a model rate

Sets the tenant-wide price of one provider and model (model IDs may contain `/`). Rates are USD per 1M tokens, as numbers or decimal strings; tiers and cache rates are optional. Publishes a policy revision.

REQUIRESbudgets:policy
Path, query & header parameters 4
provider (path)stringrequired
model (path)stringrequired

Model id; may contain `/`.

dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
If-Match (header)stringoptional

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

One pricing.token_rates item (provider/model come from the path). Rates are USD per 1M tokens (*_usd_per_1m), tool fees USD per 1k calls / hour / session, multipliers > 0; each a number or a decimal string ("0.15"). At least one rate, fee, multiplier, tiers or cache_write_default_ttl.

audio_input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
audio_output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_read_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_1h_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_5m_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_default_ttlobjectoptional
"5m""1h""unpriced"
cache_write_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
code_execution_usd_per_hourone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
container_usd_per_sessionone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
file_search_usd_per_1kone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
grounding_usd_per_1kone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
image_input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
image_output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
messagestringoptional
max length: 500
modelstringoptional

Optional; must equal the path value

output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
providerstringoptional

Optional; must equal the path value

provider_labelstring | nulloptional
reasoning_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
regional_multipliersobjectoptional
Object fields
data_residencyone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
geoone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
regionalone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
us_onlyone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$

Unknown fields are rejected in this object.

service_tier_multipliersobjectoptional
Object fields
fastone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
flexone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
priorityone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$

Unknown fields are rejected in this object.

tiersarray<object>optional
min items: 1max items: 8
Array item specification
above_input_tokensintegerrequired
min: 0max: 9007199254740991
audio_input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
audio_output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_read_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_1h_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_5m_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
image_input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
image_output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
reasoning_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$

Unknown fields are rejected in this object.

web_fetch_usd_per_1kone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
web_search_usd_per_1kone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$

Unknown fields are rejected in this object.

curl --request PUT \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-pricing/rates/openai/gpt-4.1-mini' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"' \
--header 'Content-Type: application/json' \
--data '{
"input_usd_per_1m": "0.40",
"message": "Negotiated rate",
"output_usd_per_1m": "1.60"
}'

Authentication, errors & retry rules Try it in the playground

GET/budget-subjects

List budget subjects

One row per subject (user, app, key or smart group) across all budgets, with the tightest budget first. Filter with q (substring), kind, budget_id, min_pct and state; include_idle=true adds members with no usage.

REQUIRESbudgets:read
Path, query & header parameters 10
limit (query)integeroptional

Page size.

min: 1max: 500default: 100
cursor (query)stringoptional

Opaque cursor from the previous page's next_cursor.

period (query)stringoptional

current (default), previous, or the ISO start of a past calendar window.

q (query)stringoptional

Case-insensitive substring of the subject.

kind (query)stringoptional

Filter by kind.

budget_id (query)stringoptional

Budget id.

min_pct (query)stringoptional

Only subjects at or above this percent of their limit.

state (query)stringoptional

ok, alerting, granted, overflow or blocked.

sort (query)stringoptional

Sort order, for example pct, used or remaining.

include_idle (query)stringoptional

Also list smart-group members and key owners with no usage (true or false).

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-subjects?limit=50' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

GET/budget-subjects/{kind}/{value}

Read a budget subject

Every budget that would count this subject (kind user, app, key or smart_group), including budgets with no usage yet, and whether each rule depends on request details. `app` narrows rules that depend on the app.

REQUIRESbudgets:read
Path, query & header parameters 4
kind (path)stringrequired

user, app, key or smart_group.

value (path)stringrequired
period (query)stringoptional

current (default), previous, or the ISO start of a past calendar window.

app (query)stringoptional

App name, for rules that depend on the app.

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-subjects/user/alice%40example.com' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

GET/budget-usage-summary

Read budget usage summary

One row per budget: subjects tracked, total used, subjects over 80 percent, in overflow, at the limit or blocked, and active grants. `period` selects a past calendar window.

REQUIRESbudgets:read
Path, query & header parameters 1
period (query)stringoptional

current (default), previous, or the ISO start of a past calendar window.

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budget-usage-summary' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

GET/budgets

List budgets

Budgets (spend, request or token limits) of the active policy, with `caller` describing what the key may do and `policy_engine` status. When QuilrQL is not enabled for the tenant the list is empty. Filters: kind, metric, managed, adjustable.

REQUIRESbudgets:read
Path, query & header parameters 6
limit (query)integeroptional

Page size.

min: 1max: 500default: 100
cursor (query)stringoptional

Opaque cursor from the previous page's next_cursor.

kind (query)stringoptional

Filter by kind.

metric (query)stringoptional

spend_usd, requests or a token metric.

managed (query)stringoptional

true lists only API-managed budgets.

adjustable (query)stringoptional

true lists only budgets that accept grants.

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets?limit=50' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

POST/budgets

Create a budget

Adds a budget to the API-managed budgets policy and publishes a new policy revision (201). With dry_run=true returns the diff, diagnostics and impact without publishing (200). An id is generated when omitted.

REQUIRESbudgets:policy
Path, query & header parameters 2
dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
Idempotency-Key (header)stringrequired

Unique per logical write. A retry with the same key and body replays the original result for 24 hours; the same key with a different body is a 409. Not needed with dry_run=true.

min length: 1max length: 200
Full request body specification application/json

adjustmentsone of 2 variantsoptional
BudgetAdjustments object
auto_approveobjectoptional
Object fields
max_countintegeroptional
min: 1max: 100
perobjectoptional
"day""week""month"
smart_groupsarray<string>optional
max items: 32
Array item specification
string
up_to_pctintegeroptional
min: 1max: 1000

Unknown fields are rejected in this object.

ceilingone of 2 variantsrequired

Highest grant limit (USD for spend); >= limit

Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
max_durationstringoptional

1h..366d (default 366d)

pattern: ^\d+[hd]$
overflowobjectoptional
Object fields
add_pctintegerrequired
min: 1max: 1000

Unknown fields are rejected in this object.

requestablebooleanoptional
default: false

Unknown fields are rejected in this object.

Also accepts null.

alertsarray | nulloptional
max items: 5
applies_toobjectoptional
Object fields
appsarray<string>optional
max items: 100
Array item specification
string
smart_groupsarray<string>optional
max items: 100
Array item specification
string

Unknown fields are rejected in this object.

familystring | nulloptional
idstringoptional
max length: 128pattern: ^[A-Za-z0-9][A-Za-z0-9._:-]*$
kindstring | nulloptional
"budget""rate"null
labelstring | nulloptional
max length: 120
limitone of 2 variantsrequired
Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
messagestringoptional
max length: 500
metricstringrequired
modestring | nulloptional
"enforce""alert""paused"null
perarray<string>optional
Array item specification
string
windowobjectrequired

Unknown fields are rejected in this object.

curl --request POST \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets' \
--header 'Authorization: Bearer <management-key>' \
--header 'Idempotency-Key: create-support-bot-001' \
--header 'Content-Type: application/json' \
--data '{
"kind": "rate",
"limit": 1000,
"metric": "requests",
"per": [
"application.name"
],
"window": {
"kind": "rolling",
"unit": "hour"
}
}'

Authentication, errors & retry rules Try it in the playground

POST/budgets/_batch

Apply budget changes in a batch

Up to 100 budget, rate and exemption operations published as ONE policy revision, all or nothing. Each op may carry its own if_match.

REQUIRESbudgets:policy
Path, query & header parameters 3
dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
If-Match (header)stringoptional

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Idempotency-Key (header)stringrequired

Unique per logical write. A retry with the same key and body replays the original result for 24 hours; the same key with a different body is a 409. Not needed with dry_run=true.

min length: 1max length: 200
Full request body specification application/json

messagestringoptional
max length: 500
opsarray<object>required
min items: 1max items: 100
Array item specification
budgetobjectoptional
Object fields
adjustmentsone of 2 variantsoptional
BudgetAdjustments object
auto_approveobjectoptional
Object fields
max_countintegeroptional
min: 1max: 100
perobjectoptional
"day""week""month"
smart_groupsarray<string>optional
max items: 32
Array item specification
string
up_to_pctintegeroptional
min: 1max: 1000

Unknown fields are rejected in this object.

ceilingone of 2 variantsrequired

Highest grant limit (USD for spend); >= limit

Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
max_durationstringoptional

1h..366d (default 366d)

pattern: ^\d+[hd]$
overflowobjectoptional
Object fields
add_pctintegerrequired
min: 1max: 1000

Unknown fields are rejected in this object.

requestablebooleanoptional
default: false

Unknown fields are rejected in this object.

Also accepts null.

alertsarray | nulloptional
max items: 5
applies_toobjectoptional
Object fields
appsarray<string>optional
max items: 100
Array item specification
string
smart_groupsarray<string>optional
max items: 100
Array item specification
string

Unknown fields are rejected in this object.

familystring | nulloptional
idstringoptional
max length: 128pattern: ^[A-Za-z0-9][A-Za-z0-9._:-]*$
kindstring | nulloptional
"budget""rate"null
labelstring | nulloptional
max length: 120
limitone of 2 variantsrequired
Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
messagestringoptional
max length: 500
metricstringrequired
modestring | nulloptional
"enforce""alert""paused"null
perarray<string>optional
Array item specification
string
windowobjectrequired

Unknown fields are rejected in this object.

changesobjectoptional

Identity fields (id, metric, per/group_by, window) are immutable (422 identity_field_immutable); applies_to only on API-managed budgets.

Object fields
adjustmentsone of 2 variantsoptional
BudgetAdjustments object
auto_approveobjectoptional
Object fields
max_countintegeroptional
min: 1max: 100
perobjectoptional
"day""week""month"
smart_groupsarray<string>optional
max items: 32
Array item specification
string
up_to_pctintegeroptional
min: 1max: 1000

Unknown fields are rejected in this object.

ceilingone of 2 variantsrequired

Highest grant limit (USD for spend); >= limit

Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
max_durationstringoptional

1h..366d (default 366d)

pattern: ^\d+[hd]$
overflowobjectoptional
Object fields
add_pctintegerrequired
min: 1max: 1000

Unknown fields are rejected in this object.

requestablebooleanoptional
default: false

Unknown fields are rejected in this object.

Also accepts null.

alertsarray | nulloptional
max items: 5
applies_toobjectoptional
Object fields
appsarray<string>optional
max items: 100
Array item specification
string
smart_groupsarray<string>optional
max items: 100
Array item specification
string

Unknown fields are rejected in this object.

familystring | nulloptional
kindstring | nulloptional
"budget""rate"null
labelstring | nulloptional
max length: 120
limitone of 2 variantsoptional
Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
messagestringoptional
max length: 500
modestring | nulloptional
"enforce""alert""paused"null
exemptionobjectoptional
Object fields
applies_toobjectoptional
Object fields
appsarray<string>optional
max items: 100
Array item specification
string
smart_groupsarray<string>optional
max items: 100
Array item specification
string
usersarray<string>optional
max items: 100
Array item specification
string

Unknown fields are rejected in this object.

expires_atstringoptional

Any RFC 3339 instant; stored as rule.expires_at in UTC second precision (YYYY-MM-DDTHH:MM:SSZ), fractional seconds rounded up.

format: date-time
familiesarray<string>optional
Array item specification
string
kindsarray<object>optional
Array item specification
object

Values: "budget""rate"

messagestringoptional
max length: 500
quotasone of 2 variantsrequired
Variant 1 "all"
"all"
Variant 2 array<string>
array<string>
min items: 1max items: 64
reasonstringrequired
min length: 1max length: 300

Unknown fields are rejected in this object.

exemption_idstringoptional
idstringoptional
if_matchstringoptional
modelstringoptional
opobjectrequired
"patch""create""delete""put_rate""delete_rate""set_unpriced_models""create_exemption""delete_exemption"
providerstringoptional
provider_labelstring | nulloptional
rateobjectoptional

One pricing.token_rates item (provider/model come from the path). Rates are USD per 1M tokens (*_usd_per_1m), tool fees USD per 1k calls / hour / session, multipliers > 0; each a number or a decimal string ("0.15"). At least one rate, fee, multiplier, tiers or cache_write_default_ttl.

Object fields
audio_input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
audio_output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_read_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_1h_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_5m_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_default_ttlobjectoptional
"5m""1h""unpriced"
cache_write_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
code_execution_usd_per_hourone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
container_usd_per_sessionone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
file_search_usd_per_1kone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
grounding_usd_per_1kone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
image_input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
image_output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
messagestringoptional
max length: 500
modelstringoptional

Optional; must equal the path value

output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
providerstringoptional

Optional; must equal the path value

provider_labelstring | nulloptional
reasoning_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
regional_multipliersobjectoptional
Object fields
data_residencyone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
geoone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
regionalone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
us_onlyone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$

Unknown fields are rejected in this object.

service_tier_multipliersobjectoptional
Object fields
fastone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
flexone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
priorityone of 2 variantsoptional
Variant 1 number
number
greater than: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$

Unknown fields are rejected in this object.

tiersarray<object>optional
min items: 1max items: 8
Array item specification
above_input_tokensintegerrequired
min: 0max: 9007199254740991
audio_input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
audio_output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_read_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_1h_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_5m_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
cache_write_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
image_input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
image_output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
input_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
output_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
reasoning_usd_per_1mone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$

Unknown fields are rejected in this object.

web_fetch_usd_per_1kone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$
web_search_usd_per_1kone of 2 variantsoptional
Variant 1 number
number
min: 0
Variant 2 string
string
pattern: ^\d{1,12}(\.\d{1,12})?$

Unknown fields are rejected in this object.

valuestring | nulloptional
"zero""block"null

Unknown fields are rejected in this object.

curl --request POST \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets/_batch' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12"' \
--header 'Idempotency-Key: create-support-bot-001' \
--header 'Content-Type: application/json' \
--data '{
"message": "Raise support budget and price gpt-4.1-mini",
"ops": [
{
"changes": {
"limit": "20"
},
"id": "support_spend",
"op": "patch"
},
{
"model": "gpt-4.1-mini",
"op": "put_rate",
"provider": "openai",
"rate": {
"input_usd_per_1m": "0.40",
"output_usd_per_1m": "1.60"
}
}
]
}'

Authentication, errors & retry rules Try it in the playground

DELETE/budgets/{budget_id}

Delete a budget

Removes an API-managed budget and publishes a new revision. Budgets written by hand in policy return 409 budget_not_api_managed. Requires the budget etag in If-Match.

REQUIRESbudgets:policy
Path, query & header parameters 3
budget_id (path)stringrequired
dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
If-Match (header)stringrequired

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

messagestringoptional

Recorded with the policy revision.

max length: 500

Unknown fields are rejected in this object.

curl --request DELETE \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets/support_spend' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12-support_spend"'

Authentication, errors & retry rules Try it in the playground

GET/budgets/{budget_id}

Read a budget

One budget and its etag (`r<revision>-<id>`), used as If-Match on budget writes.

REQUIRESbudgets:read
Path, query & header parameters 1
budget_id (path)stringrequired

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets/support_spend' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground

PATCH/budgets/{budget_id}

Update a budget

Changes limit, label, mode, alerts, adjustments or (API-managed budgets only) applies_to, and publishes a new revision. id, metric, per and window are immutable (422 identity_field_immutable). Requires the budget etag in If-Match. dry_run=true previews diff and impact.

REQUIRESbudgets:policy
Path, query & header parameters 3
budget_id (path)stringrequired
dry_run (query)booleanoptional

Return the policy diff, diagnostics and impact without publishing.

default: false
If-Match (header)stringrequired

Budget etag "r<revision>-<id>" (required on PATCH/DELETE of a budget); grant etag "<version>" (required on PATCH/DELETE of a grant); optional policy etag "r<revision>" on pricing, exemption and batch writes; optional alert-destinations etag on PUT /budget-alert-destinations.

Full request body specification application/json

Identity fields (id, metric, per/group_by, window) are immutable (422 identity_field_immutable); applies_to only on API-managed budgets.

adjustmentsone of 2 variantsoptional
BudgetAdjustments object
auto_approveobjectoptional
Object fields
max_countintegeroptional
min: 1max: 100
perobjectoptional
"day""week""month"
smart_groupsarray<string>optional
max items: 32
Array item specification
string
up_to_pctintegeroptional
min: 1max: 1000

Unknown fields are rejected in this object.

ceilingone of 2 variantsrequired

Highest grant limit (USD for spend); >= limit

Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
max_durationstringoptional

1h..366d (default 366d)

pattern: ^\d+[hd]$
overflowobjectoptional
Object fields
add_pctintegerrequired
min: 1max: 1000

Unknown fields are rejected in this object.

requestablebooleanoptional
default: false

Unknown fields are rejected in this object.

Also accepts null.

alertsarray | nulloptional
max items: 5
applies_toobjectoptional
Object fields
appsarray<string>optional
max items: 100
Array item specification
string
smart_groupsarray<string>optional
max items: 100
Array item specification
string

Unknown fields are rejected in this object.

familystring | nulloptional
kindstring | nulloptional
"budget""rate"null
labelstring | nulloptional
max length: 120
limitone of 2 variantsoptional
Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
messagestringoptional
max length: 500
modestring | nulloptional
"enforce""alert""paused"null
curl --request PATCH \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets/support_spend' \
--header 'Authorization: Bearer <management-key>' \
--header 'If-Match: "r12-support_spend"' \
--header 'Content-Type: application/json' \
--data '{
"adjustments": {
"ceiling": "50",
"max_duration": "90d"
}
}'

Authentication, errors & retry rules Try it in the playground

POST/budgets/{budget_id}/grants

Issue a budget grant

Gives one subject of an adjustable budget a time-boxed limit (higher or lower than the base, at most the budget's ceiling). A new grant supersedes the subject's active one. Grants do not change policy.

REQUIRESbudgets:grant
Path, query & header parameters 2
budget_id (path)stringrequired
Idempotency-Key (header)stringrequired

Unique per logical write. A retry with the same key and body replays the original result for 24 hours; the same key with a different body is a 409. Not needed with dry_run=true.

min length: 1max length: 200
Full request body specification application/json

expires_atstringrequired
format: date-time
limitone of 2 variantsrequired
Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
messagestringoptional
max length: 500
reasonstringoptional
max length: 1000
starts_atstringoptional
format: date-time
subjectobjectrequired

One bucket of the budget: {"user": email}, {"app": name}, {"smart_group": g}, {"model": m}, raw {"<group_by field>": value}, or {"bucket": "<canonical>"}; every group_by field must be supplied (422 subject_unresolved / subject_not_in_budget).

Unknown fields are rejected in this object.

curl --request POST \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets/support_spend/grants' \
--header 'Authorization: Bearer <management-key>' \
--header 'Idempotency-Key: create-support-bot-001' \
--header 'Content-Type: application/json' \
--data '{
"expires_at": "2026-10-31T23:59:59Z",
"limit": "25",
"reason": "Quarter-end ticket surge",
"subject": {
"user": "alice@example.com"
}
}'

Authentication, errors & retry rules Try it in the playground

POST/budgets/{budget_id}/grants/_bulk

Issue budget grants in bulk

Issues up to 1000 grants, listed in `grants` or expanded from every member of a smart group (`subjects_from`). Each item succeeds or fails independently; failures are listed in `errors`. 201 when at least one grant was issued, otherwise 200.

REQUIRESbudgets:grant
Path, query & header parameters 2
budget_id (path)stringrequired
Idempotency-Key (header)stringrequired

Unique per logical write. A retry with the same key and body replays the original result for 24 hours; the same key with a different body is a 409. Not needed with dry_run=true.

min length: 1max length: 200
Full request body specification application/json

expires_atstringoptional
format: date-time
grantsarray<object>optional
max items: 1000
Array item specification
object
limitone of 2 variantsoptional
Variant 1 string
string
pattern: ^\d+(\.\d{1,6})?$
Variant 2 number
number
min: 0
messagestringoptional
max length: 500
reasonstringoptional
max length: 1000
starts_atstringoptional
format: date-time
subjects_fromobjectoptional
Object fields
smart_groupstringrequired

Unknown fields are rejected in this object.

Unknown fields are rejected in this object.

curl --request POST \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets/support_spend/grants/_bulk' \
--header 'Authorization: Bearer <management-key>' \
--header 'Idempotency-Key: create-support-bot-001' \
--header 'Content-Type: application/json' \
--data '{
"expires_at": "2026-10-31T23:59:59Z",
"limit": "25",
"reason": "Launch week",
"subjects_from": {
"smart_group": "support-team"
}
}'

Authentication, errors & retry rules Try it in the playground

GET/budgets/{budget_id}/usage

Read budget usage

Usage of one budget per subject in the current (or a past calendar) window: used, base and effective limits, remaining, percent, state, grant and overflow. Filter by subject, min_pct and state; sort by pct, used or remaining. Usage is a cached snapshot refreshed every few seconds (`as_of`, `stale`).

REQUIRESbudgets:read
Path, query & header parameters 12
budget_id (path)stringrequired
limit (query)integeroptional

Page size.

min: 1max: 500default: 100
cursor (query)stringoptional

Opaque cursor from the previous page's next_cursor.

period (query)stringoptional

current (default), previous, or the ISO start of a past calendar window.

min_pct (query)stringoptional

Only subjects at or above this percent of their limit.

state (query)stringoptional

ok, alerting, granted, overflow or blocked.

sort (query)stringoptional

Sort order, for example pct, used or remaining.

include_idle (query)stringoptional

Also list smart-group members and key owners with no usage (true or false).

subject.user (query)stringoptional

User email.

subject.app (query)stringoptional

App name.

subject.smart_group (query)stringoptional

Smart group name.

subject.model (query)stringoptional

Model id.

No request body.

curl --request GET \
'https://guardrails-usa-1.quilr.ai/llmgateway/management/v1/budgets/support_spend/usage?limit=50' \
--header 'Authorization: Bearer <management-key>'

Authentication, errors & retry rules Try it in the playground