# Gondola > Gondola is a DIEM yield marketplace built on Venice AI. DIEM holders ("lenders") deposit a Venice inference API key, set a per-token price, and earn USDC on what would otherwise be idle daily allowance. Buyers hit an OpenAI-compatible gateway and pay per request in USDC on Base. A broker routes each request within a small price band of the cheapest available lender key, favoring in-band lenders who referred active buyers, falling back to Gondola's own prepaid key when no lender key has capacity, meters usage, and settles off-chain. Gondola stores no prompt or completion content (per-request records hold token counts and accounting metadata only) and adds no logging on top of Venice's no-logging model. The one stored exception is a video source clip over 18 MB, held privately for the length of its job. Site: https://gondola-ai.com ## Key concepts - **DIEM**: Venice's staked-compute allowance. 1 staked DIEM is roughly $1 per day of inference. Once staked it produces a daily allowance that resets at midnight UTC. - **Lender**: a Base wallet that deposits a Venice INFERENCE API key and sets a single price factor against Venice's list price. Gondola routes paid inference to the key and credits USDC for every request served. - **Buyer**: a Base wallet that tops up a USDC balance and calls the OpenAI-compatible gateway. Each request debits the actual metered cost of the model used. - **Broker**: Gondola itself. It selects a lender within a small price band of the cheapest healthy one for each request, with in-band preference for lenders who referred active buyers, meters token usage, and settles balances off-chain. Top-ups and payouts happen on-chain in USDC on Base. - **Fees**: symmetric and small. Buyers pay the posted price plus a platform fee of up to 2 percent; lenders receive the posted price minus a platform fee of up to 2 percent. The broker keeps the spread. No subscriptions. Payouts have a small minimum to avoid gas-draining tiny withdrawals. - **Privacy**: Gondola never stores prompts or completions; the one exception is a video source clip over 18 MB, held privately for the length of its job (see https://gondola-ai.com/privacy). Models on `GET /v1/models` expose Venice's privacy tier where classified (private = zero retention on Venice-controlled infrastructure, anonymized = relayed to the provider with identity stripped). ## API OpenAI-compatible. Base URL: https://api.gondola-ai.com/v1 Anthropic-compatible too: POST /v1/messages implements the Anthropic Messages API (streaming, tool use, count_tokens), so Claude Code and the Anthropic SDK work with ANTHROPIC_BASE_URL=https://api.gondola-ai.com (no /v1 suffix; the SDK adds the path). Authenticate with a Gondola key (`gnd_...`) in the `Authorization: Bearer` header, exactly as you would with OpenAI. The Anthropic surface also accepts the key in `x-api-key`. Balance visibility: successful responses and insufficient-balance 402s on the paid endpoints carry an `x-gondola-balance` header, your remaining Gondola balance in USD as a plain decimal string, plus `x-gondola-balance-warning: low` when it is running low. The value is the spendable wallet-level Gondola balance at the moment the response was built. During streamed responses the in-flight request's hold may still be excluded, so treat it as a lower bound. It is not a per-key spend limit, and a missing header means the balance was unknown for that response, never that it is zero. For polling, use `GET /v1/balance`. Routing visibility: every response from an endpoint that reserved a lender key also carries `X-Gondola-Chosen-Factor` (the price factor, relative to Venice list, the request was actually routed at), `X-Gondola-Candidates` (how many lender keys were eligible), `X-Gondola-Second-Best-Factor` (the next-cheapest factor, omitted when there was only one candidate), `X-Gondola-Charge-Usd` (the fee-inclusive estimated charge for this exact request; omitted when the request carries video, audio or a file, whose cost is known only once the model reports usage), `X-Gondola-Priority: true` when in-band referral priority (rather than a plain weighted-random draw) decided which tied lender served the request, and `X-Gondola-House: true` when no marketplace lender had capacity and the request was served from Gondola's own prepaid Venice credits instead (Gondola acting as supplier of last resort, priced at Venice list plus the platform fee). Marketplace lenders never price above Venice list; Gondola's own key is the one deliberate exception, and its presence is always disclosed via this header. Cost control for unattended or scripted use: send the request header `x-gondola-max-factor` (a number from 0 to 1) to set a hard price ceiling. Gondola will never route the request to a lender key priced above that factor, including its own key, and will not silently serve it at a higher price either: a request nothing can serve within the ceiling gets a `503` (`529` on `/v1/messages`) with `X-Gondola-Best-Available-Factor` reporting the cheapest factor that was actually available, so you can decide whether to raise the ceiling and retry. Omit the header for no ceiling, which is the default and lets a request fall through to Gondola's own key rather than fail. This is the primary lever for capping spend on agentic tools that make many unattended calls. For an absolute dollar cap instead of a relative one, send `x-gondola-max-charge-usd` (a number greater than 0, e.g. 0.50) to cap this exact request's estimated fee-inclusive charge in USD, with no upper bound and no cap when the header is omitted. It composes with `x-gondola-max-factor`: the factor ceiling applies first, then the dollar cap on the survivors. A request nothing can serve within the cap is refused before anything is billed or held, with a `402` (`max_charge_exceeded`, `billing_error` on `/v1/messages`) and `X-Gondola-Best-Available-Charge-Usd` reporting the cheapest charge that was actually available, rounded up, so retrying with exactly that value succeeds. The final charge is always min(estimate, actual), so a served request never exceeds the cap. Most useful for video, priced per clip from under a dollar up to $25. On the accountless x402 endpoints the cap also bounds the payment challenge and the signed payment value, so a cap below the $0.01 minimum charge always refuses there with no payment taken. A malformed, empty, zero, or negative value is a `400` (`invalid_max_charge`), never silently ignored. Capacity: a model that is temporarily oversubscribed upstream returns `429` (`rate_limit_error` on `/v1/messages`) with a `Retry-After` in seconds. This is not a per-key rate limit, Gondola sets none. Honor the header rather than retrying immediately: it is jittered per response so a fleet of clients does not all come back at the same instant and re-trigger the same overload, and it lengthens while an overload persists, so a growing value means the model is saturated rather than flickering. Gondola already retries once internally before returning the `429`, so a request that reaches you has failed twice. Nothing is charged for a request that fails this way. Per-model capacity history is published as `overload_rate_7d` on `GET /v1/models`. When the overloaded model has a hand-verified same-weights fast tier (e.g. `kimi-k3` and `kimi-k3-fast-api`), the `429` also carries `X-Gondola-Alternative-Model` naming it, with the price difference stated in the error message; switching is your call, nothing is rerouted for you. When it has no such tier, the `429` instead carries `X-Gondola-Fallback-Available: true` and a sentence pointing at the opt-in `x-gondola-fallback-models` header described below, which is the same offer in machine and human readable form. The fallback offer does not appear if you already sent that header; the fast-tier hint still can, since it points at a model rather than at the header. Automatic capacity fallback (opt-in, text endpoints): send the request header `x-gondola-fallback-models` with up to 3 comma-separated model ids you are willing to pay for. When the model you asked for is still overloaded after the internal retry, Gondola tries your listed models in order, at most one attempt each, at each model's own price; your `x-gondola-max-factor` and `x-gondola-max-charge-usd` caps still apply to every candidate. A response served by a fallback carries `X-Gondola-Served-Model` naming what actually ran, and the routing headers (including `X-Gondola-Charge-Usd`) describe that model; when the header is absent, the model you asked for served. Nothing ever switches without this header. Requires an API key (not available on accountless x402 requests). An unknown or non-text model id in the list is a `400` (`invalid_fallback_models`), never silently ignored. Worst case the walk adds up to 3 extra upstream attempts before the original `429` comes back; a server fault mid-walk ends it immediately. Request compatibility on `POST /v1/chat/completions`: bodies are OpenAI-shaped and forwarded as sent, except that params which only exist on other gateways and have no meaning on a single-upstream marketplace are dropped before forwarding instead of failing the request: `include_reasoning` (reasoning models return `reasoning_content` either way), `provider` (incl. `max_price`; use `x-gondola-max-charge-usd` for a price cap), `route`, `models` (the body param is dropped; for capacity fallback use the `x-gondola-fallback-models` request header instead), `transforms` (no prompt compression; an over-long prompt gets the `context_length_exceeded` 400 with the cap headers, and the same code without them when the model's own tokenizer counts the prompt plus the requested output over its context window although Gondola's estimate fit), `usage`, `top_a`, `session_id`, `prediction`, `trace`, `debug`, `stop_server_tools_when`. A few more keys are dropped because Venice's engine rejects them outright: `thinking` (use `reasoning_effort` instead), `logit_bias`, and `prompt_cache_retention`. One more key is dropped for a privacy reason rather than to avoid a `400`: `anon_user_id` (Venice would forward it to the model provider for attribution; Gondola drops it, so nothing in that field reaches the provider; the OpenAI `user` field is still sent and Venice discards it). Params that would change what you get or what you pay are rejected with a `400` (`unrecognized_keys`) rather than silently disabled: `plugins`, `web_search_options`, `modalities`, `image_config`, `structured_outputs`, `service_tier`, top-level `cache_control`, `prompt_cache_options`; web search is enabled through the model suffix (`model:enable_web_search=on`) or `venice_parameters` instead. Out-of-range sampling values clamp or drop instead of failing the request (`seed: -1` and `top_k: -1` mean random/disabled, temperature above 2 clamps to 2, `stop` arrays are capped to their first four strings). Some relayed models (aion 3.5, Claude 5, Gemini) refuse a conversation whose last non-system message is from the assistant, even when system instructions follow it: when one of them refuses a request that ends in system (or developer) messages after an assistant turn, Gondola re-sends those trailing messages once as user messages, at no extra charge, and the response carries `X-Gondola-System-As-User` with the number of messages changed. Nothing is changed unless the model has already refused, and a conversation that really ends with an assistant message (a prefill) gets the model's own `400`. One respelling always happens, on every model: a `role: "tool"` message whose `content` is an array of text parts is sent without its `cache_control` markers, and a single text part is sent as the plain string, because the upstream otherwise shows the model the array as serialized JSON. On Claude models a removed tool-result marker moves to the nearest earlier user or assistant content part (Claude cannot use a marker after a tool step on this API); every removed marker that is not moved, including all of them on other models, is reported as `X-Gondola-Cache-Markers-Dropped: tool-results`. A Claude request that carries a cache marker and a system message after the conversation started gets `X-Gondola-Cache-Warning: system-hoisted`: Claude's API moves every system message to the top, so the cached prefix changes on each request; keep system content at the start to cache it. `/v1/messages` is Anthropic-shaped and rebuilt from an allowlist, so none of this applies there. ## Accountless / agent access (x402) No account, no API key: pay per request with USDC on Base via the x402 protocol (HTTP 402), protocol v2 or v1. Call `POST /v1/chat/completions`, `POST /v1/images/generations`, or `POST /v1/messages` with no Authorization header and the response is a `402` carrying the payment requirements priced for that exact request twice: as a `PAYMENT-REQUIRED` response header (x402 v2 envelope, base64 JSON, CAIP-2 networks) and as the v1 JSON body's `accepts` array. Retry with a signed authorization under `PAYMENT-SIGNATURE` (v2, any current @x402 client) or `X-PAYMENT` (v1, e.g. legacy x402-fetch) and the request is served; the receipt rides back in the `PAYMENT-RESPONSE` and `X-PAYMENT-RESPONSE` headers. Payments settle to Gondola and credit the paying wallet's balance first, so any amount above the metered cost is not lost: it stays as spendable credit for that wallet's next paid request, and signing in at https://gondola-ai.com with the same wallet shows and spends the same balance. `POST /api/buyer/x402-topup` (site host, not the api host) accepts an x402 payment as a plain balance top-up (optional JSON body `{"amount": 20}`). Video endpoints are Bearer-only for now. Live endpoints: - `POST /v1/chat/completions` - text chat (streaming and non-streaming) - `POST /v1/messages/count_tokens` - exact prompt token count for an Anthropic-shaped body, before you send it. Free, no reservation, and callable on a zero balance; the counts it returns are exact rather than estimated. A body large enough to be expensive to tokenize is refused with a 400 rather than counted approximately - `POST /v1/images/generations` - image generation - `POST /v1/images/edits` - image editing (inpaint models) - `POST /v1/images/upscale` - image upscaling (base64 image in, raw upscaled bytes out; scale 2 or 4, fixed price per scale) - `POST /v1/video/quote` - price a video generation before queuing (video pricing is dynamic per model, duration, and resolution; upscale models quote from a video_url plus upscale_factor; the same parameter checks as `/v1/video/queue` apply, so a value the queue would refuse is refused here too) - `POST /v1/video/queue` - submit an async video generation; returns a job id. Modes by model: text-to-video, image-to-video (image_url), transition (image_url + end_image_url), reference-to-video (reference_image_urls, 1 up to a per-model cap between 3 and 30; kling reference models are anchor-first and additionally REQUIRE image_url as the anchor frame, with references optional), video-to-video and video upscale (video_url, https only: Gondola fetches the clip once, an MP4, MOV or WebM file up to 300 seconds on a public https host (standard port), and prices and generates from those exact bytes; the size limit is 18 MB unless the model's `max_source_clip_bytes` on `GET /v1/models` is higher, and a larger clip needs a Gondola balance of at least $2, counts against 20 such fetches per hour per account (a quote and a job each count; past it, 429 `source_clip_rate_limited`), and is held privately until the job ends, answering 503 `source_clip_busy` with `retry-after` when too many clips are being fetched at once; a video-to-video model that takes reference images publishes `max_reference_images` and `min_reference_images`, e.g. minimax-h3-max-recast takes 1 to 4 reference_image_urls naming the identity that replaces the person in the clip). `prompt` is required unless the model's row carries `prompt_required: false`. Some image-to-video and reference-to-video models also accept an optional end_image_url end frame, and some models accept audio inputs: audio_url (a background track, WAV or MP3 up to 30s) and, on reference-to-video, reference_audio_urls (1 to 10 WAV or MP3 voice or sound references, 2 to 15s each and 15s in total, alongside reference images), each a data:audio base64 URL or an https URL; audio output is switched on for them where the model makes it optional. `duration`, `resolution`, `aspect_ratio` and `upscale_factor` are checked against the model's own lists from `GET /v1/models`: a different spelling of a listed value is accepted (`1080p` for `1080P`, `5` for `5s`, `"2x"` for `2`), and a value outside a list the model publishes is refused with a 400 naming the options rather than swapped for another (a field a model publishes no list for is left to Venice). Venice requires `aspect_ratio` on every model that lists aspect ratios, so an omitted one is filled with that model's `default_aspect_ratio`, which is priced the same as an omitted aspect; the quote and the queue response both echo it. A model that does not support a field you sent rejects the request with a 400 before any charge - `POST /v1/video/retrieve` - poll a video job by id (JSON status while processing, raw mp4 bytes when done; a job Venice fails without a reason answers `generation_failed` and is refunded about a minute after the first such poll; the clip stays retrievable until the client acknowledges delivery or is cleaned up within about a day) - `POST /v1/video/ack` - tell Gondola the clip is safely stored so Venice's copy can be deleted promptly (optional and idempotent; the reaper otherwise scrubs about a day after settlement, and retrieve keeps working until then, so a download that dies partway never costs you the clip) - `GET /v1/models` - public, no auth required. Returns every callable model with its modality, target endpoint, capability fields, a per-model `privacy` tier (`private` = zero data retention on Venice-controlled infrastructure, `anonymized` = relayed to the model provider with your identity stripped), and a fee-inclusive "from" price for the cheapest active offer where one exists. Text models also publish `cached_input_usd_per_mtok` and `cache_write_usd_per_mtok` when Venice prices those tiers; prompt caching is automatic server-side on Venice-hosted models (no cache_control needed); Claude models cache up to client `cache_control` markers (on system, user and assistant text parts and on tool definitions), and without an effective marker only a shorter prefix may be cached; cached tokens bill at the cached rate. `prompt_cache_key` (an optional cache-affinity hint, OpenAI convention) is forwarded when you send it; when you do not, Gondola derives a per-conversation key and forwards that, so repeat turns land on the backend that already holds your prefix cache and bill at the cached rate more reliably. If you send your own key, keep it stable for the whole conversation: a key that changes per request scatters your turns across backends and defeats the cache. Video models are quote-priced: get the exact price from `POST /v1/video/quote`. Video rows also publish what `/v1/video/queue` accepts: `durations`, `resolutions` (or `upscale_factors` on upscalers), `aspect_ratios` with the `default_aspect_ratio` an omitted aspect gets, `max_reference_images` on reference-to-video models and on the video-to-video models that take reference images (with `min_reference_images`), `prompt_required: false` on the models that serve a request with no prompt, plus `venice_documented_image_limits` (shortest side and aspect range Venice documents for input images). That last object is Venice's documentation, and some documented minimums are not enforced. Gondola checks a limit only where a probe proved Venice enforces it (today the aspect range on minimax-h3-max-reference-to-video, for base64 images), and refuses an image outside it with a 400 before any charge. Images inside the documented limits are the safe choice. Text models also publish two measured 7-day reliability rates, both per request rather than per upstream attempt (a retried request counts once), and both omitted until measured: `error_rate_7d` is the share of requests that failed through a fault on our side or the model's, and `overload_rate_7d` is the share Venice turned away because the model was at capacity. They are separate on purpose: a high `overload_rate_7d` means a model is oversubscribed right now, not broken, and those requests are never charged. A model our own hourly liveness probe has confirmed down additionally carries `unavailable: true` and `unavailable_since` (ISO timestamp). Both keys are absent otherwise, including for models we have not probed yet, so read absence as "not known to be down" rather than as a health guarantee. Requests to an unavailable model will most likely fail; a request that fails before Venice starts processing it is never charged, and one that an upstream failure cuts short once processing has begun is charged for the prompt and any tokens already delivered. The model stays callable: we publish the signal rather than blocking it, so you can decide whether to switch. - `POST /v1/audio/speech` - OpenAI-compatible text to speech (Bearer-only). `input` up to 4096 characters (over-length is refused, never truncated); `voice` must be one of the model's listed voices from `GET /v1/models` metadata (omit it for the model default; cloned `vv_` voice handles are not supported through the marketplace) and `response_format` one of the model's supported formats. Returns raw audio bytes. Priced per input character at the listed per-1K-characters rate times the routed offer's factor plus the standard buyer fee; the charge is deterministic before the call. - `POST /v1/audio/quote` - price an async music or sound-effect generation before queuing (Bearer-only). Takes the same body as queue and resolves it identically, so the quoted configuration is exactly what a queue would bill; returns the Venice list price and an estimated buyer charge at the current cheapest offer. - `POST /v1/audio/queue` - submit an async music/SFX generation (Bearer-only); returns a job id. `prompt` required; per-model options (`duration_seconds`, `lyrics_prompt`, `force_instrumental`, `lyrics_optimizer`, `loop`, `voice`, `language_code`, `speed`) are validated against the model's own metadata from `GET /v1/models` and refused with the model's real bounds when unsupported. The price is fixed at queue time from the quote. - `POST /v1/audio/retrieve` - poll an audio job by id (JSON status while processing, raw audio bytes when done; the clip stays retrievable until you ack or it is cleaned up within about a day, so a crashed download can just retry) - `POST /v1/audio/ack` - tell Gondola the clip is safely stored so Venice's copy can be deleted promptly (optional; the reaper otherwise scrubs about a day after settlement) - `POST /v1/audio/transcriptions` - OpenAI-compatible speech to text (Bearer-only, multipart). Send `file` (wav, flac, mp3, m4a, or ogg with intact headers; raw AAC and webm are refused with a convert hint) up to about 4 MB (Venice's own cap is 25 MB, but our platform buffers request bodies below that), plus `model`, optional `timestamps` and `language`; `response_format` json (default) or text. Returns `{text, duration, timestamps?}`; billed on `duration` in seconds at the listed per-second rate times the routed offer's factor plus the standard buyer fee. The clip's length is read from the file's own headers before anything is charged. - `POST /v1/embeddings` - OpenAI-compatible embeddings (Bearer-only). `input` is a string or an array of up to 2048 strings; integer token-id arrays are rejected with a 400 (LangChain's OpenAIEmbeddings sends them by default; set `check_embedding_ctx_length=False` so it sends raw text). Per-item token caps are per model (see `GET /v1/models`); billing is per token off the response's `usage.total_tokens` at the listed per-1M-token rate times the routed offer's factor plus the standard buyer fee. - `POST /v1/augment/text-parser` - document text extraction (Bearer-only, multipart). Send `file` (PDF, DOCX, PPTX, XLSX, or plain text) up to about 4 MB plus optional `response_format` json (default) or text; returns the extracted text and its token count. Flat-priced per document at the routed offer's factor plus the standard buyer fee; documents are processed in memory and never stored. - `GET /v1/balance` - your current Gondola balance as JSON (`balance_usd`, `low_balance`), for polling and automated top-ups. Bearer or `x-api-key` auth. ## Market data Public, no auth, aggregate-only read endpoints for research and analytics (CORS-enabled, JSON, ~60s cached). All amounts are USD unless the field name says otherwise; all timestamps are ISO-8601 UTC; every response echoes an `as_of` marker and the resolved `window`. Numbers cover paid traffic only. No wallet, buyer, or lender identity is ever exposed: results are day/model buckets, sums, and distinct counts. - `GET /v1/market/realization?since=YYYY-MM-DD&until=YYYY-MM-DD&model=` - per (day, model) settled aggregate: `lender_received_usd` (USDC the lender actually received), `diem_consumed` (Venice list face in DIEM units; 1 DIEM ~= $1/day of capacity), and `requests`. Realization vs Venice list = `lender_received_usd / diem_consumed`. Top-level `diem_spot_usd` gives the DIEM token price for a token-value view. `day` is the request-start UTC day. `since`/`until` are optional (default last 30 days, max 90-day span); `model` filters to one id. - `GET /v1/market/daily?since=YYYY-MM-DD&until=YYYY-MM-DD` - marketplace-wide daily totals: `volume_usd` (fee-inclusive buyer charge), `requests`, `fees_usd` (broker spread), `lender_received_usd`, `diem_consumed`, `active_lenders`, `active_buyers`. - `GET /v1/market/models?window=24h|7d` - per-model activity: `volume_usd` and `requests` over the window, the cheapest fee-inclusive offer price (`best_input_usd_per_1m_tokens` / `best_output_usd_per_1m_tokens`), and the Venice list price (`venice_list_input_usd_per_1m_tokens` / `venice_list_output_usd_per_1m_tokens`). Price fields are null for non-token models (image, video); each row carries `modality` and `price_unit`. Example: ```python from openai import OpenAI client = OpenAI(base_url="https://api.gondola-ai.com/v1", api_key="gnd_...") resp = client.chat.completions.create( model="llama-3.3-70b", messages=[{"role": "user", "content": "Ciao"}], ) print(resp.choices[0].message.content) ``` ## Links - Home: https://gondola-ai.com - Marketplace (public board of lender offers and prices): https://gondola-ai.com/marketplace - Model prices (public price board: every callable model with its live market price, Venice list price, and the provider's own official API price): https://gondola-ai.com/models - Lend (deposit a Venice key and earn): https://gondola-ai.com/lend - API keys and usage (Dashboard): https://gondola-ai.com/dashboard - Points (weekly points leaderboard, your standing and how the program works): https://gondola-ai.com/points - Setup guides (connect any OpenAI-compatible tool to Gondola): https://gondola-ai.com/guides - Guide, Claude Code: https://gondola-ai.com/guides/claude-code - Guide, Cursor: https://gondola-ai.com/guides/cursor - Guide, Cline: https://gondola-ai.com/guides/cline - Guide, Aider: https://gondola-ai.com/guides/aider - Guide, OpenCode: https://gondola-ai.com/guides/opencode - Guide, Continue: https://gondola-ai.com/guides/continue - Guide, SillyTavern: https://gondola-ai.com/guides/sillytavern - Guide, OpenClaw: https://gondola-ai.com/guides/openclaw - Guide, Hermes Agent: https://gondola-ai.com/guides/hermes-agent - Guide, oh-my-pi: https://gondola-ai.com/guides/oh-my-pi - Guide, New API: https://gondola-ai.com/guides/new-api - Guide, OpenHarness: https://gondola-ai.com/guides/openharness - Guide, Ante: https://gondola-ai.com/guides/ante - Guide, Zot: https://gondola-ai.com/guides/zot - How Gondola works (the Venice relationship and the request pipeline): https://gondola-ai.com/guides/how-it-works - X (updates and announcements): https://x.com/gondolamarket - Privacy: https://gondola-ai.com/privacy - Terms: https://gondola-ai.com/terms - Built on Venice AI: https://venice.ai - Venice AI's own docs (authoritative for model behavior, characters, privacy tiers): https://docs.venice.ai