Base URL:
https://api.velobase.io/v1, the OpenAI SDK expects the /v1
suffix. Auth: Authorization: Bearer <project-key> (a vb_live_… key). A
project key bills the customer named in the header. You can also issue a
customer-scoped vb_customer_… key that carries its own customer, so no header
is needed. Who to bill: the X-Velobase-Customer: <your-user-id> header.Your models
Models are defined per project, and you bring your own upstream key (BYOK). In the dashboard’s Models section you add a model with three things:- a public model id (what your app passes as
model), - the price your customers pay, per million tokens,
- the upstream provider key it routes to.
GET /v1/models returns exactly the models your project has configured, with
per-model pricing in both credits and USD (input_price_per_million_credits,
input_price_per_million_usd, output_price_per_million_credits,
output_price_per_million_usd, plus cache_read_... and cache_write_...
variants), along with context_window, max_output_tokens, display_name,
description, and active.
There is no platform-wide model list. A model that exists but has no upstream
provider key attached returns 402 byok_key_required (an operator
configuration issue, distinct from customer balance).
Copy for AI
Paste this into your AI coding assistant (Cursor, Claude Code, etc.) and it can wire up the integration in one shot:Make a call
Images and PDFs
Chat requests can carry images and PDF documents inline, on both protocols, for any model whose upstream supports them:- Images: OpenAI-style
image_urlparts (adata:URL with base64 bytes, or a plainhttps:URL), and Anthropic-styleimageblocks (base64 or url source). Thedetailfield is passed through. - PDFs: OpenAI-style
fileparts (file.file_dataas a base64 data URL), and Anthropic-styledocumentblocks (base64 source). Documents referenced only by URL are rejected withunsupported_content; send the bytes. - Images inside tool results (Anthropic protocol): when a tool returns an image, the gateway re-emits it to the model right after the tool message, so it is never silently dropped.
/v1/files), and image
generation are out of scope; the gateway covers chat with inline vision and
documents.
Billing needs no extra setup: the upstream’s own token accounting already
prices media, and the gateway settles from it. For the pre-call hold, the
gateway estimates images from their pixel dimensions and PDFs from their page
count (read from the file header, never decoded), so required_credits on a
402 stays close to what the call will really cost.
How the hold is sized
Before forwarding, the gateway places a temporary hold on the customer’s wallet: an input part estimated from the request (text length, image dimensions, PDF pages) plus an output part sized frommax_tokens. When the
call finishes, the real cost is settled and the rest of the hold is released.
Set max_tokens on every request you can. Without it the output part is
reserved at 8,000 tokens, which raises the balance a customer needs to clear
the 402 check far above the call’s typical cost.
Request headers
Per-call billing headers
Every billed response carries the billing result on its headers, so you can show cost and balance without a second request:
These headers are CORS-exposed, so a browser frontend can read them too.
Streaming
Streaming is supported on bothPOST /v1/chat/completions and
POST /v1/messages. The billing result arrives in the final standard frame
of the stream: for OpenAI-protocol streams it rides the last usage chunk
(before [DONE]), and for Anthropic-protocol streams it rides the
message_delta event. Usage accounting works the same for streaming and
non-streaming calls.
Fund the customer first
A model call needs a funded customer wallet, otherwise it returns402 insufficient_balance (the body includes the required and available credit
amounts, so you can drive a paywall from it). Top one up before (or right
after) you create the user. amount is integer credits: 1 USD = 1,000,000
credits.
Where the money comes from
Each model call settles against exactly one ledger: the end-customer’s wallet, in your pricing units. The upstream provider bills you directly on the API key you attached to the model (BYOK); Velobase does not resell tokens. Two 402s to tell apart:402 insufficient_balance: the customer’s wallet cannot cover the call. Fix by depositing.402 byok_key_required: the model has no upstream provider key attached. Fix in the dashboard’s Models section.
Reconcile usage
GET /v1/usage returns one row per call. Filter with customer_id, model,
transaction_id, trace_id, and paginate with cursor and limit. Join rows
to the X-Velobase-Transaction-Id from each response to reconcile spend per
customer. Each billed call also has a receipt at
GET /v1/billing/receipts/:transaction_id.
Next steps
JavaScript SDK
Deposits, balances and billing primitives from Node/TypeScript.
Python SDK
The same control-plane operations from Python via REST.