Skip to main content
Use POST /v1/billing/deduct to deduct from a customer’s available wallet balance in a single request. This is the right choice for fixed-price image generation, fixed-cost API calls, and other one-time operations where cost is known upfront. It is one of the billing primitives you use for work you price yourself.
Model calls you route through the Velobase AI gateway (POST /v1/chat/completions, POST /v1/messages) bill the customer wallet automatically at real token cost. You do not need to call deduct for those. Use direct deduction for your own priced work. See the gateway quickstart for routing model calls.
If cost is unknown in advance, or you need to reserve funds before settlement, use staged deduction instead.

Minimal Example

Parameters

body.customer_id
string
required
The unique identifier for this customer. The customer must already exist and have enough available balance in their wallet.
body.transaction_id
string
required
Unique ID for this charge transaction. Also serves as the idempotency key: repeating a request with the same transaction_id returns the original result without double-charging.
body.amount_usd
number
required
Amount to deduct, in US dollars. Must be greater than 0. You can instead pass amount_cents or amount_credits, where 1 USD = 100 cents = 1,000,000 credits. A bare amount is legacy and is interpreted as cents.
body.credit_types
string[]
Restrict deduction to these wallet categories only. If omitted, the system may draw from any active credits. If provided and the selected categories have insufficient credits, the request fails.
body.business_type
string
Transaction category for reporting. Examples: TASK, ORDER, TOKEN_USAGE.
body.description
string
A human-readable note for this transaction.

Response

transaction_id
string
The unique transaction ID passed in the request.
deducted_amount
number
Total amount actually deducted, in credits (1,000,000 credits = 1 USD).
deduct_details
array
Deduction breakdown. Funds may be consumed from multiple wallet categories when the amount spans more than one source.
deducted_at
string
ISO 8601 timestamp when the deduction completed.
is_idempotent_replay
boolean
true when the response was returned from a previous request with the same transaction_id.

Deduction Rules and Wallet Categories

  • The system automatically deducts from all available balance across the customer’s wallets.
  • If credit_types is provided, deduction is limited to those wallet categories only.
  • Callers do not choose which wallet category to consume from.
  • Funds that expire sooner are consumed first. If expiry is the same, older sources are consumed first.
  • Only funds that are currently active are eligible for deduction. Sources that have not started yet or have already expired are ignored.
  • Use GET /v1/customers/{id} to inspect the remaining balance per wallet and per source.

Insufficient Balance

Returns 400 if the customer doesn’t have enough available balance:
If credit_types is provided, the error message becomes insufficient balance in selected credit_types when the selected wallet categories do not have enough credits. Failed requests do not produce a partial deduction and do not leave behind a half-completed state.

Idempotency

Same transaction_id returns the same result, with is_idempotent_replay: true and no double charge.

Verify the Result

GET /v1/customers/{id} returns the customer with a wallets map. Each wallet reports total, used, frozen, and available, plus a sources array broken down by funding source:
After deduction, check:
  • whether the wallet’s available decreased (values are in credits, where 1,000,000 credits = 1 USD)
  • which sources[] entries were consumed
  • whether each sources[].available value changed as expected

Error Format

All API errors return an HTTP error status and a structured error object:
error.message
string
Human-readable description of the error.
error.type
string
High-level error category.
error.code
string
Stable machine-readable error code for programmatic handling.