POST /v1/chat/completions, POST /v1/messages), customer and deposit endpoints, and the billing primitives you use for work you price yourself (POST /v1/billing/freeze, /v1/billing/consume, /v1/billing/deduct, /v1/billing/unfreeze).
Most failures on the model gateway come down to one of two things: the request did not resolve an end-customer to bill (no
X-Velobase-Customer header and a project key, or an expired customer-scoped key), or the customer’s wallet has no available funds. See the gateway section below.Error Format
All errors return a structurederror object containing three fields:
| Field | Type | Description |
|---|---|---|
error.message | string | A human-readable description of what went wrong. Use this for logs and user-facing messages. |
error.type | string | A high-level category: bad_request, auth_error, not_found, conflict, too_many_requests, server_error. |
error.code | string | A stable, machine-readable identifier. Use this field for all programmatic error handling. |
Error Codes Reference
Below is a list of commonerror.code values you may encounter, organized by category.
Model gateway: customer resolution and routing
Model gateway: customer resolution and routing
These errors occur on billable model calls (
POST /v1/chat/completions, POST /v1/messages) when Velobase cannot decide which customer to bill, or the request targets a model that is not available to the key. Non-billable endpoints such as GET /v1/models do not require a resolvable customer.| Code | HTTP | Description |
|---|---|---|
customer_not_found | 404 | The X-Velobase-Customer value, or the customer bound to a vb_customer_ key, does not match any customer. |
customer_required | 400 | A project key (vb_live_) was used on a billable endpoint without an X-Velobase-Customer: <user-id> header, so there is no customer to bill. |
api_key_expired | 401 | A customer-scoped key (vb_customer_) is past its expiresAt. |
model_not_found | 404 | The requested model id does not exist. Live model ids include deepseek/deepseek-v4-pro (supports streaming) and anthropic/claude-opus-4.8, claude-opus-4.7, claude-opus-4.6, claude-opus-4.5, claude-sonnet-4.6, claude-haiku-4.5 (Bedrock, non-streaming). |
model_not_allowed | 403 | The model is not in the allowedModels whitelist for this customer-scoped key. |
Validation and routing: 400 Bad Request / 404 Not Found
Validation and routing: 400 Bad Request / 404 Not Found
These errors occur when request parameters are invalid or a referenced resource does not exist.
| Code | HTTP | Description |
|---|---|---|
invalid_starts_at | 400 | The starts_at parameter is not a valid ISO 8601 datetime. |
invalid_expires_at | 400 | The expires_at parameter is not a valid ISO 8601 datetime. |
invalid_credit_types | 400 | The credit_types array is empty or contains invalid strings. |
customer_not_found | 404 | The requested customer_id does not exist. |
Wallet and deduction: 400 Bad Request
Wallet and deduction: 400 Bad Request
These errors occur when a billing operation cannot be completed because the customer’s wallet has no available funds, or the freeze/consume/deduct sequence is invalid. They apply both to per-call model billing and to the billing primitives you use for work you price yourself.Amounts are expressed in explicit unit fields:
amount_usd, amount_cents, or amount_credits, where 1 USD = 100 cents = 1,000,000 credits. A bare amount is legacy and means cents.| Code | Description |
|---|---|
insufficient_balance | The customer’s wallet does not have enough available funds. Top it up with POST /v1/customers/deposit. |
insufficient_balance_in_selected_credit_types | The wallet has enough funds overall, but not within the specific credit_types requested. |
no_consumable_freeze_records | You attempted to consume a transaction that was never frozen or cannot be found. |
freeze_records_already_consumed | The frozen funds for this transaction_id have already been consumed. |
no_unfreezable_records | You attempted to unfreeze a transaction that was never frozen, or has already been consumed or unfrozen. |
actual_amount_exceeds_frozen_amount | The amount passed to consume is greater than the amount originally frozen for this transaction. |
Concurrency and consistency: 409 Conflict / 500 Internal Server Error
Concurrency and consistency: 409 Conflict / 500 Internal Server Error
These errors indicate a conflict between two requests or an unexpected internal failure.
| Code | HTTP | Description |
|---|---|---|
transaction_conflict | 409 | The transaction_id was already used for a different customer. |
customer_scope_mismatch | 409 | An operation referenced a record belonging to a different customer. |
billing_account_not_found | 500 | An internal inconsistency where an expected wallet account is missing. |
server_error | 500 | An unexpected internal error occurred on the Velobase servers. |