Skip to main content

Budgets

A Budget is a spend boundary for one billing user. It is not a wallet, a funding source, or an authorize-time reservation.

Two identifiers, two roles

  • budget_id is Vluna's internal identifier. Management endpoints keep using it for list, get, close, support, and reporting joins.
  • budget is an immutable external reference. Your integration can choose it and pass it through Gate requests without storing a Vluna UUID.

The external reference is unique within the billing account and billing user. It is opaque to Vluna: use a run id, job id, or another stable resource id whose scope and lifecycle your system owns. Do not put secrets in it.

Create a Budget

POST /mgt/v1/budgets accepts optional budget:

{
"budget": "run_01K4Q6FJ2B",
"name": "Email assistant run",
"scope_kind": "global",
"limit_xusd": "50000000"
}

The response returns both identifiers:

{
"ok": true,
"data": {
"budget_id": "8a53a407-975d-491d-811b-d9168915484e",
"budget": "run_01K4Q6FJ2B",
"status": "active",
"consumed_xusd": "0"
}
}

If budget is omitted, Vluna generates budget_id and uses the same string as the external reference. This keeps the simple store-and-forward flow available without introducing a second generated value.

Select it in Gate requests

Pass the external reference as budget in authorize or direct ingest:

{
"lease": "run_01K4Q6FJ2B:model-call:1",
"budget": "run_01K4Q6FJ2B",
"feature_code": "openai.gpt-4o",
"estimated_quantity_minor": "1200"
}

Authorize resolves the reference in the current account/user namespace and binds the internal Budget to the lease. Commit therefore needs only lease; it does not accept budget again. Direct ingest has no lease, so it accepts budget on each request.

Gate responses and operational facts may return budget_id. Treat it as a diagnostic and join key, not as the value your runtime must carry between its own resources.

Management remains ID-based

Use the internal UUID for:

  • GET /mgt/v1/budgets/{budget_id}
  • POST /mgt/v1/budgets/{budget_id}/close
  • support, audit, and reporting joins

Creating an external reference does not rename these management APIs. This separation keeps runtime mapping convenient without making a user-controlled identifier the database primary key.

Failure and lifecycle rules

  • Reusing an external reference in the same account/user namespace returns a conflict.
  • Gate selection of an unknown reference returns 422 with RESOURCE.NOT_FOUND.
  • The Budget must be active and within its configured window when evaluated.
  • Authorize checks current headroom but reserves nothing. If work fails, send no compensation request. Only committed or ingested usage consumes the Budget.

Next