Skip to main content
Velobase is a model-agnostic, OpenAI-compatible AI gateway. Point your OpenAI SDK at it and call any model your project has configured, changing two things: the base URL and one header that says which end-customer to bill. Every call is metered against that customer’s wallet, and the per-call cost comes back on the response headers.
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_url parts (a data: URL with base64 bytes, or a plain https: URL), and Anthropic-style image blocks (base64 or url source). The detail field is passed through.
  • PDFs: OpenAI-style file parts (file.file_data as a base64 data URL), and Anthropic-style document blocks (base64 source). Documents referenced only by URL are rejected with unsupported_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.
Audio and video input, file upload endpoints (/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 from max_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 both POST /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 returns 402 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.
See Depositing Credits for wallets, validity windows, and idempotency rules.

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.