freeze -> consume / unfreeze flow to bill work that you price yourself, when the cost is unknown upfront. This is one half of Velobase: the billing ledger for your own work.
This is the right choice for async tasks, batch jobs, and any flow where the final cost is only known after execution.
If you are billing model calls, you usually do not need this flow. Point your OpenAI or Anthropic SDK at
https://api.velobase.io/v1 and pass X-Velobase-Customer: <user-id>, and the gateway freezes, settles the real token cost, and deducts from the customer wallet for you on every call. See the Quickstart for the gateway path. Use staged deduction below when you price the work yourself rather than per model token.transaction_id is the unique ID for this charge transaction and stays the same across freeze, consume, and unfreeze.
All amount fields are in cents. 1 USD = 100 cents = 1,000,000 credits. A bare amount is legacy and is interpreted as cents.
Freeze
Reserve a maximum budget before starting work. After freezing, the funds are no longer available to spend, but they have not been consumed yet.Freeze ParametersFreeze ResponseReturns
The unique identifier for this customer. The customer must already exist and have enough available funds in their wallet to cover the freeze amount.
Unique ID for this charge transaction. Use the same value for the subsequent
consume or unfreeze call.Maximum amount to reserve, in cents (1 USD = 100 cents = 1,000,000 credits). You may instead send
amount_usd or amount_credits. A bare amount is legacy and is read as cents. Must be greater than 0. Set this to the upper bound of expected cost.Restrict the freeze to these wallet categories only. If omitted, the system may use any active funds. The same categories are used automatically during consume.
Transaction category for reporting. Examples:
TASK, ORDER, TOKEN_USAGE.A human-readable note for this freeze.
The transaction ID passed in the request.
Total amount reserved by this freeze, in cents.
Breakdown of which wallet sources were frozen. The system may freeze across multiple wallet categories.
true when the response was returned from a previous request with the same transaction_id.400 with insufficient balance if the customer wallet does not have enough available funds.If credit_types is provided during freeze, and the selected wallet categories do not have enough funds, the error message becomes insufficient balance in selected credit_types.Consume
Settle the actual cost after the task finishes. Any unused funds are returned automatically.Example: freeze Consume Response
100 cents, finish with an actual cost of 73 cents, and the remaining 27 cents is automatically returned.Consume ParametersThe same transaction ID used in the freeze step.
Actual amount to consume, in cents. If less than the frozen amount, the remainder is returned. Defaults to the full frozen amount if omitted.
Amount permanently consumed by this operation, in cents.
Unused frozen funds automatically returned to the available wallet balance, in cents (
frozen_amount - actual_amount).Breakdown of which wallet sources were consumed.
ISO 8601 timestamp when consumption completed.
true when the response was returned from a previous request with the same transaction_id.Unfreeze (Cancel)
Release frozen funds without consuming. Use when the task is cancelled.Unfreeze Response
Total amount returned to the available wallet balance, in cents.
Breakdown of which wallet sources were unfrozen.
ISO 8601 timestamp when the unfreeze completed.
true when the response was returned from a previous request with the same transaction_id.Wallet Categories and Consumption Order
- The system automatically freezes and consumes from all available wallet funds.
- If
credit_typesis provided duringfreeze, only those wallet categories are eligible for this transaction. - Callers do not choose which wallet category to use.
- Funds that expire sooner are handled first. If expiry is the same, older sources are handled first.
- Only funds that are currently active participate in freeze and consume. Funds that have not started yet or have already expired are ignored.
- Use the customer API to inspect remaining funds per wallet source.
Idempotency
All three operations are idempotent ontransaction_id. Duplicate calls return the original result with is_idempotent_replay: true.
Verify the Result
Fetch the customer to inspect their wallets:wallets["default"] summary:
- whether
frozenincreases after freeze - whether
usedincreases after consume - whether
availablechanges as expected - which wallet
sources[]were used
Error Format
All API errors return an HTTP error status and a structurederror object:
Human-readable description of the error.
High-level error category.
Stable machine-readable error code for programmatic handling.