Skip to main content
Version: MVP

Provider budgets

2 min readReferenceUpdated 2026-05-19

What you'll find here

The pre-routing budget and quota check that gates whether Craik is allowed to dispatch a request to a configured model provider. This is the gate; the budget and quota view is the read-only operator display of the same information.

References only, never secrets.

Status records carry budget_ref and quota_ref strings that point at external budget and quota systems. Concrete amounts, account ids, and credentials never enter the routing decision payload.

Records

ProviderBudgetStatus

ProviderRoutingBudgetDecision

ProviderBudgetStatus

Non-secret budget and quota snapshot for one provider, prepared by the operator surface or an integration before routing is attempted.

Field
Type
Meaning
provider_id
str
The provider the status applies to. Must match the routed provider.
budget_ref
str | None
Reference to the external budget record. Not a value, not a secret.
quota_ref
str | None
Reference to the external quota record.
budget_remaining
float | None
Remaining budget in the integrating system's units. Optional; absence means unknown, not unlimited.
quota_remaining
int | None
Remaining quota in calls or requests.
blocked
bool
Explicit block flag set upstream (for example, by an admin freeze).
reason
str | None
Human-readable rationale for a block. Surfaced verbatim in the decision.

ProviderRoutingBudgetDecision

The structured allow-or-deny outcome produced by provider_budget_decision(provider, status) and consumed by the provider router.

Field
Type
Meaning
allowed
bool
Whether routing is permitted under the current status.
provider_id
str
The provider the decision applies to.
reason
str
Why the decision came out the way it did. Always populated.
budget_ref · quota_ref
str | None
Carried through from the provider record so receipts can trace the decision back to its source.
budget_remaining · quota_remaining
float | None · int | None
The remainders observed at decision time. Only present on allow decisions or when surfaced by an explicit block reason.

Decision rules

A decision is always produced — never silently dropped.

provider_budget_decision returns a ProviderRoutingBudgetDecision in every case. The provider router is expected to read allowed and reason directly; there is no second channel for "no answer."

The check denies routing when any of the following is true, in order:

Status mismatch

status.provider_id does not equal the provider being routed.

Explicit block

status.blocked is set. The status reason is surfaced verbatim; absent reason falls back to "provider budget status is blocked."

Budget exhausted

budget_remaining is set and <= 0.

Quota exhausted

quota_remaining is set and <= 0.

Otherwise the decision is allowed with reason "provider budget and quota allow routing."

Absent remainders mean unknown, not unlimited.

budget_remaining=None and quota_remaining=None are treated as "no signal" — the check does not block on them, but it also does not invent a remaining amount. Integrations that want hard limits must populate the value.

What's next