API Reference
Version: 3.29.2 | Last Updated: 2026-10-18
Claude 5.5 — additional capacity (2026-10-18):
claude-opus-5-5andclaude-sonnet-5-5retain their IDs, prices and customer discounts. The additional verified-account route supports text, vision, streaming and automatic client function round trips, including parallel calls. Selectthinking_level: low | medium | high(default High). Its declared context is 1M tokens and maximum output 128K; the context probe covered 38K input tokens. Native cache hits are returned inusage.prompt_tokens_details.cached_tokensand used in billing. JSON object/schema enforcement is unavailable on the current active Claude 5.5 routes:response_formatreturns 400 before generation and customer billing. A JSON request in ordinary user text is not guaranteed structured output. Forced tool choice is currently unsupported on the active Claude 5.5 transports and returns 400. Strict function schemas, mixed tools+JSON and explicit cache breakpoints do not use the AGY route; no parameter is silently downgraded. API429 adds no agent system prompt or toolset.ChatGPT consumer models (2026-10-16): 12 new
chatgpt-*model IDs onPOST /v1/chat/completions— GPT-6, GPT-5.6, GPT-5.3 families with built-in web search. Append-searchto any base ID (e.g.chatgpt-gpt-6-mini-search) to enable web browsing. Prices match official OpenAI API rates.chatgpt-researchprovides autonomous deep research. See the GPT section below.Gemini 4 Argon (2026-10-15): use
gemini-4-argononPOST /v1/chat/completions, with ordinary or streaming responses.thinking_levelacceptslow,mediumandhigh(default). Text, image understanding, client-executed function tools andresponse_format(json_object/json_schema) are supported. JSON streams are buffered until the complete response passes JSON/schema validation, then emitted as OpenAI SSE. Invalid or truncated JSON returns 502 and is not billed by API429; invalid schemas return 400 before generation. Use local schema references only; external references and$idresources are rejected. Hosted tools, video and combining tools with JSON response_format in one request remain unavailable. Check your key'sGET /v1/modelsfor access. Thinking tokens are included incompletion_tokensand billed as output. Exact prices and account discounts come from the runtime catalog; private effort IDs are not additional public models.Additional text models (2026-10-13):
gemini-3.1-flash-lite,gemini-2.5-flash-thinkingandgpt-oss-120b-mediumsupport text chat and streaming. Check availability and your token's permissions withGET /v1/models; use exact IDs. Existinggemini-3.5-flash-litecalls now have another exact-model serving route. Rates and discounts remain available in the runtime catalog. Hidden GPT-OSS thought parts are not concatenated into the final answer.Image model names: documentation and the website list each image model once, using its technical ID with the friendly name in parentheses. Nano Banana names are compatibility aliases, not additional models. Existing API calls and authenticated
/v1/modelscompatibility entries are unchanged.Fish Audio billing (2026-10-10):
fish-s2.1-prois now billed like the official Fish Audio API — $15 per 1M UTF-8 bytes of input text, before your client-level discount. Latin text is 1 byte per character (unchanged); Cyrillic is 2 bytes and Chinese/Japanese/Korean 3 bytes per character.Claude 5.5 (2026-10-10):
claude-opus-5-5,claude-sonnet-5-5andclaude-haiku-5-5are available onPOST /v1/chat/completions. Each answered real requests in production. Prices are Anthropic's official list rates before your client-level discount; Haiku 5.5 bills prompts over 100,000 input tokens at its higher tier. See the Extended text models table.GPT-6 Astra:
gpt-6-astrasupports text/images, streaming, reasoning and strict JSON. Use/v1/responsesfor client-executed tools, including async function calls. Hosted OpenAI tools, WebSocket steering and Fast/Flex are not enabled on this route. See the GPT section below.GPT-6.1 Sol (2026-09-30): use
gpt-6.1-sol; the baregpt-6.1is an alias of it. It answered real requests on the production Codex route. Only the Sol tier of GPT-6.1 is served:gpt-6.1-luna,gpt-6.1-astraandgpt-6.1-terraare not available. Reasoning effort islowthroughmax(nonone); use/v1/responsesfor tools.GPT-6 Sol and Luna (2026-09-23): use the exact IDs
gpt-6-solandgpt-6-luna. Both answered real text requests on the production Codex route. Sol is available on two of the three active credentials tested; the gateway rotates away from an account that returns a model-entitlement error. Check your token'sGET /v1/modelsbefore use. There is no publishedgpt-6-terraID;gpt-5.6-terraremains available.Pricing clarification (2026-09-06): numerical tables here are API429 base/configuration references, not a live official vendor quote or a personal retail quote. Standard API429 retail, conditions and cache rates come from the runtime catalog. Existing GPT-5.6 base rates remain unchanged; OpenAI's current promotional Sol/Terra prices are lower. Do not infer a universal 70% saving against today's vendor price.
Current Gemini Flash models (2026-09-03):
gemini-3.8-flashis the latest stable Flash model published by API429.gemini-3.7-flashremains supported. The release notes below describe past releases, not the access granted to an individual token.Check access with the same key and endpoint: the website's public catalog is platform-wide;
GET /v1/modelsis filtered for the token used in that request and the currently available serving routes. An older token can have an explicit model allowlist that does not automatically gain new models. Absence from the token's catalog is not, by itself, a reason to upgrade your plan. Ask support to review the token's model permissions, then refresh the catalog.If a listed model returns
not supported: retry the catalog check with the exact same token and base URL used for generation, and use the exact canonical model ID. The current error can also mean the token's allowlist excludes the model. Send support the model ID, endpoint, request time andtrace_id(or only the token's last four characters), never the full token. Do not keep retrying a fixed access restriction or assume a plan change will resolve it.What's new in 3.26.0
- More Gemini TTS models:
gemini-3.8-flash-tts,gemini-3.8-flash-lite-ttsandgemini-2.5-flash-preview-ttsjoingemini-3.1-flash-tts-previewonPOST /v1/audio/speech. See "Text-to-Speech".- Speech-to-text: new OpenAI-compatible
POST /v1/audio/transcriptionswithgemini-3.5-transcribe—json,text,verbose_json(segments with speaker labels, word timestamps),srtandvtt. See "Speech-to-Text".What's new in 3.25.0
- Eleven v4 and v4 Turbo:
eleven_v4andeleven_v4_turbo, the newest ElevenLabs speech models (released 2026-09-28, 90+ languages), are available onPOST /v1/audio/speechand listed inGET /v1/models.eleven_v3stays available unchanged. See "ElevenLabs models".What's new in 3.24.0
- Extended text catalogue: Kimi (
kimi-k3,kimi-k2.7-code), Qwen (qwen-3.8-max,qwen-3.8-flash), GLM (glm-5.3,glm-5.3-flash,glm-5.2,glm-5-turbo), DeepSeek (deepseek-v4-pro,deepseek-v4.1-flash), MiMo (mimo-v2.5-pro,mimo-v2.5),minimax-m3,hy4-previewandcomposer-2.5-fastonPOST /v1/chat/completions. See "Extended text models".- New Claude, Gemini and Grok ids:
claude-fable-5.1,gemini-3.6-flashandgrok-4.5.- These models accept text input only.
What's new in 3.23.0
- GPT Image 2.5:
gpt-image-2.5-flare(fast mode) andgpt-image-2.5-sunburst(thinking mode) are available onPOST /v1/images/generationsat a fixed price per image: $0.053 and $0.211 official, $0.0159 and $0.0633 API429 standard. See "GPT Image 2.5".- Landscape and portrait sizes keep their shape: on
/v1/images/generations,size:"1536x1024"andsize:"1024x1536"now produce 3:2 and 2:3 images instead of squares, and any otherWIDTHxHEIGHTuses the nearest supported aspect ratio. The DALL·E sizes andgpt-image-2are unchanged.What's new in 3.22.1
- GPT-5.4 / 5.3 / 5.2 retired upstream: on 2026-09-08 OpenAI stopped serving
gpt-5.4,gpt-5.4-mini,gpt-5.3-codexandgpt-5.2on the transport this gateway uses. The IDs stay accepted as compatibility aliases:gpt-5.4-mini(andgpt-5-mini) resolve togpt-5.6-luna, the others togpt-5.6-terra, and each request is billed at the resolved model's rate. Migrate to the GPT-5.6 IDs explicitly.gpt-5.6-lunais available: the lightweight GPT-5.6 tier now serves on Chat Completions and Responses at $1.00 / $0.10 / $1.25 / $6.00 per 1M (input / cached / cache write / output).GPT-6.1 Sol release (2026-09-30)
- Added
gpt-6.1-solto the Codex route and public catalog after a direct provider probe, withgpt-6.1as an alias. Rates: $2.00 / $0.10 / $2.50 / $10.00 per 1M (input / cached / cache write / output); above 272K input $4 / $0.20 / $5 / $15.- The other GPT-6.1 tiers answered "not supported" on this route and are not advertised.
GPT-6 Sol/Luna release (2026-09-23)
- Added canonical
gpt-6-solandgpt-6-lunato the Codex route and public catalog after direct provider probes.gpt-6-terrais not an available model ID.- The model-specific retry path skips a credential that rejects Sol without disabling that account for other models. Existing token allowlists remain unchanged.
What's new in 3.20.3
- Images in Chat Completions:
message.imagesand a realusage: an image model on/v1/chat/completionsnow returns the picture(s) inmessage.imagesasimage_urlparts (the shape OpenRouter and the Vercel AI SDK use) in addition to the markdown data URI kept incontent.usageis no longer{0, 0, 0}: it reports the prompt's text tokens plus 1290 per reference image, 1290 per generated image (completion_tokens_details.image_tokens) andimage_count. Streaming sends one image event, a finish chunk and, withstream_options.include_usage, a usage chunk before[DONE]. Billing is unchanged: per generated image. See "Image models on Chat Completions".gemini-2.5-flash-imageon/v1/chat/completionsgenerates images again: the model now runs on the image path like the rest of the Gemini image family. A text prompt returns a generated image,image_urlparts in the last user message are used as the edit source, and the request is billed at the image rate. Previously the call could answer with empty content (reasoning tokens only) and be billed as text.- No charge for an image model that returns no image: if a Gemini image model answers a chat request with neither an image nor visible text, the gateway returns
502withThe image model returned no image; the request was not billed.instead of a paid empty200.capabilitiesinGET /v1/models: every model item now carries acapabilitieslist (for example["chat", "image_editing", "image_generation", "vision"]), the same values the public catalog publishes. Useimage_editingto pick a model for/v1/images/editsinstead of probing with paid calls. Standard OpenAI fields are unchanged.- Image alias listing:
nano-bananaandnano-banana-proare listed inGET /v1/modelsagain (they are served by Google asgemini-2.5-flash-image/gemini-3-pro-image).nana-bana-proand the retiredgemini-3-pro-image-preview/gemini-3.1-flash-image-previewremain accepted as compatibility aliases but are not listed.- Gemini 3.5 Flash serving route: on 2026-09-03 the upstream that served the
gemini-3.5-flash-low/-medium/-higheffort variants retired Gemini 3.5 Flash and began answering with a text notice instead of an error.gemini-3.5-flashis now served on Google's own transports only, and the three effort IDs remain accepted as compatibility aliases ofgemini-3.5-flashat the same price. The suffix no longer changes the reasoning budget — passthinking_level(low/medium/high) ongemini-3.5-flashinstead.gemini-3.5-flash-lowis no longer listed inGET /v1/models.- Retirement notices are errors: a provider reply whose only content is a "model is no longer available" notice is treated as a failed attempt — it is retried on the next serving route and is never billed.
What's new in 3.20.2
- Music access for customers: new active
external_customertokens receive both asyncvideoandaudioscopes by default. Existing customer and project tokens are upgraded only while they retain API429's managed policy.- Explicit restrictions stay explicit: test, internal, admin, unclassified, and manually configured policies are unchanged. Restricted model allowlists must include
lyria-3-pro-previewbefore the token can generate music.What's new in 3.20.0
- Lyria 3 Pro music generation: added
lyria-3-pro-previewthrough the durable asyncPOST /v1/music/generationsAPI.- Songs and instrumentals: prompts may request genre, mood, arrangement and structure; optionally provide lyrics or request instrumental-only output. The result is an MP3 delivered by HTTPS URL.
- Safe paid requests:
Idempotency-Keyis mandatory, jobs are never automatically replayed after an uncertain upstream outcome, and each completed song costs $0.08.What's new in 3.19.0
- Gemini 3.8 Flash GA: added the exact canonical model ID
gemini-3.8-flash, generally available since 2026-09-02. API429 exposes it through both client-token and Service Account authentication.- Context and reasoning contract: 1,048,576-token input window, 65,536-token output limit, and
low/medium/highreasoning effort withmediumas the default.- Canonical-only requests: do not append
-non-thinkingor effort suffixes to the model ID. Customtemperature,top_p,top_k, andn/ nativecandidateCountare unsupported.- Strict request validation: generation must end with a non-empty user text turn; model-prefill turns are rejected. Native
FunctionResponseparts require both a call ID and function name.- Promotional pricing: $0.75 input, $0.075 cached input, and $3.75 output (including thought tokens) per 1M tokens through 2026-12-31. The 2027 rates double to $1.50 / $0.15 / $7.50 and require a pricing update before 2027-01-01.
What's new in 3.18.0
- Gemini Omni 1.1 Flash: use the stable client model ID
gemini-omni-1.1-flash. The retiredgemini-omni-flash-previewand shortgemini-omni-flashspellings remain input-only compatibility aliases.- New Omni controls: added
360p,1080p, and4kalongside720p, first/last-frame interpolation, and source-video extension.- Resolution-aware video billing: Omni reservations and usage fallback use Google's published token rate for the requested resolution; native provider usage remains authoritative when returned.
- Safe video access default: active external-customer tokens receive only the async
videoscope by default. Text, image, and audio async scopes remain explicit admin opt-ins.- Native TTS billing parity: Gemini
generateContentspeech requests now use the same character-based balance preflight and single successful-request charge as/v1/audio/speech, including multi-speaker requests.What's new in 3.17.0
- Gemini TTS contract corrected:
gemini-3.1-flash-tts-previewis the current Gemini speech model on both API429 TTS surfaces. Cloud TTS model IDs are no longer presented as GeminigenerateContentmodels.- Round-trip-safe media: standard and URL-safe base64 inputs are accepted; gateway output is canonical padded standard base64.
- Image response contract:
response_format:"url"always returnsurl(with a data-URI fallback), Google MIME/person controls use a Vertex-backed credential, and the actual returned MIME is preserved.- Resolution billing clarified: exact Gemini Flash and Pro prices are listed for 1K, 2K, and 4K, including standard API429 discounted amounts.
What's new in 3.16.0
- Branded endpoint: the API is now published at
https://gateway.api429.com. The previous address keeps working; no migration required.What's new in 3.16.0
- Voice cloning: upload a recording to
POST /v1/audio/voicesand pass the id it returns asvoiceonPOST /v1/audio/speech. The voice is private to the key that created it. Billed per character like any other synthesis; registering a voice is free.- Voice catalogue:
GET /v1/audio/voiceslists the public voices a model accepts, filterable bylanguageandq. Addscope=minefor your own cloned voices.voiceis required onfish-s2.1-pro: there is no default. Omitting it, or passing a voice name rather than a 32-character id, returns400— a wrong voice is never silently substituted.What's new in 3.15.0
- nobalancerapi catalogue: a separate set of image, editing and video models enabled per account rather than served by default — Midjourney, FLUX.1, Qwen Images, Sora Images, DALL·E 3, clothing replacement, and video (Veo, Kling, Pika, face replacement, upscale). Pricing on request.
- Midjourney batches: a generation returns all 4 images of the job by default (you are billed per job, not per returned image); pass
nexplicitly to receive fewer. Request-levelsize/aspect_ratioare ignored — use--arinsideprompt.- Midjourney modifications: every generated image returns an
id; pass it assource_image_idwithmj-upscale,mj-upscale-creative,mj-outpaint-*,mj-variations-subtle,mj-variations-strongormj-remixto act on that image.What's new in 3.14.0
- Fish Audio TTS: new
fish-s2.1-proonPOST /v1/audio/speech— 80+ languages, a large public voice library, $15 per 1M UTF-8 bytes official ($4.50 after the standard 70% discount).- Output formats:
fish-s2.1-prohonoursresponse_format—mp3(default),wav,pcm,opus. Usewavwhen the consumer requires RIFF/WAVE.- Long-form narration: long input is split on sentence boundaries, synthesised in parallel and returned as one joined clip. An hour of speech takes roughly three minutes;
opuscannot be joined and returns400for long input.- Link delivery: send
"delivery": "url"on/v1/audio/speechto get a JSON descriptor with a CDN link instead of the audio bytes. Omit it and the raw-bytes response is unchanged.What's new in 3.13.0
- Grok 4.6: added the exact canonical xAI model id
grok-4.6after production probes confirmed text, vision, reasoning, function calling, structured output, Chat Completions, and Responses API.- Reasoning:
reasoning_effortacceptslow,medium,high, orxhigh; omit it for xAI'shighdefault. Reasoning cannot be disabled.- Exact usage and billing: cached input and reasoning tokens are preserved and charged once. Official Standard rates are $2 input / $0.50 cached input / $6 output per 1M below 200K input tokens, and $4 / $1 / $12 from 200K input tokens onward, before API429 discounts.
- Fail-closed tools: local function tools are supported. Separately billed xAI web, X, and code-execution tools are not exposed until per-call metering is available.
What's new in 3.12.0
- Gemini 3.7 Flash: added the stable
gemini-3.7-flashmodel, with a 1,048,576-token input window, 65,536-token output limit, multimodal input and text output. For the latest published Flash model, see the current-model note above.- Verified availability: production validation confirmed the canonical ID. API429 publishes only
gemini-3.7-flash; provider-specific effort suffixes are not part of the public API.- Current promotional pricing: $0.75 input, $0.075 cached input and $3.75 output per 1M tokens through 2026-12-31. Google has announced $1.50 / $0.15 / $7.50 starting 2027-01-01.
- Compatibility controls: OpenAI clients may send
temperature,top_p,top_kandthinking_budget; API429 removes those unsupported controls before dispatch. Usethinking_levelorreasoning_effortwithlow,medium, orhigh(default:medium).What's new in 3.11.0
- Nano Banana Pro is GA: use canonical ID
gemini-3-pro-image. The retiredgemini-3-pro-image-previewID and friendly namesnano-banana-pro/nana-bana-proremain accepted as compatibility aliases and are rewritten before the Google request.- Model catalogue re-audited: every
Available Modelstable (text, GPT, Claude, image, video, TTS) was verified against live pricing; no other IDs or prices changed.What's new in 3.10.0
- Single ElevenLabs model: the ElevenLabs family is now one canonical model,
elevenlabs-gen, listed inGET /v1/modelsat $0.100 / 1K chars official ($0.030 after the standard 70% discount). It is served by three interchangeable backends tried in order until one returns audio, and you are always billed at theelevenlabs-genrate no matter which backend served the request.- Legacy ids still accepted:
eleven_v3,eleven_multilingual_v2,eleven_flash_v2_5, andapi429-ttskeep routing for backward compatibility but are no longer advertised in the catalogue; new integrations should useelevenlabs-gen.What's new in 3.9.0
- Claude Opus 5 and Claude Fable 5:
claude-opus-5andclaude-fable-5are available for Claude chat workloads. Both are listed in the Claude pricing table below and served through the standard Claude provider chain.- ElevenLabs standby: every ElevenLabs model now has a primary backend and an automatic standby. If the primary is unavailable the request is retried transparently, and you are billed for the model you asked for either way.
- Generic ElevenLabs alias:
api429-ttsrequests ElevenLabs speech without pinning a specific model; it resolves to the current default (eleven_multilingual_v2).- Gemini TTS correction: the earlier multi-model rollout was superseded. The current Gemini TTS model on
/v1/audio/speechand the Gemini-native gateway isgemini-3.1-flash-tts-preview.- Content filter: TTS input rejected by the speech provider's content filter now returns
422naming how many fragments were blocked, instead of a generic failure.- Fixed reasoning-effort Gemini variants:
gemini-3.5-flash-lowandgemini-3.1-pro-loware documented and billed at their base model's rate.- Catalogue cleanup:
GET /v1/modelsno longer advertises IDs it cannot serve — internal route twins, a disabled provider's aliases, vendor-prefixed catalogue keys, and reasoning variants that do not resolve upstream. These IDs already returned an error when called; listing them was the bug. Request routing itself is unchanged, so nothing that worked before has stopped working. If you pinned one of the removed IDs, switch to the documented equivalent: use the clean alias (gemini-2.0-flash, not a vendor-prefixed form), the base Claude model instead of accw-twin, andgemini-3.5-flashorgemini-3.1-pro-previewinstead of a-high/-mediumvariant.What's new in 3.8.0
- ElevenLabs TTS: added
eleven_v3,eleven_multilingual_v2, andeleven_flash_v2_5on the OpenAI-compatiblePOST /v1/audio/speechendpoint.- Native voices: pass an ElevenLabs
voice_idthrough the standardvoicefield; the requested ElevenLabs model is preserved end to end.- Transparent pricing: the catalogue shows the official ElevenLabs character price and the standard API429 price after the 70% discount.
What's new in 3.7.0
- Gemini Omni Flash video: added native
gemini-omni-flash-previewgeneration through the async/v1/videos/generationsAPI. The accepted compatibility alias isgemini-omni-flash.- Multimodal video workflows: text-to-video, image-to-video, reference-to-video, source-video editing, and stateful follow-up editing with
previous_job_idare supported.- Usage and billing: completed Omni jobs expose native input/output/thought token usage when Google provides it, and billing settles the initial reservation to official Agent Platform usage.
- Model integrity: Omni requests are not silently routed to Veo or another video model. Check
GET /v1/modelsfor availability on your token.What's new in 3.6.0
- GPT-5.6 family: added
gpt-5.6(alias ofgpt-5.6-sol),gpt-5.6-sol, andgpt-5.6-terrafor Chat Completions and Responses API.- Reasoning: GPT-5.6 supports
none,low,medium,high,xhigh, andmax; the default ismedium.- Usage and billing: cache-read/cache-write usage is preserved, streaming requests are billed from the final usage event, and requests above 272K input tokens use the published long-context rates.
- Availability:
gpt-5.6-lunawas not available at launch; it is listed since 3.22.1. CheckGET /v1/modelsfor the authoritative per-token catalogue.What's new in 3.5.10
- Nano Banana 2 Lite (
gemini-3.1-flash-lite-image/nano-banana-2-lite) is now available onPOST /v1/images/generations.- Pricing: Lite image generation is billed at $0.0336 per 1K output image; batch image jobs use the $0.0168 batch unit.
- Routing: the public alias resolves to the Google/Vertex native image model ID before provider selection.
What's new in 3.5.9
- Claude Sonnet 5 (
claude-sonnet-5/claude-sonnet-5.0) is now available for Claude chat workloads through the standard Claude provider chain.- Pricing and context: Sonnet 5 is listed at $2 input / $10 output per 1M tokens during the current launch pricing window and supports a 1M-token context window.
- Availability note: Sonnet 5 is available through the gateway's current Claude routes; provider-specific route details are intentionally not part of the public contract.
What's new in 3.5.8
- Anthropic-compatible Messages API: documented
POST /v1/messagesfor Claude clients that already use the official Anthropic Messages API shape. Usex-api-keyauth and the same API429 client token.- Claude usage transparency: clarified
usage.input_tokens/usage.output_tokenson native Messages responses andprompt_tokens/completion_tokenson OpenAI-compatible responses.- Claude native streaming: documented Anthropic SSE event order for
stream:trueon/v1/messages.- Claude cache and web search notes: documented the current public contract for prompt-cache usage fields and Anthropic server-tool passthrough.
What's new in 3.5.7
- Grok models: added xAI Grok text models —
x-ai/grok-4,x-ai/grok-4-reasoning,x-ai/grok-3,x-ai/grok-3-reasoning— on the standardPOST /v1/chat/completionsendpoint.- Extended text catalogue: additional vendor-prefixed chat IDs are now selectable —
openai/gpt-5,openai/gpt-5-instant,openai/gpt-5-thinking, andgoogle/gemini-3-pro,google/gemini-2.5-pro,google/gemini-2.5-flash.- New image models:
nano-banana-2(alias ofgemini-3.1-flash-image),api429-image,gpt-image-1, andgrok-image(xAI Aurora) added toPOST /v1/images/generations.- Confirm availability with
GET /v1/modelsusing the same token and base URL as generation. The response reflects model permissions and serving availability, not an automatic promise of access after a plan change.What's new in 3.5.6
- Gemini video input for chat: token-gated Gemini text routes now accept video input on
POST /v1/chat/completionsusing OpenAI-compatible message content parts.- Supported video input shapes:
input_videowith base64 data, and directvideo_urlinputs that the gateway stages temporarily before sending to Gemini.- Streaming support:
stream:trueworks for video-input chat requests and returns standard OpenAI-compatible SSE chunks.What's new in 3.5.5
- Veo 3.1 video generation: added async video generation docs for
veo-3.1-generate-001,veo-3.1-fast-generate-001, andveo-3.1-lite-generate-001.- Native migration paths: clients can use the API429/OpenAI-style
/v1/videos/generationsroute or Vertex-compatiblepredictLongRunning/fetchPredictOperationroutes by changing only the base URL and token.- Video billing: documented per-second Veo 3.1 list prices and async polling behavior.
What's new in 3.5.4
- Gemini 3.5 Flash (
gemini-3.5-flash) is now part of the public Gemini text catalogue. It supports chat, streaming, multimodal input, function/tools, structured output, search grounding, code execution and thinking. Output is text only.- Pricing:
gemini-3.5-flashis billed at the Google Standard PayGo Global text rate: $1.50 input / $9.00 output per 1M tokens. Image generation, TTS and embeddings use their own model IDs.What's new in 3.5.3
- Self-contained client docs: removed links to separate
.mdguides that are not served publicly. GPT Image 2, Claude, TTS, embeddings and multimodal examples now live in this API Reference.- Claude public contract cleanup: public docs list only canonical Claude model IDs (
claude-*). Internal routing/fallback model IDs are intentionally not documented for client integrations.- Client troubleshooting cookbook: added concrete guidance for SSE parsing, image edits/reference images, 429/503 retries, unsupported fields and endpoint/model mismatches.
What's new in 3.5.2
- Public model catalogue audit: the GPT and Gemini tables now match the current client-visible
/v1/modelscatalogue. Unsupported legacy GPT/Codex IDs and the allowlist-gated Gemini custom-tools preview are no longer advertised as public model IDs.- Canonical IDs clarified: use the exact model IDs in these tables for new integrations.
GET /v1/modelsremains the authoritative per-token allowlist.What's new in 3.5.1
- GPT Image 2 client guide: clarified how to call
gpt-image-2through API429 Images endpoints and how billing is calculated from text input, image input and image output.- GPT Image 2 pricing refresh: updated API429 billing notes to match OpenAI's current GPT-Image-2 token rates and official per-image calculator examples.
What's new in 3.5.0
- Claude catalogue refresh: all public Anthropic/Claude text models are listed with canonical model IDs, accepted aliases, context windows and API429 list prices.
- Claude integration guide cleanup: public docs now describe only the client-facing API contract (
/v1/chat/completions, streaming and jobs).What's new in 3.4.0
- GPT Image 2:
model:"gpt-image-2"on/v1/images/generationsand/v1/images/editsis documented as a dedicated GPT Image path, not a Gemini image alias.- GPT Image edits/reference images:
/v1/images/editsand Responsesimage_generationguidance now coversinput_image, masks, supported output options, concrete GPT Image 2 pricing, and client-visible retry/error behavior.What's new in 3.3.0
- Claude streaming updates for plain
stream:truechat requests. Text deltas stream through OpenAI-compatible SSE.stream:true + toolsremains synthetic SSE.What's new in 3.2.0
- Claude long-gen optional headers for batch screenwriter / multi-turn workflows:
X-Session-Keyfor conversation continuity andX-Async-Jobs-Optin: truefor durable jobs on overload. See "Optional headers" under Claude Models below.What's new in 3.1.0
- Claude Sonnet 4.5 (
claude-sonnet-4-5/claude-sonnet-4.5) — same pricing as 4.6 ($3 / $15 per 1M), 200k context, Extended Thinking enabled.- GPT-5.5 (
gpt-5.5) — frontier model from OpenAI, $5 / $30 per 1M.- Gemini 3.1 TTS preview (
gemini-3.1-flash-tts-preview) — the current Gemini speech model on API429.OpenAI-compatible gateway for chat, image, text-to-speech and embedding models across the Gemini, GPT and Claude families, plus native-compatible Gemini and Anthropic entry points for clients that already use those SDKs. Supports both Chat Completions and Responses API formats. Works with any OpenAI SDK client (Python, JS, Go, Rust, Ruby, Java, cURL).
Argon function round trip
Send OpenAI tools with type: "function". tool_choice supports auto,
none, required, or a declared function name in the standard object form.
The API returns finish_reason: "tool_calls"; your application executes the
functions. Append the complete assistant message, including each call's
id and any extra_content.google.thought_signature provided, then append a role: "tool"
message with the matching tool_call_id and the function result for every
call. Send the resulting history with the same model and function declarations,
usually with tool_choice: "auto", to obtain the final answer. This also works
with streaming and multiple calls in a turn; assemble calls by their stream
index and preserve their signatures. API429 does not execute your functions.
Google may sign only the first call in a batch; preserve signatures where present.
For structured output, send for example
{"type":"json_schema","json_schema":{"name":"answer","strict":true,"schema":{"type":"object","properties":{"answer":{"type":"integer","enum":[42]}},"required":["answer"],"additionalProperties":false}}}
as response_format. API429 validates the original schema, including required
fields, enums and additionalProperties, and removes a complete Markdown JSON
fence if AGY adds one. It does not repair malformed JSON or make a second paid
generation to fix it. For json_object, the result must be a JSON object.
Browser Studio and API Reference
Studio is a visual playground, not the endpoint reference. It offers text, single-image generation and single-speaker TTS with a personal API429 client key. The model selector is filtered to the modes supported by Studio and the key's current access; a listed route is not an uptime guarantee. Video generation is not yet available in the Studio interface. For arbitrary supported API payloads, use the interactive API Reference.
Studio supports elevenlabs-gen with the configured default voice and MP3 output. Gemini TTS voice selection appears only when gemini-3.1-flash-tts-preview is actually published and available to the key; a legacy Gemini example does not enable that route.
- Guest examples are prepared demonstrations, clearly labeled; they do not call a model or incur charges. The voice demo explains the live player rather than playing a fabricated result.
- Real runs use your own paid balance. Connecting a key and obtaining an estimate are free. Studio does not accept an administrator key and does not supply a shared provider key.
- Before a run, Studio shows a reservation. The server enforces that displayed maximum, settles actual usage through normal billing and releases the unused amount. Direct API calls have their own billing and do not inherit Studio's spending limits.
- MVP limits: 2,000 prompt characters, 1,024 output tokens for text, one 1K image, one active run per funding wallet, 10 admissions/minute and $5 of cumulative reservations/day (UTC), with at most $1 reserved per run. Failed admissions do not consume funds; completed failed runs still count toward the daily reservation quota. Project keys share their parent's wallet limits. Metadata requests are additionally limited per wallet/process.
- A failed response with no recorded billable usage releases the reservation. A timeout, interrupted connection or missing metering puts the request on hold for reconciliation; it does not prove the provider stopped work. Use Check request and send support the displayed request ID. Do not keep starting new generations or refresh before saving that ID.
- Check request is strictly read-only: it cannot initiate generation, including when the original request never reached the server. An unknown request stays unresolved until you check again or contact support. Estimates use the selected model's catalog pricing route, and the UI preserves small charges to six decimal places.
- Your API key remains in the tab's memory and is sent over HTTPS only to API429 for execution; it is not saved in browser storage. Studio has no marketing session replay or analytics scripts. Result bodies are encrypted server-side, available for replay for 24 hours, and then cleared by periodic cleanup. Financial records and request IDs are retained. Normal provider processing and service logging still apply.
Studio по-русски
Открыть Studio: выберите режим, подключите клиентский ключ из личного кабинета, введите запрос и проверьте резерв перед платным запуском. Технический справочник находится отдельно. Гостевой демопример не обращается к модели. При неопределённом результате используйте «Проверить запрос» и сохраните Trace для поддержки; новый платный запрос автоматически не запускается. Видео пока не включено в интерфейс Studio.
Quick Start
Base URL: https://gateway.api429.com/v1
Auth: Authorization: Bearer YOUR_API_KEY
The previous address
https://hostkey24760.api429.comcontinues to work; existing integrations do not need to change anything. New integrations should usehttps://gateway.api429.com.
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY"
)
response = client.chat.completions.create(
model="gemini-3.1-pro",
messages=[{"role": "user", "content": "Hello!"}]
)
print(response.choices[0].message.content)
Table of Contents
- Endpoints & Auth Matrix
- Authentication
- Text Models (Chat Completions)
- Responses API
- GPT Models
- Grok & Extended Catalogue
- Claude Models
- Image Generation Models
- Embeddings
- Video Generation Models
- Text-to-Speech
- Integration Cookbook
- Files API
- Client Usage & Balance
- Error Handling
- Rate Limits
- Supported SDK Clients
Endpoints & Auth Matrix
The same base host (https://gateway.api429.com) serves four API families.
Pick the one that matches your SDK.
| API family | Paths | Auth |
|---|---|---|
| OpenAI-compatible | /v1/*, /hf/v1/*, /openai/v1/* — models, chat/completions, responses, images/generations, embeddings, audio/speech |
Authorization: Bearer <token> |
| Anthropic-compatible | POST /v1/messages — Claude Messages API request/response shape, including Anthropic-style SSE streaming |
x-api-key: <token> |
| Gemini native | /v1beta/models/{model}:generateContent, :streamGenerateContent, :countTokens, :embedContent, :batchEmbedContents (also under /gemini/v1beta/*) |
x-goog-api-key: <token> or ?key=<token> |
| Vertex Express | /vertex-express/v1beta/models/{model}:generateContent, :streamGenerateContent, GET /vertex-express/v1beta/models |
x-goog-api-key: <token> or ?key=<token> |
| Video generation | /v1/videos/generations, /v1/videos/generations/{job_id}, Vertex-compatible :predictLongRunning / :fetchPredictOperation |
Bearer token for /v1/videos/*; x-goog-api-key, ?key=, or Bearer token for Vertex-compatible routes |
| Files API | POST /upload/v1beta/files, GET/DELETE /v1beta/files[/…] (plus /gemini/ variants) |
x-goog-api-key: <token> or ?key=<token> |
| Client usage | GET /api/client/balance, GET /api/client/usage/daily, GET /api/client/usage/summary, POST /api/client/usage/daily/telegram |
Authorization: Bearer <token> |
Streaming endpoints return text/event-stream (SSE). Error payloads are normalised
as {"error": {"code": ..., "message": ...}}.
Authentication
All OpenAI-compatible and client-usage endpoints require a Bearer token:
Authorization: Bearer YOUR_API_KEY
Anthropic-compatible /v1/messages accepts the same API429 client token in
Anthropic's standard header:
x-api-key: YOUR_API_KEY
anthropic-version is accepted for SDK compatibility. The gateway does not
require clients to pin a specific version.
Gemini-native, Vertex Express, and Files API endpoints accept the Google-style header or query parameter:
x-goog-api-key: YOUR_API_KEY
GET /v1beta/models?key=YOUR_API_KEY
Tokens are issued by the admin panel. Contact your administrator for access.
Service Account (SA) authentication is also supported for Google Vertex AI SDK clients. See the dedicated Service Account Guide tab for setup instructions and examples.
Text Models (Chat Completions)
Available Models
| Model | Status | Input $/1M tokens | Output $/1M tokens | Capabilities |
|---|---|---|---|---|
gemini-3.8-flash |
Stable | $0.75 | $3.75 | chat, vision/multimodal input, thinking, JSON/schema, URL context, countTokens |
gemini-3.7-flash |
Stable | $0.75 | $3.75 | chat, multimodal input, thinking, JSON/schema, URL context |
gemini-2.5-flash-lite |
Stable | $0.10 | $0.40 | chat |
gemini-2.5-flash |
Stable | $0.30 | $2.50 | chat, search |
gemini-2.5-pro |
Stable | $1.25 | $10.00 | chat, thinking, search |
gemini-3.5-flash |
Stable | $1.50 | $9.00 | chat, multimodal input, thinking, search, tools, JSON/schema |
gemini-3.5-flash-lite |
Stable | $0.30 | $2.50 | chat, streaming, multimodal input, thinking, tools, JSON/schema |
gemini-3-flash-preview |
Preview | $0.50 | $3.00 | chat, thinking, search |
gemini-3.1-flash-lite-preview |
Preview | $0.25 | $1.50 | chat |
gemini-3.1-pro-preview |
Preview | $2.00 | $12.00 | chat, thinking, search, vision |
Gemini 3.8 Flash is GA. The exact public ID is
gemini-3.8-flash; do not append-non-thinking,-low,-medium,-high, or another effort suffix. It has a 1,048,576-token input window and a 65,536-token output limit. Selectlow,medium, orhighwiththinking_levelorreasoning_effort; the default ismedium. API429 serves the request through a managed provider chain with Google/Vertex fallback. Provider-specific model IDs are mapped internally and are not part of the public API. In Chat/Responses, tools are not supported by API429's adapter for this model. Unsupported Responses tools (includingweb_search_preview,web_search, andfile_search) return HTTP 400; they are never silently treated as text-only requests. Use native Gemini for supported function declarations and URL context.
Gemini 3.8 pricing window. The table shows the promotion through 2026-12-31. Cached input is $0.075/1M, and the $3.75 output rate includes thought tokens. On 2027-01-01 all three rates double to $1.50 input, $0.15 cached input, and $7.50 output; pricing must be updated before then.
Gemini 3.8 request controls. Custom
temperature,top_p,top_k, andn/ nativecandidateCountare not supported. Omit them rather than relying on a provider default.frequency_penaltyandpresence_penaltyremain valid.
Gemini 3.8 tool turns. The OpenAI-compatible route rejects
tools,tool_choice, assistanttool_calls, androle:"tool"messages for this model. Use the native Gemini route when function calling is required. Native requests support client-executedfunctionDeclarationsandurlContext. Search, Maps, File Search, computer use, and code execution are not part of the current API429 contract for this model.
Gemini 3.8 turn validation.
generateContentand OpenAI-compatible chat requests must end with a user turn containing non-whitespace text; assistant or model prefill is rejected. NativeFunctionResponseobjects must include both a call identifier (call_idor RESTid) andname.countTokensaccepts chat history independently and counts the supplied system instruction and function declarations as well as message contents.
Gemini 3.7 Flash remains GA. It supports text, image, video, audio and PDF input and returns text. API429 exposes exactly the canonical
gemini-3.7-flashID; do not append an effort suffix. Older Gemini 3.0/3.1 entries in this table remain preview IDs.
Gemini 3.7 pricing window. The table shows Google's current Standard promotion through 2026-12-31. Cached input is $0.075/1M. Google has announced $1.50 input, $0.15 cached input and $7.50 output starting 2027-01-01.
Gemini 3.7 request controls. Custom
temperature,top_p,top_k,n/ nativecandidateCountandthinking_budgetare not forwarded. Choose reasoning withthinking_levelor OpenAI-stylereasoning_effort:low,medium, orhigh.minimaland disabled thinking are not supported.
Gemini 3.7 tool turns. OpenAI-compatible
tools/tool_choicerequests are rejected for this model because its tool round trip requires native function-call IDs and thought signatures. Use the native Gemini route for function calling; ordinary chat, structured output and URL context remain available through the OpenAI-compatible route.
Gemini 3.5 Flash output mode.
gemini-3.5-flashaccepts text, image, audio, video and document/PDF inputs on the text chat path, but returns text. Use image models for image output, TTS models for audio output and embedding models for vector output.
Long-context pricing.
gemini-2.5-proandgemini-3.1-pro-previewswitch to a higher billing tier when the prompt exceeds 200K tokens (roughly 2× the base rate on both input and output). Prompts below 200K are billed at the rates shown above.
Model aliases (shorthand):
gemini-3.1-pro→gemini-3.1-pro-previewgemini-3-flash→gemini-3-flash-preview
Fixed reasoning-effort variants. These IDs pin the reasoning budget at request time instead of letting the model choose. They are billed at their base model's rate — the suffix changes latency and depth, not price.
| Model | Billed as | Input $/1M | Output $/1M | Notes |
|---|---|---|---|---|
gemini-3.5-flash-low |
gemini-3.5-flash |
$1.50 | $9.00 | Compatibility alias since 2026-09-04: served as gemini-3.5-flash; use thinking_level: "low" on the canonical id for the reduced budget |
gemini-3.1-pro-low |
gemini-3.1-pro-preview |
$2.00 | $12.00 | Pro quality with a reduced reasoning budget |
Higher-effort variants (-high, -medium) are not currently offered: they do
not resolve on our upstream. Request gemini-3.5-flash or
gemini-3.1-pro-preview for full reasoning, or pass thinking_level on the
base model.
Model suffixes (append to any compatible model):
-search— Enable grounded web search (e.g.gemini-3.1-pro-search)-non-thinking— Disable reasoning/thinking mode (e.g.gemini-3.1-pro-non-thinking)-image-generation— Enable inline image output on image-capable models
gemini-3.8-flash and gemini-3.7-flash are canonical-only in API429 and
reject all of these model-ID suffixes. Use thinking_level or
reasoning_effort to select a supported thinking level on either model.
Gemini Live API (advanced)
gemini-3.1-flash-live-preview is a streaming bidirectional audio model
served over Google's Live API (bidiGenerateContent). It is not reachable
via /v1/chat/completions — clients need to use the native Gemini Live
protocol. Contact your administrator if you need Live API access.
Endpoint
POST /v1/chat/completions
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
model |
string | No | gemini-2.5-flash-lite |
Model ID from the table above |
messages |
array | Yes | — | Array of message objects |
temperature |
float | No | 0.7 |
Creativity (0.0–2.0); unsupported by Gemini 3.8/3.7 |
max_tokens |
integer | No | — | Max output tokens |
stream |
boolean | No | false |
Enable streaming |
top_p |
float | No | 0.9 |
Nucleus sampling; unsupported by Gemini 3.8/3.7 |
stop |
string/array | No | — | Stop sequences |
tools |
array | No | — | Function calling tools where the selected model supports the OpenAI-compatible tool adapter; for Gemini 3.8/3.7 use native generateContent |
tool_choice |
string | No | — | auto, none, required; unavailable for Gemini 3.8/3.7 on the OpenAI-compatible route |
response_format |
object | No | — | {"type": "json_object"} or {"type": "json_schema", ...} for JSON mode |
parallel_tool_calls |
boolean | No | true |
Allow the model to emit multiple tool calls at once |
reasoning_effort |
string | No | medium |
Reasoning depth. GPT-5.6 accepts none, low, medium, high, xhigh, or max (see below). |
n |
integer | No | 1 |
Number of completions; values other than 1 are unsupported by Gemini 3.8/3.7 |
Feature coverage by model family:
| Feature | Gemini | Claude | GPT |
|---|---|---|---|
| Function calling (non-stream & stream) | ✅ except Gemini 3.8/3.7 on the OpenAI-compatible route | ✅ | ✅ |
role:"tool" follow-up (multi-turn) |
✅ except Gemini 3.8/3.7 on the OpenAI-compatible route | ✅ | ✅ |
tool_choice (auto / required / specific) |
✅ except Gemini 3.8/3.7 on the OpenAI-compatible route | ✅ | ✅ |
| Parallel tool calls | ✅ except Gemini 3.8/3.7 on the OpenAI-compatible route | ⚠️ (serialised) | ✅ |
JSON mode / JSON schema (response_format) |
✅ | ✅ | ✅ |
| Stop sequences | ✅ | ✅ | ⚠️ (dropped on some GPT models) |
| Vision (image_url / base64) | ✅ | ✅ | ✅ |
| Video input for text analysis | ✅ token-gated Gemini chat only | — | — |
| Extended reasoning | ✅ via reasoning_effort or -non-thinking suffix |
✅ auto on thinking-enabled models | ✅ via reasoning_effort or -high / -low model suffix |
Notes on reasoning:
For gemini-3.8-flash and gemini-3.7-flash, tool turns are supported only
through the native Gemini generateContent route. The OpenAI-compatible route rejects tools,
tool_choice, and role:"tool" instead of dropping Google's required
function-call IDs or thought signatures.
- The
reasoning_effortfield (low/medium/high) maps to each model's native reasoning budget. On Claude thinking-enabled modelstemperaturemust be absent — the gateway strips it automatically. - Compatible Gemini models additionally honour a
-non-thinkingsuffix on the model id to disable reasoning entirely.gemini-3.8-flashandgemini-3.7-flashare excluded: their canonical IDs accept onlylow,medium, orhighthinking levels. - GPT reasoning models accept suffixes like
-high,-lowon the model id as shorthand forreasoning_effort.
Message object:
{
"role": "system" | "user" | "assistant",
"content": "text content"
}
For multimodal requests, content may be an array of content parts:
{
"role": "user",
"content": [
{"type": "text", "text": "Describe this video in one paragraph."},
{
"type": "input_video",
"input_video": {
"format": "mp4",
"data": "BASE64_VIDEO_BYTES"
}
}
]
}
Gemini Video Input for Chat
Use this when you want a Gemini text model to analyze an existing video and return text. This is different from the async Video Generation Models section, which creates new videos.
POST /v1/chat/completions
Supported on token-enabled Gemini text models whose IDs match gemini-*, for
example gemini-2.5-flash, gemini-2.5-pro, gemini-3.5-flash and preview
Gemini text models when they are visible in GET /v1/models for your token.
Supported client formats:
- API429 OpenAI-compatible chat extension:
content[]item withtype: "video_url"andvideo_url.url. - API429 OpenAI-compatible chat extension:
content[]item withtype: "input_video"and base64input_video.data. - Gemini native:
contents[].parts[].fileData.fileUriwithmimeType: "video/mp4"or another supported video MIME type.
The client keeps the same OpenAI-compatible request envelope, base URL, and API
key flow. Video input is an API429-supported extension inside that envelope; the
balancer downloads and validates video input, then selects inline delivery or
temporary storage for the compatible route. Malformed video parts return 400
with a specific validation message.
Supported OpenAI-compatible video input parts:
| Part type | Shape | Notes |
|---|---|---|
input_video |
{"type":"input_video","input_video":{"format":"mp4","data":"<base64>"}} |
Best for SDK integrations that already have local video bytes. |
video_url |
{"type":"video_url","video_url":{"url":"https://.../clip.mp4","mime_type":"video/mp4"}} |
URL must be a direct public HTTP(S) file. Redirects are not followed. |
Supported formats: mp4, mov, avi, webm.
Current limits:
- Maximum original client video size: 150 MiB, subject to route-specific limits.
- Maximum video parts passed upstream on this OpenAI-compatible route: 1.
- Large videos may be prepared or compressed; if preparation requires multiple parts, the request is rejected instead of silently dropping video content.
- For the compatible
gemini-3.8-flashinline-video route, original videos up to 30 MB (30,000,000 bytes) are sent directly as inline media. The serialized model request, including text, tools and encoded video, must fit within 42 MB (42,000,000 bytes); otherwise the gateway returns413. These are gateway safeguards, not Google's limits. - This inline route rejects larger files instead of falling back to storage-based video delivery, which has returned upstream permission errors for this model. Other video routes retain their existing storage/preparation limits.
- Inline video processing is limited to one active request per API process by
default, through completion or stream closure. When busy, it returns
429withRetry-After: 5; use bounded retry with backoff. Existing account/rate limits apply. - Adapter tests verified approximately 30 MB / 30 seconds with audio and a 5-minute / 15.7 MB video with audio in streaming mode. These synthetic tests are not an arbitrary-duration, audio-quality or latency guarantee; some direct transport tests required more than two minutes.
- Operators can lower
ANTIGRAVITY_INLINE_VIDEO_MAX_BYTESandANTIGRAVITY_INLINE_REQUEST_MAX_BYTES, or disableANTIGRAVITY_INLINE_VIDEO_ENABLEDto restore the previous storage behavior (including its known permission issue). No model substitution is performed.
Other behavior:
stream:falseandstream:trueare both supported.- The response is text. Use
/v1/videos/generationsfor video output. - Inline delivery creates no temporary storage object. Storage-based delivery passes a signed file URL and deletes the staged object after the request finishes.
- These changes cover OpenAI-compatible
input_videoandvideo_urlinputs; they do not rewrite client-supplied Gemini nativefileDatareferences. - Full base64 video bodies are redacted from durable request logs.
Python (OpenAI SDK, local video)
import base64
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY",
)
with open("clip.mp4", "rb") as f:
video_b64 = base64.b64encode(f.read()).decode("ascii")
response = client.chat.completions.create(
model="gemini-2.5-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Describe what happens in this video."},
{
"type": "input_video",
"input_video": {
"format": "mp4",
"data": video_b64,
},
},
],
}],
max_tokens=300,
)
print(response.choices[0].message.content)
cURL (direct video URL)
curl https://gateway.api429.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-2.5-flash",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Summarize this video in 5 bullets."},
{
"type": "video_url",
"video_url": {
"url": "https://example.com/videos/clip.mp4",
"mime_type": "video/mp4"
}
}
]
}],
"max_tokens": 500
}'
cURL (streaming)
curl https://gateway.api429.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-2.5-flash",
"stream": true,
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Describe this video in one sentence."},
{
"type": "input_video",
"input_video": {
"format": "mp4",
"data": "BASE64_VIDEO_BYTES"
}
}
]
}]
}'
Examples
Python (OpenAI SDK)
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY"
)
response = client.chat.completions.create(
model="gemini-3.1-pro",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain quantum computing in 3 sentences."}
],
temperature=0.7,
max_tokens=200
)
print(response.choices[0].message.content)
Python (Streaming)
stream = client.chat.completions.create(
model="gemini-3.1-pro",
messages=[{"role": "user", "content": "Write a poem about AI"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
Python (Gemini 3.5 Flash multimodal input)
response = client.chat.completions.create(
model="gemini-3.5-flash",
messages=[{
"role": "user",
"content": [
{"type": "text", "text": "Summarize the visual details in this image."},
{"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}},
],
}],
max_tokens=500,
)
print(response.choices[0].message.content)
Python (Gemini 3.5 Flash structured output)
response = client.chat.completions.create(
model="gemini-3.5-flash",
messages=[{"role": "user", "content": "Extract title, date and people from this text."}],
response_format={"type": "json_object"},
)
print(response.choices[0].message.content)
Python (Function Calling)
response = client.chat.completions.create(
model="gemini-3-flash-preview",
messages=[{"role": "user", "content": "What's the weather in Tokyo?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get weather for a city",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string", "description": "City name"}
},
"required": ["city"]
}
}
}],
tool_choice="auto"
)
Python (Web Search)
# Append -search to enable grounded web search
response = client.chat.completions.create(
model="gemini-3.1-pro-search",
messages=[{"role": "user", "content": "What happened in tech news today?"}]
)
cURL
curl https://gateway.api429.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3-flash-preview",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 100
}'
cURL (Streaming)
curl https://gateway.api429.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-3-flash-preview",
"messages": [{"role": "user", "content": "Hello!"}],
"stream": true
}'
JavaScript / TypeScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://gateway.api429.com/v1",
apiKey: "YOUR_API_KEY",
});
const response = await client.chat.completions.create({
model: "gemini-3.1-pro",
messages: [{ role: "user", content: "Hello!" }],
max_tokens: 100,
});
console.log(response.choices[0].message.content);
Response Format
{
"id": "chatcmpl-abc123",
"object": "chat.completion",
"created": 1712345678,
"model": "gemini-3.1-pro",
"choices": [
{
"index": 0,
"message": {
"role": "assistant",
"content": "Hello! How can I help you today?"
},
"finish_reason": "stop"
}
],
"usage": {
"prompt_tokens": 12,
"completion_tokens": 8,
"total_tokens": 20
}
}
Streaming Response (SSE)
data: {"id":"chatcmpl-abc123","choices":[{"index":0,"delta":{"role":"assistant"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","choices":[{"index":0,"delta":{"content":"Hello"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","choices":[{"index":0,"delta":{"content":"!"},"finish_reason":null}]}
data: {"id":"chatcmpl-abc123","choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}
data: [DONE]
Responses API
POST /v1/responses
POST /openai/v1/responses
OpenAI Responses API — newer alternative to Chat Completions with a unified
response object, native tool handles, and built-in reasoning state.
Works with all supported model families: Gemini, GPT and Claude.
How it works per model family
| Model family | Behavior |
|---|---|
GPT (gpt-5.6, gpt-5.6-sol, gpt-5.6-terra, gpt-5.5, …) |
Native Responses API with tool, streaming and reasoning support. |
Gemini (gemini-*) |
Transparently translated to/from Chat Completions internally. |
Claude (claude-*) |
Transparently translated to/from Chat Completions internally. |
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
model |
string | Yes | Any supported model ID |
input |
string or array | Yes | User input (string for simple, array for multi-turn) |
instructions |
string | No | System instructions |
stream |
boolean | No | Enable SSE streaming (default: false) |
tools |
array | No | Function definitions for tool use |
temperature |
number | No | Sampling temperature |
max_output_tokens |
integer | No | Maximum output tokens |
top_p |
number | No | Nucleus sampling |
Input format
Simple string:
{"model": "gpt-5.3-codex", "input": "Write hello world in Python"}
Multi-turn conversation:
{
"model": "gpt-5.3-codex",
"input": [
{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "What is 2+2?"}]},
{"type": "message", "role": "assistant", "content": [{"type": "output_text", "text": "4"}]},
{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Now multiply by 3"}]}
],
"instructions": "You are a math tutor."
}
With tool calls:
{
"model": "gpt-5.3-codex",
"input": [
{"type": "message", "role": "user", "content": [{"type": "input_text", "text": "Weather in NYC?"}]},
{"type": "function_call", "name": "get_weather", "call_id": "call_1", "arguments": "{\"city\":\"NYC\"}"},
{"type": "function_call_output", "call_id": "call_1", "output": "{\"temp\":72,\"condition\":\"sunny\"}"}
],
"tools": [
{"type": "function", "name": "get_weather", "description": "Get weather", "parameters": {"type": "object", "properties": {"city": {"type": "string"}}}}
]
}
With images:
{
"model": "gemini-3.1-pro",
"input": [
{"type": "message", "role": "user", "content": [
{"type": "input_text", "text": "Describe this image"},
{"type": "input_image", "image_url": "https://example.com/photo.jpg"}
]}
]
}
Examples
Python (OpenAI SDK)
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY",
)
# Simple request
resp = client.responses.create(
model="gpt-5.3-codex",
input="Write a Python function to sort a list",
)
print(resp.output_text)
Python (Streaming)
stream = client.responses.create(
model="gpt-5.3-codex-high",
input="Explain quantum computing in simple terms",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="")
Python (With tools)
resp = client.responses.create(
model="gemini-3.1-pro",
input="What is the weather in London?",
tools=[{
"type": "function",
"name": "get_weather",
"description": "Get current weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
},
}],
)
for item in resp.output:
if item.type == "function_call":
print(f"Call: {item.name}({item.arguments})")
cURL (non-streaming)
curl https://gateway.api429.com/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.3-codex",
"input": "Hello!",
"stream": false
}'
cURL (streaming)
curl -N https://gateway.api429.com/v1/responses \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.3-codex",
"input": "Write a hello world in Rust",
"stream": true
}'
Non-streaming Response
{
"id": "resp_abc123",
"object": "response",
"created_at": 1712345678,
"status": "completed",
"model": "gpt-5.3-codex",
"output": [
{
"id": "msg_def456",
"type": "message",
"role": "assistant",
"content": [
{"type": "output_text", "text": "Here is the code..."}
]
}
],
"usage": {
"input_tokens": 12,
"output_tokens": 45,
"total_tokens": 57
}
}
Streaming Events (SSE)
When stream: true, the server sends SSE events:
event: response.created
data: {"type":"response.created","response":{"id":"resp_abc","status":"in_progress"},"sequence_number":1}
event: response.output_item.added
data: {"type":"response.output_item.added","output_index":0,"item":{"id":"msg_1","type":"message","role":"assistant"},"sequence_number":2}
event: response.output_text.delta
data: {"type":"response.output_text.delta","output_index":0,"delta":"Hello","sequence_number":3}
event: response.output_text.delta
data: {"type":"response.output_text.delta","output_index":0,"delta":" world","sequence_number":4}
event: response.completed
data: {"type":"response.completed","response":{"id":"resp_abc","status":"completed","usage":{...}},"sequence_number":10}
data: [DONE]
Event types:
| Event | Description |
|---|---|
response.created |
Stream started |
response.in_progress |
Processing |
response.output_item.added |
New message/reasoning/function_call item |
response.content_part.added |
New text content part |
response.output_text.delta |
Text chunk |
response.output_text.done |
Text content finished |
response.reasoning_summary_text.delta |
Reasoning/thinking chunk |
response.function_call_arguments.delta |
Tool call arguments chunk |
response.function_call_arguments.done |
Tool call complete |
response.output_item.done |
Item finished |
response.completed |
Stream done, includes usage |
Image Generation via Responses API
GPT models can generate images through the image_generation tool in
the Responses API. The gateway fulfils the tool call through the
dedicated GPT Image route and returns a base64 image.
resp = client.responses.create(
model="gpt-5.5",
input="Draw a cute orange cat sitting on a windowsill",
tools=[{"type": "image_generation"}],
)
for item in resp.output:
if item.type == "image_generation_call":
import base64
with open("cat.png", "wb") as f:
f.write(base64.b64decode(item.result))
GPT Image 2
Use model:"gpt-image-2" for GPT Image workloads. It is served by the
dedicated GPT Image path on both:
POST /v1/images/generationsPOST /v1/images/edits
Clients using the OpenAI SDK can point their existing Images API calls
at the API429 base URL and keep model:"gpt-image-2".
Text-to-image:
curl https://gateway.api429.com/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2",
"prompt": "A cinematic product photo of a matte black espresso machine",
"size": "1024x1024",
"quality": "low",
"response_format": "b64_json"
}'
Image edit / reference image:
curl https://gateway.api429.com/v1/images/edits \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "model=gpt-image-2" \
-F "prompt=Replace the background with a clean white studio backdrop" \
-F "image=@product.png;type=image/png" \
-F "size=1024x1024" \
-F "quality=low" \
-F "response_format=b64_json"
Supported edit upload formats: PNG, JPEG and WebP. A request may include
multiple image form fields and an optional mask image. Transparent
backgrounds are capability-gated on this Codex OAuth route: the 2026-09-09
transparent PNG canary was rejected upstream. Use opaque or auto.
OpenAI Platform preview support does not imply Codex OAuth availability.
When a supported non-GPT image model is requested with mask, API429 routes
the edit to gpt-image-2 via Codex OAuth. The response model is the effective
model and api429.requested_model records the original selection; GPT Image 2
pricing applies. JSON /v1/images/generations requests with an inline
base64/data-URI source image (or images / reference_images) and mask
use the same edit route; remote files should use multipart upload. Mask and
first source must be valid PNG images with matching dimensions, and the mask
must have an alpha channel. Invalid masks, unavailable Codex credentials, and
unsupported transparency fail before a successful-generation charge; masked
requests never fall back to Gemini.
Both generation and edit endpoints forward size, quality, background,
output_format (png, jpeg, webp), and output_compression (0–100).
The requested tool model is explicitly gpt-image-2, not an alias for Gemini
or GPT Image 2.5. xhigh/max and unverified image model IDs are rejected
rather than charged using the old auto tariff.
The Codex Images adapter uses gpt-5.6-sol as the mainline Responses model
that orchestrates the gpt-image-2 tool. These are separate roles: changing
the mainline model does not upgrade the image model or guarantee exact output
dimensions. Operators can override CODEX_IMAGE_MAINLINE_MODEL (for example,
to roll back to gpt-5.5). Client-selected mainline models on /v1/responses
are not replaced by this Images-adapter setting. Existing image tariffs and
reasoning effort (medium) are unchanged.
response_format:"url" currently returns a data URI, not an externally
hosted download link. Its MIME type is detected from the generated bytes.
Use b64_json for SDK integrations that require raw base64. The optional
api429.outputs metadata reports actual dimensions and format; any observed
difference from requested parameters appears in api429.parameter_mismatches.
Hosted Codex can return a different size; API429 does not silently resize art.
All attempts and all n images share one deadline (currently 250 seconds).
An ambiguous timeout returns 504 without automatic resubmission or Gemini
fallback. If an n>1 request has already produced images before another fails,
those images are returned and billed, with api429.warning.code set to
partial_image_batch; inspect failed_images before deciding what to retry.
The file field may be named either image or image[] (the name the
official OpenAI SDKs use when you pass a list of files); both accept several
files and may be mixed in one request.
API429's Codex image tariff is an estimate, not a pass-through of measured
OpenAI image token usage. The existing prices are unchanged: estimated text
input, a fixed high-fidelity equivalent per input image/mask, and the output
table below with size multipliers. Omitted/auto quality uses the high tariff.
The reference OpenAI token rates used to derive the tariff are:
| Component | Reference token rate |
|---|---|
| Text input | $5.00 / 1M tokens |
| Cached text input | $1.25 / 1M tokens |
| Image input | $8.00 / 1M tokens |
| Cached image input | $2.00 / 1M tokens |
| Image output | $30.00 / 1M tokens |
For convenience, OpenAI's image calculator gives these approximate output prices for common GPT Image 2 sizes:
| Quality | 1024x1024 | 1024x1536 | 1536x1024 |
|---|---|---|---|
low |
$0.006 | $0.005 | $0.005 |
medium |
$0.053 | $0.041 | $0.041 |
high |
$0.211 | $0.165 | $0.165 |
The response identifies this pricing basis as
api429.billing.basis:"api429_estimate". api429.provider_usage preserves
reported mainline Responses usage separately from image-tool usage. Missing
usage is null, not zero; mainline output tokens are not image output tokens.
Do not use these counters as a wallet receipt. Prices and per-token discounts
continue to be applied by the existing billing system. For smoke tests and
drafts, use quality:"low" and a 1024-class size.
Codex-backed image_generation calls through /v1/responses are charged once
at the same GPT Image 2 tariff. Earlier versions omitted the image charge on
that early-return path; this release closes that accounting gap. This does not
retroactively debit old requests. Failed calls do not create a successful image
charge, and reported mainline usage is not billed again as image output usage.
GPT Image 2.5
gpt-image-2.5-flare and gpt-image-2.5-sunburst generate images on
POST /v1/images/generations. The model ID selects the rendering mode:
Flare is the fast mode, Sunburst the thinking mode. There is no separate
quality switch, and a request always renders in the mode its ID names.
curl https://gateway.api429.com/v1/images/generations \
-H "Authorization: Bearer $API429_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-image-2.5-flare",
"prompt": "A paper boat on a calm lake at sunset",
"size": "1536x1024",
"response_format": "b64_json"
}'
| Parameter | Behavior |
|---|---|
prompt |
Required. |
size / aspect_ratio |
Set the shape: 1024x1024 is square, 1536x1024 is 3:2, 1024x1536 is 2:3, and any other WIDTHxHEIGHT uses the nearest supported ratio. The model chooses the pixel dimensions (a square image is 1254×1254), so they do not match size exactly. |
n |
1–8. Each image is a separate generation and is billed separately. |
image / images / reference_images |
Up to 10 reference images in total, as data URIs or URLs. |
response_format |
b64_json, or url, which returns a data URI as for the other image models. |
Not supported on these models: quality, background, output_format
other than PNG, output_compression, mask, moderation and streaming. These
fields are currently ignored rather than rejected, and the output is always
PNG. /v1/images/edits does not accept these models; to pass reference
images, send them in images on /v1/images/generations.
Each image is billed at a fixed price, whatever its size: Flare at OpenAI's medium-quality 1024×1024 rate for GPT Image 2.5 ($0.053, $0.0159 API429 standard) and Sunburst at the high-quality rate ($0.211, $0.0633). A per-client billing profile may change the discount.
Gemini Batch Images
Gemini image batches are async/non-realtime jobs for large image runs. The public submit flow follows the OpenAI-compatible Files + Batch pattern:
curl https://gateway.api429.com/v1/files \
-H "Authorization: Bearer YOUR_API_KEY" \
-F purpose="batch" \
-F file="@batchinput.jsonl"
curl https://gateway.api429.com/v1/batches \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_file_id": "file_abc123",
"endpoint": "/v1/responses",
"completion_window": "24h",
"metadata": {"job": "nightly-image-generation"}
}'
Official OpenAI-compatible Phase 1 rows target /v1/responses and request the
image_generation tool:
{"custom_id":"row-000001","method":"POST","url":"/v1/responses","body":{"model":"gemini-3.1-flash-image","input":"studio product photo of a red ceramic mug","tools":[{"type":"image_generation"}]}}
Reference images (image editing / compose) are supported via input_image
content parts. Inline the image as a data: URI (base64) or use a gs://
URI; external http(s) URLs are rejected at submit because batch workers
cannot fetch them at execution time:
{"custom_id":"row-000002","method":"POST","url":"/v1/responses","body":{"model":"gemini-3.1-flash-image","input":[{"role":"user","content":[{"type":"input_text","text":"replace the mug logo with the one from the reference"},{"type":"input_image","image_url":"data:image/png;base64,iVBORw0KGgo..."}]}],"tools":[{"type":"image_generation"}]}}
/v1/images/generations in batch JSONL is an API429 extension only; it is not
an official OpenAI Batch endpoint. If you use the API429 image edits extension,
prefer JSONL-friendly image_url inputs rather than inline base64. The official
Phase 1 endpoint remains /v1/responses.
Batch limits and behavior:
| Area | Contract |
|---|---|
| Runtime | Async/non-realtime. OpenAI-compatible completion_window is 24h; Google may queue jobs for capacity for up to 72h. |
| Output size | Google batch image output is 1K only. Do not submit unsupported 2K/4K batch image requests. |
| Input file | JSONL uploaded with purpose=batch; size limit follows GEMINI_BATCH_MAX_INPUT_FILE_BYTES (default 1GB). |
| Billing | API429 reserves balance at submit, charges completed rows only, and releases failed rows. Batch image price is 50% of the configured realtime image unit price, or the separate gemini_batch provider rows when configured. |
| Storage | Completed outputs are exposed through API429 file IDs; generated image artifacts include CDN URLs when present. |
| Admin flag | Allow with gemini_batch_images; this is separate from realtime image. |
| Deployment | Worker pods need GEMINI_BATCH_WORKER_ENABLED=true. Each service account must have a per-SA bucket mapping; there is no shared GCS bucket fallback. |
GPT Models
GPT-6 Astra
Use the exact ID gpt-6-astra. Production provider checks passed for text, image input, function calling (including async: true) and strict JSON schema. Responses API is recommended; Chat Completions supports conversations/JSON but tools require Responses.
{"model":"gpt-6-astra","input":"Explain this code briefly.","reasoning":{"effort":"high"}}
Efforts: low, medium (default), high, xhigh, max; none and minimal are unsupported. Omit temperature, top_p and logprobs. Official model limits are 1.05M context, 922K input and 128K output, subject to account and gateway limits; the full window is not load-tested.
Client-side function/custom tools execute in your application. Preserve output items and call IDs and return the corresponding tool result. This transport does not enable hosted web/file search, image generation, containers, shell, computer use, MCP, Skills, WebSocket mid-turn steering, configuration_update, background mode, explicit cache TTL, or Fast/Flex/priority tiers. Unsupported options must not be assumed to work merely because they exist in OpenAI Platform documentation. Native audio/video output is not supported by Astra. Clients must handle upstream failure/safety events without automatic continuation.
Base billing per 1M tokens (input / cache read / cache write / output): $10 / $1 / $12.50 / $50 through 272K input; $20 / $2 / $25 / $75 above 272K for the entire request. Output includes reasoning; cache buckets are not double-counted. Existing API429 discounts apply. Official model, official pricing.
All GPT-family models (including the Codex sub-family) are available through two endpoints:
POST /v1/chat/completions— standard Chat Completions formatPOST /v1/responses— OpenAI Responses API format (recommended for GPT reasoning models; required for Astra tool calling)
The gateway picks the right path automatically based on the model id.
Available Models
Prices below are API429 base rates before discounts. They are not all current official vendor list prices. The new GPT-6 Sol/Luna rates use OpenAI's published Standard token rates as of 2026-09-23; existing GPT-5.6 base rates remain unchanged pending a commercial repricing decision. Read the runtime catalog for actual standard retail.
| Model | Input $/1M | Cached input | Cache write | Output $/1M | Context | Best For |
|---|---|---|---|---|---|---|
gpt-6.1-sol |
$2.00 | $0.10 | $2.50 | $10.00 | 1.05M | Near-Astra coding, agents and professional work; Responses tools |
gpt-6.1 |
$2.00 | $0.10 | $2.50 | $10.00 | 1.05M | Alias of gpt-6.1-sol |
gpt-6-astra |
$10.00 | $1.00 | $12.50 | $50.00 | 1.05M | Reasoning and client-executed agents; Responses tools |
gpt-6-sol |
$2.00 | $0.20 | $2.50 | $10.00 | 1.05M | Complex coding and agentic workflows; Responses tools |
gpt-6-luna |
$0.10 | $0.01 | $0.125 | $0.50 | 1.05M | Focused, high-volume tasks; Responses tools |
| GPT-5.6 | ||||||
gpt-5.6 |
$5.00 | $0.50 | $6.25 | $30.00 | 1.05M | Official alias of gpt-5.6-sol |
gpt-5.6-sol |
$5.00 | $0.50 | $6.25 | $30.00 | 1.05M | Highest capability tier for complex reasoning and agents |
gpt-5.6-terra |
$2.50 | $0.25 | $3.125 | $15.00 | 1.05M | Balanced capability, latency and cost |
gpt-5.6-luna |
$1.00 | $0.10 | $1.25 | $6.00 | 1.05M | Lightweight tier for fast, low-cost tasks |
| Frontier (GPT-5.5) | ||||||
gpt-5.5 |
$5.00 | — | — | $30.00 | — | Agentic coding, computer use and research |
| Compatibility IDs (retired upstream on 2026-09-08) | ||||||
gpt-5.4 |
$2.50 | $0.25 | $3.125 | $15.00 | 1.05M | Served by gpt-5.6-terra |
gpt-5.4-mini |
$1.00 | $0.10 | $1.25 | $6.00 | 1.05M | Served by gpt-5.6-luna |
gpt-5.3-codex |
$2.50 | $0.25 | $3.125 | $15.00 | 1.05M | Served by gpt-5.6-terra |
gpt-5.2 |
$2.50 | $0.25 | $3.125 | $15.00 | 1.05M | Served by gpt-5.6-terra |
| ChatGPT consumer route | ||||||
chatgpt-gpt-6 |
$2.00 | $0.20 | — | $10.00 | 128K | GPT-6 Sol equivalent via consumer route |
chatgpt-gpt-6-mini |
$0.10 | $0.01 | — | $0.50 | 128K | GPT-6 Luna equivalent; fast, cheap |
chatgpt-gpt-6-t-mini |
$1.10 | $0.275 | — | $4.40 | 128K | GPT-6 reasoning mini (o4-mini equivalent) |
chatgpt-gpt-5-6 |
$4.00 | $0.40 | — | $20.00 | 128K | GPT-5.6 Sol equivalent via consumer route |
chatgpt-gpt-5-6-mini |
$0.20 | $0.02 | — | $1.20 | 128K | GPT-5.6 Luna equivalent; fast, cheap |
chatgpt-gpt-5-6-t-mini |
$1.10 | $0.275 | — | $4.40 | 128K | GPT-5.6 reasoning mini (o4-mini equivalent) |
chatgpt-gpt-5-3-mini |
$0.75 | $0.075 | — | $4.50 | 128K | GPT-5.4 Mini equivalent |
chatgpt-research |
$2.00 | $0.50 | — | $8.00 | — | Deep Research: autonomous multi-step research agent |
The chatgpt-* models offer an alternative access path for OpenAI models
with built-in web search. Append -search to the model ID to enable web
browsing (e.g., chatgpt-gpt-6-mini-search). Search variants bill at the
same token rate plus $10.00 per 1,000 search calls. These models support
POST /v1/chat/completions with streaming. Cache write is not available on
this route. Check GET /v1/models for your token's access.
Use the exact model IDs above for new integrations. Compatibility IDs
gpt-5.6 resolves to gpt-5.6-sol. OpenAI retired the GPT-5.4 / 5.3 /
5.2 tier for Codex on 2026-09-08, so gpt-5.4, gpt-5.3-codex, gpt-5.2
and the older compatibility IDs gpt-5 and gpt-5.1 are still accepted for
existing clients but resolve to gpt-5.6-terra and bill at the resolved
gpt-5.6-terra rate; gpt-5.4-mini and gpt-5-mini resolve to
gpt-5.6-luna and bill at the gpt-5.6-luna rate. Migrate to the GPT-5.6
IDs (or gpt-5.5) explicitly; the compatibility IDs are not advertised as
separate selectable models. Older gpt-5*-codex variants
are not public model IDs unless they appear in your token's
GET /v1/models response.
Reasoning effort presets — use reasoning_effort or append a suffix to the model ID:
| Suffix | Effect | Latency Impact | Example |
|---|---|---|---|
-max |
Maximum GPT-5.6 reasoning depth | Highest | gpt-5.6-sol-max |
-xhigh |
Very high reasoning depth | Higher | gpt-5.6-terra-xhigh |
-high |
Deeper reasoning | +30-50% | gpt-5.3-codex-high |
-medium or no suffix |
Medium reasoning | baseline | gpt-5.6 |
-low |
Lighter reasoning, faster | -10-20% | gpt-5.3-codex-low |
-none |
Skip reasoning entirely | -30-50% | gpt-5.3-codex-none |
All presets bill at the same token rate as the base model. GPT-6 Sol/Luna and GPT-5.6 accept all six values; GPT-6.1 Sol and GPT-6 Astra do not accept none. Older GPT models may support a subset. For GPT-6 Sol/Luna function calls, use /v1/responses; a native function call was verified on the Codex route for each model.
GPT-6.1 Sol requests above 272K input tokens pay $4 / $0.20 / $5 / $15 per 1M (input / cached / cache write / output) for the entire request (official GPT-6.1 Sol model).
GPT-6 Sol/Luna requests above 272K input tokens use 2x input/cache rates and 1.5x output rates for the entire request. Their long-context input / cached input / cache write / output rates per 1M tokens are respectively $4 / $0.40 / $5 / $15 for Sol and $0.20 / $0.02 / $0.25 / $0.75 for Luna. These are token rates only; hosted tools and Fast/Flex processing are not enabled on this gateway route. Official Sol model, official Luna model.
GPT-5.6 long-context and cache billing
When usage.input_tokens is greater than 272,000, the long-context rates apply to the entire request:
| Model | Input | Cached input | Cache write | Output |
|---|---|---|---|---|
gpt-5.6 / gpt-5.6-sol |
$10.00 | $1.00 | $12.50 | $45.00 |
gpt-5.6-terra |
$5.00 | $0.50 | $6.25 | $22.50 |
Automatic prompt caching is supported. Responses API reports cache usage in
usage.input_tokens_details.cached_tokens and cache_write_tokens; Chat
Completions exposes the same values under usage.prompt_tokens_details.
Explicit cache-control fields are not currently accepted on the GPT gateway
route. reasoning.mode: "pro" is also not currently available; use
reasoning.effort: "max" for the deepest supported reasoning. The current
gateway route does not enforce max_output_tokens, so clients should stop
generation locally when they require a stricter output cap.
GPT-5.6 Responses requests may use the built-in web_search tool. Each
web_search_call is billed at $10.00 per 1,000 calls ($0.01 per call), and
the search-content tokens returned to the model are billed at the selected
model's input-token rate. The response output array contains the
web_search_call item used for transparent request accounting.
For Instructor clients, Mode.MD_JSON (markdown_json_mode) is supported as
a client-side fallback: Instructor adds the schema to the prompt and parses
the markdown-fenced JSON response locally. Do not send
markdown_json_mode as an API request field. Prefer strict
response_format: {"type":"json_schema", ...} when possible.
Using Responses API (recommended for GPT-5.x)
GPT-5.x models support the OpenAI Responses API natively. Use this endpoint when you want built-in reasoning state and native tool handles.
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY",
)
# Simple request
resp = client.responses.create(
model="gpt-5.6",
input="Write a Python quicksort implementation",
)
print(resp.output_text)
# With reasoning effort
resp = client.responses.create(
model="gpt-5.6-sol",
input="Find the bug in this code and explain your reasoning",
instructions="You are a senior code reviewer.",
reasoning={"effort": "max"},
)
print(resp.output_text)
# Streaming
stream = client.responses.create(
model="gpt-5.6-terra",
input="Explain async/await in Python",
stream=True,
)
for event in stream:
if event.type == "response.output_text.delta":
print(event.delta, end="")
Using Chat Completions (also supported)
Examples
Python (OpenAI SDK)
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY"
)
# GPT-5.6 Sol with high reasoning
response = client.chat.completions.create(
model="gpt-5.6-sol",
messages=[
{"role": "system", "content": "You are a senior developer."},
{"role": "user", "content": "Review this Python function for bugs."}
],
reasoning_effort="high",
)
print(response.choices[0].message.content)
Python (Streaming)
stream = client.chat.completions.create(
model="gpt-5.6-terra",
messages=[{"role": "user", "content": "Write a hello world in Rust"}],
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
cURL
curl https://gateway.api429.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gpt-5.4-mini",
"messages": [{"role": "user", "content": "Hello!"}]
}'
Grok & Extended Catalogue
xAI Grok models and an extended set of vendor-prefixed chat IDs use the same
Bearer token and OpenAI SDK configuration as Gemini, GPT and Claude. Always
send the exact model id returned by your token's GET /v1/models response.
Grok (xAI)
grok-4.7 is the canonical current xAI flagship. It is available on
POST /v1/chat/completions and POST /v1/responses, including streaming.
It accepts text and image input and produces text, function calls, or
structured JSON output. On the Responses API, send the complete input context;
previous_response_id continuation is not enabled for this route yet.
| Model | Input $/1M | Cached $/1M | Output $/1M | Context | Best For |
|---|---|---|---|---|---|
grok-4.7 |
$2.00 | $0.50 | $6.00 | 500K | Current xAI flagship: reasoning, vision, function calling, structured output |
grok-4.6 |
$2.00 | $0.50 | $6.00 | 500K | Previous flagship, remains available |
The rates above are the official xAI Standard list rates before API429 or client-specific discounts. For requests with 200,000 or more input tokens, the whole request uses the long-context rates: $4 input, $1 cached input, and $12 output per 1M tokens. Reasoning tokens are output tokens for billing.
Use reasoning_effort with low, medium, high, or xhigh. If omitted,
xAI defaults to high. stop, presence_penalty, and frequency_penalty are
not accepted by Grok 4.7. Local function tools are supported; xAI-hosted web,
X-search, and code-execution tools are not exposed by API429 yet because they
have separate per-call pricing.
Verified October 2, 2026. Availability is subject to your key permissions; check GET /v1/models.
Additional Grok catalogue IDs
The following vendor-prefixed compatibility IDs are separate catalogue
entries. Their x-ai/ prefix is part of the model id.
| Model | Input $/1M | Output $/1M | Best For |
|---|---|---|---|
x-ai/grok-4 |
$1.25 | $2.50 | Grok 4 compatibility tier — general chat and reasoning |
x-ai/grok-4-reasoning |
$1.25 | $2.50 | Grok 4 with extended reasoning / thinking |
x-ai/grok-3 |
$1.25 | $2.50 | Fast, cost-effective general-purpose Grok |
x-ai/grok-3-reasoning |
$1.25 | $2.50 | Grok 3 with extended reasoning |
Extended vendor-prefixed chat IDs
These IDs offer additional GPT and Gemini tiers alongside the native catalogue above. They are billed per the table below and accept the same chat parameters.
| Model | Input $/1M | Output $/1M | Notes |
|---|---|---|---|
openai/gpt-5 |
$1.00 | $8.00 | GPT-5 standard |
openai/gpt-5-instant |
$1.25 | $10.00 | Low-latency GPT-5 variant |
openai/gpt-5-thinking |
$1.25 | $10.00 | GPT-5 with extended reasoning |
google/gemini-3-pro |
$2.00 | $12.00 | Gemini 3 Pro |
google/gemini-2.5-pro |
$1.25 | $10.00 | Gemini 2.5 Pro |
google/gemini-2.5-flash |
$0.30 | $2.50 | Fast, low-cost Gemini |
Availability of every model above is gated by your token. Always check your token's
GET /v1/modelsresponse for the authoritative selectable list and current pricing.
Example
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY",
)
resp = client.chat.completions.create(
model="grok-4.6",
messages=[{"role": "user", "content": "Explain quantum entanglement in two sentences."}],
reasoning_effort="high",
)
print(resp.choices[0].message.content)
Extended text models
Additional chat models from Moonshot, Alibaba, Zhipu, DeepSeek, Xiaomi,
MiniMax, Tencent and Cursor, plus newer Claude, Gemini and Grok ids. They use
the same Bearer token and OpenAI SDK configuration on
POST /v1/chat/completions (streaming included) and accept text input
only. Send the exact model id from the first column.
Prices are the vendors' official list rates per 1 million tokens before your client-level discount. Cached input is charged at the cached rate where the vendor publishes one, otherwise at the input rate.
| Model ID | Input $/1M | Cached $/1M | Output $/1M | Notes |
|---|---|---|---|---|
claude-opus-5-5 |
$4.00 | $0.20 | $20.00 | Anthropic Claude Opus 5.5 |
claude-sonnet-5-5 |
$2.00 | $0.10 | $10.00 | Anthropic Claude Sonnet 5.5 |
claude-haiku-5-5 |
$0.10 | $0.01 | $0.50 | Anthropic Claude Haiku 5.5; over 100K input: $0.50 / $0.05 / $2.50 for the whole request |
claude-fable-5.1 |
$10.00 | $0.25 | $50.00 | Anthropic Claude Fable 5.1 |
gemini-3.6-flash |
$0.75 | $0.075 | $3.75 | Introductory rate until 2026-12-31 |
grok-4.5 |
$2.00 | $0.30 | $6.00 | ≥200K input: $4 / $0.60 / $12 for the whole request |
kimi-k3 |
$3.00 | $0.30 | $15.00 | Moonshot flagship |
kimi-k2.7-code |
$0.95 | $0.19 | $4.00 | Moonshot coding model |
qwen-3.8-max |
$2.00 | — | $6.00 | Alibaba Qwen flagship |
qwen-3.8-flash |
$0.15 | — | $0.47 | Fast, low-cost Qwen |
glm-5.3 |
$1.40 | $0.26 | $4.40 | Zhipu GLM flagship |
glm-5.3-flash |
$0.15 | $0.03 | $0.50 | Fast, low-cost GLM |
glm-5.2 |
$1.40 | $0.26 | $4.40 | Previous GLM flagship |
glm-5-turbo |
$1.20 | $0.24 | $4.00 | GLM speed-optimised |
deepseek-v4-pro |
$1.32 | $0.044 | $3.96 | DeepSeek flagship |
deepseek-v4.1-flash |
$0.30 | $0.006 | $1.20 | Fast, low-cost DeepSeek |
mimo-v2.5-pro |
$0.435 | $0.0036 | $0.87 | Xiaomi MiMo; retires 2026-10-21 |
mimo-v2.5 |
$0.14 | $0.0028 | $0.28 | Xiaomi MiMo; retires 2026-10-21 |
minimax-m3 |
$0.30 | $0.06 | $1.20 | >512K input: $0.60 / $2.40 |
hy4-preview |
$0.834 | $0.042 | $2.501 | Tencent Hunyuan preview |
composer-2.5-fast |
$3.00 | $0.50 | $15.00 | Cursor coding model |
Claude Models
Claude models are available through two public API surfaces:
| Surface | Endpoint | Auth | Use when |
|---|---|---|---|
| OpenAI-compatible | POST /v1/chat/completions |
Authorization: Bearer <token> |
Your client already uses OpenAI Chat Completions or Responses-style tooling. |
| Anthropic-compatible | POST /v1/messages |
x-api-key: <token> |
Your client already uses Anthropic Messages API / Anthropic SDK shape and you want to change only the base URL and token. |
Use the canonical claude-* model IDs below for public integrations. API429
may route requests internally for availability, but clients should not depend
on internal route names or provider-specific aliases.
All Claude models listed here support chat, streaming, tool calling, web search and vision/image input unless otherwise noted. Vision means text + image input with text output; these models do not generate images.
Available Models
Model IDs use dash separators. Dotted aliases are accepted for compatibility,
but new integrations should send the canonical model ID from the first column.
For 1M context, use the canonical -1m model IDs shown below, or Anthropic's
bracket-style aliases such as claude-opus-4.8[1m].
The prices below are API429 list prices per 1 million tokens before your
client-level discount.
| Model ID | Accepted Alias(es) | Input $/1M | Output $/1M | Context | Best For |
|---|---|---|---|---|---|
claude-fable-5 |
— | $10.00 | $50.00 | 1M | Most capable Claude model for the hardest reasoning and long-horizon work |
claude-opus-5 |
— | $5.00 | $25.00 | 1M | Newest Opus for demanding reasoning, coding and analysis |
claude-sonnet-5 |
claude-sonnet-5.0 |
$2.00 | $10.00 | 1M | Newest Sonnet for coding, agents and professional work |
claude-opus-4-8 |
claude-opus-4.8 |
$5.00 | $25.00 | 1M | Highest quality reasoning, coding, analysis |
claude-opus-4-8-1m |
claude-opus-4.8-1m, claude-opus-4.8[1m] |
$5.00 | $25.00 | 1M | Opus with explicit 1M-context ID |
claude-opus-4-7 |
claude-opus-4.7 |
$5.00 | $25.00 | 1M | Highest quality reasoning, coding, analysis |
claude-opus-4-7-1m |
claude-opus-4.7-1m, claude-opus-4.7[1m] |
$5.00 | $25.00 | 1M | Opus with explicit 1M-context ID |
claude-opus-4-6 |
claude-opus-4.6 |
$5.00 | $25.00 | 1M | Complex analysis and long-form work |
claude-opus-4-6-1m |
claude-opus-4.6-1m, claude-opus-4.6[1m] |
$5.00 | $25.00 | 1M | Opus 4.6 with explicit 1M-context ID |
claude-sonnet-4-6 |
claude-sonnet-4.6 |
$3.00 | $15.00 | 1M | Balanced intelligence, speed and cost |
claude-sonnet-4-5 |
claude-sonnet-4.5 |
$3.00 | $15.00 | 200k | General Claude chat and writing workloads |
claude-haiku-4-5-20251001 |
claude-haiku-4-5, claude-haiku-4.5 |
$1.00 | $5.00 | 200k | Lowest latency and lowest cost Claude model |
You can also call GET /v1/models with your API key to see the exact Claude
models enabled for your token.
Anthropic-compatible Messages API
Use this endpoint when your code already targets Anthropic's Messages API. The request body and response body follow the Anthropic Messages shape; API429 selects and rotates upstream Claude credentials server-side.
POST https://gateway.api429.com/v1/messages
Required headers:
x-api-key: YOUR_API_KEY
content-type: application/json
anthropic-version: 2023-06-01
anthropic-version is accepted for SDK compatibility and may be omitted; when
it is omitted API429 forwards 2023-06-01 upstream.
cURL
curl -X POST https://gateway.api429.com/v1/messages -H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" -H "anthropic-version: 2023-06-01" --data @payload.json
payload.json:
{
"model": "claude-sonnet-5",
"max_tokens": 512,
"system": "You are a concise technical assistant.",
"messages": [
{"role": "user", "content": "Explain Mutex vs RwLock in Rust."}
]
}
Response
{
"id": "msg_...",
"type": "message",
"role": "assistant",
"model": "claude-sonnet-5",
"content": [
{"type": "text", "text": "..."}
],
"stop_reason": "end_turn",
"usage": {
"input_tokens": 23,
"output_tokens": 87
}
}
Native streaming
Set "stream": true on /v1/messages to receive Anthropic-style SSE events:
curl -N -X POST https://gateway.api429.com/v1/messages -H "x-api-key: YOUR_API_KEY" -H "Content-Type: application/json" -H "anthropic-version: 2023-06-01" --data @payload.json
payload.json:
{
"model": "claude-sonnet-5",
"max_tokens": 512,
"stream": true,
"messages": [
{"role": "user", "content": "Write a haiku about Rust."}
]
}
Events arrive in Anthropic order:
message_start
content_block_start
content_block_delta
content_block_stop
message_delta
message_stop
Anthropic may also send ping events between content events. Usage is split
across the stream: message_start includes input usage, and message_delta
includes final output usage.
Native request fields
| Field | Type | Required | Notes |
|---|---|---|---|
model |
string | Yes | Use a Claude model ID from GET /v1/models. |
messages |
array | Yes | Anthropic message list: role is user or assistant; content may be a string or content blocks. |
max_tokens |
integer | Yes | Maximum output tokens. |
system |
string or array | No | System prompt, including content blocks with cache_control where supported upstream. |
stream |
boolean | No | Returns Anthropic SSE events when true. |
temperature |
number | No | Sampling temperature. |
tools |
array | No | Anthropic tool-use format, including server tools. |
stop_sequences |
array | No | Anthropic stop sequences. |
Native usage and billing
Native responses expose Anthropic-style usage:
{
"usage": {
"input_tokens": 123,
"cache_creation_input_tokens": 0,
"cache_read_input_tokens": 0,
"output_tokens": 45
}
}
These numbers are also recorded in API429 usage analytics and billing. For Claude requests, billable input tokens are:
input_tokens + cache_creation_input_tokens + cache_read_input_tokens
Billable output tokens are output_tokens. On the OpenAI-compatible surface,
the same values are exposed as prompt_tokens, completion_tokens, and, when
available, prompt_tokens_details.
If upstream returns prompt-cache fields such as cache_creation_input_tokens
or cache_read_input_tokens, API429 passes them through in native usage and
includes them in analytics. When those fields are absent, clients should bill
and display the reported input_tokens / output_tokens values and use the
client usage endpoints for the final charged amount.
Web search for Claude models
Claude models on this gateway accept Anthropic's stable
web_search_20250305 server tool. On the Anthropic-compatible /v1/messages
surface, this is a native Anthropic tool-use contract: the model may return
stop_reason: "tool_use" with a content block of type tool_use, and the
client continues the tool loop in the next request.
Declare it as:
{
"model": "claude-sonnet-5",
"messages": [{"role": "user", "content": "Latest Anthropic news?"}],
"tools": [{"type": "web_search_20250305", "name": "web_search", "max_uses": 3}]
}
For convenience the balancer also accepts two non-canonical input shapes and rewrites them automatically:
| Sent by client | Forwarded to Anthropic | Notes |
|---|---|---|
{"type": "web_search_preview"} (OpenAI Responses API style) |
web_search_20250305 |
OpenAI-only fields (search_context_size, user_location, include_domains, exclude_domains, search_content_types) are stripped — Anthropic 400s on unknown keys. |
{"type": "web_search_20260209"} (newer Anthropic dated variant) |
web_search_20250305 |
name and max_uses are preserved. The newer variant is not yet broadly available, so the rewrite avoids a "tools unavailable" response. |
The gateway forwards this server-tool declaration to the Claude route. On the
OpenAI-compatible surface, the final shape is still a Chat Completions
response and structured citation metadata is not exposed. On the
Anthropic-compatible Messages surface, inspect returned tool_use content
blocks and continue the native tool loop when the model stops with
stop_reason: "tool_use".
Behaviour change (2026-04-25): Before this release, requests with
web_search_previewwere silently dropped at the balancer (model answered "I have no real-time access"). They now activate a real web search — the response text changes accordingly. Clients that passedweb_search_preview"defensively" should remove it if they don't actually want search.
Examples
Python (OpenAI SDK)
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY",
)
response = client.chat.completions.create(
model="claude-sonnet-5",
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Explain the difference between TCP and UDP."},
],
)
print(response.choices[0].message.content)
cURL (vision / image input)
curl https://gateway.api429.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-opus-4-8",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image in one sentence."},
{"type": "image_url", "image_url": {"url": "data:image/png;base64,BASE64_IMAGE"}}
]
}],
"max_tokens": 256
}'
Python (Streaming, frontier model)
stream = client.chat.completions.create(
model="claude-opus-4-7",
messages=[{"role": "user", "content": "Write a Python async web scraper"}],
stream=True,
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
cURL (fastest / cheapest — Haiku snapshot)
curl https://gateway.api429.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "claude-haiku-4-5-20251001",
"messages": [{"role": "user", "content": "Hello!"}],
"max_tokens": 256
}'
Optional headers for batch / long-running Claude workflows
Two optional headers are useful for long-running Claude integrations. Clients that do not send them get normal synchronous behavior.
| Header | Endpoints | Effect |
|---|---|---|
X-Session-Key |
POST /v1/chat/completions, POST /v1/balancer/jobs/chat-completions |
Stable string per logical conversation. Helps API429 reuse server-side conversation/cache state across multi-turn batches. Tenant-namespaced server-side. Format: 1–256 chars [a-zA-Z0-9._/+-]. Full contract: client-facing X-Session-Key guide. |
X-Async-Jobs-Optin: true |
POST /v1/chat/completions |
Allows API429 to move a non-streaming request into the durable jobs queue during overload. Normal success still returns 200 inline. If queued, the response is 202 with Location: /v1/balancer/jobs/{id}/result; poll that URL for the final result. Ignored for stream=true because jobs are non-streaming. |
Recommended combo for batch screenwriter clients:
curl https://gateway.api429.com/v1/chat/completions \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "X-Session-Key: scenario/iceberg/run-001/scene-3" \
-H "X-Async-Jobs-Optin: true" \
-d '{
"model": "claude-sonnet-4-5",
"messages": [{"role": "user", "content": "Draft scene 3 of the iceberg scenario."}]
}'
Streaming note: plain Claude stream:true is token-progressive
SSE. Jobs API responses are never streaming; use polling for durability.
Image Generation Models
Nano Banana 2 native image capacity
For gemini-3.1-flash-image and its -preview alias, non-streaming
generateContent requests with one user turn and responseModalities including
IMAGE can use additional image capacity before the native Google route.
The response remains Gemini JSON (candidates[].content.parts[].inlineData).
This applies to one image per request, supported dimensions, and inline PNG,
JPEG or WebP references with an explicit output aspect ratio (up to 10
references, at most 5 MiB each). Multi-turn history, thought signatures,
tools, system/safety/sampling controls, file references, text-only requests,
streaming and unsupported image parameters retain the native Google path.
For the image-capacity path, returned token counts are estimates; image
charges use the delivered image count and requested resolution. After an
uncertain image submission or accepted task, API429 does not automatically
create a second paid image at another provider.
Image capacity is shared across API429 regions. Each connected image credential admits at most 25 concurrent generation operations in total. Requests prefer a free credential with fewer active operations; a credential that reaches its hourly image quota is skipped until minute 00 of the next hour. Other eligible image credentials are tried before the native Google backup. If all credentials are busy, the wait is bounded; unavailable shared coordination never increases the limit through a local fallback. An uncertain task can retain a reservation for up to 15 minutes, avoiding an immediate duplicate paid operation.
Available Models
| Model | Status | Cost per Image | Notes |
|---|---|---|---|
gpt-image-2 |
Stable | $0.005-$0.211 output image estimate + input tokens | GPT Image; exact price depends on text/image input, quality, and size |
gpt-image-2.5-flare |
Stable | $0.053 | GPT Image 2.5, fast mode. Fixed price per image; see "GPT Image 2.5". |
gpt-image-2.5-sunburst |
Stable | $0.211 | GPT Image 2.5, thinking mode. Fixed price per image; see "GPT Image 2.5". |
gemini-2.5-flash-image (Nano Banana) |
Stable | $0.039 | Legacy Google image model. |
gemini-3.1-flash-lite-image (Nano Banana 2 Lite) |
Stable | $0.0336 | Fast 1K image generation. |
imagen-4 |
Stable | $0.040 | Imagen 4 |
gpt-image-1 (Sora Images) |
Stable | $0.040 | Compatibility name: sora-images; up to 4 per call via n. |
grok-imagine-image |
Stable | $0.020 (1K/2K) | Native xAI Images API through the Grok OAuth pool; text-to-image |
grok-imagine-image-quality |
Stable | $0.050 (1K), $0.070 (2K) | Native xAI quality image model; compatibility alias: grok-image. |
gemini-3.1-flash-image (Nano Banana 2) |
Stable | $0.067 | Higher-resolution output (up to 4K), balanced speed/quality. |
gemini-3-pro-image (Nano Banana Pro) |
Stable | $0.134 | High visual fidelity for edits and 4K. |
api429-image |
Stable | $0.040 | api429 image: image generation and editing. |
FLUX.2-pro |
Stable | $0.030+ | Azure AI Foundry / Black Forest Labs FLUX.2 pro. Billed by generated megapixels and reference-image megapixels (1 MP = 1024×1024). |
dalle-3 |
Stable | $0.040 | DALL·E 3 (variants: dalle-3-openai, dalle-3-bing). Bing channel accepts 4:7 / 7:4 aspect ratios. |
midjourney-7.0-fast |
Stable | $0.021 | Midjourney v7 fast tier; 4-image batch, billed per job. Also: midjourney-7.0-relax ($0.011); midjourney-6.1-*, midjourney-8.1-* |
flux-1 |
Stable | $0.040 | Flux.1 generations; width/height 600–1600 px, copies 1–2 |
qwen-image |
Stable | $0.040 | Qwen text-to-image; supports width/height, style, n=1..2 |
qwen-image-edit |
Stable | $0.040 | Qwen edit with reference image. Subtypes (same price): qwen-image-remove-bg, -remove-watermark, -restore, -colorize-1, -colorize-2, -contour, -depth, -extract-clothing, -make-old, -make-young, -stylize, -3d |
acc-upper / acc-lower / acc-full |
Stable | $0.060 | AI Change Clothes (upper / lower / full body). Needs person photo in image + clothing reference in images[0] |
Use the technical IDs above in new integrations. Existing nano-banana,
nano-banana-2, nano-banana-2-lite, and nano-banana-pro requests remain
accepted for compatibility; they are not separate models. Retired -preview
IDs and legacy spelling aliases also remain compatibility inputs where supported.
The public website hides duplicate aliases only when their canonical model is
published. Check the runtime catalog for current availability. api429-image (api429 image) supports image generation and editing.
Gemini image resolution pricing:
| Canonical model | 1K official / API429 standard* | 2K official / API429 standard* | 4K official / API429 standard* |
|---|---|---|---|
gemini-3.1-flash-image (Nano Banana 2) |
$0.067 / $0.0201 | $0.101 / $0.0303 | $0.151 / $0.0453 |
gemini-3-pro-image (Nano Banana Pro) |
$0.134 / $0.0402 | $0.134 / $0.0402 | $0.240 / $0.0720 |
* API429 standard amounts apply the standard 70% client discount. A per-client billing profile may override that discount.
All image models are exposed on the same /v1/images/generations
endpoint. No extra credentials are needed on the client side. The
gateway picks the right backend for the requested model. For
model:"gpt-image-2", the request uses the dedicated GPT Image route,
not the Gemini image model family.
Resolution tiers. The rates in the main model table are 1K rates unless a row says otherwise. Gemini Flash is $0.067 / $0.101 / $0.151 at 1K / 2K / 4K. Gemini Pro is $0.134 / $0.134 / $0.240.
imagen-4has Fast / Standard / Ultra tiers ($0.02 / $0.04 / $0.06).FLUX.2-prouses Azure FLUX megapixel billing: first generated MP is $0.030, each additional generated MP is $0.015, and each reference-image MP is $0.015. xAIgrok-imagine-imagecosts $0.020 at either 1K or 2K;grok-imagine-image-qualitycosts $0.050 at 1K and $0.070 at 2K. Pickaspect_ratio/sizeaccordingly.
Grok OAuth image limits. API429 does not impose a made-up local RPM or weekly quota. Each OAuth account is rotated according to the live
x-ratelimit-*,Retry-After, and 429 reset data returned by xAI. A model-scoped limit only pauses that model on that account; an explicitly account/subscription-scoped limit pauses image use for the whole account. If xAI omits a reset time, API429 performs a synchronized probe instead of assuming a 24-hour cooldown.
Example:
curl https://gateway.api429.com/v1/images/generations \
-H "Authorization: Bearer $API429_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "grok-imagine-image-quality",
"prompt": "Editorial product photo on a clean studio background",
"resolution": "2K",
"aspect_ratio": "16:9",
"response_format": "url"
}'
The native xAI OAuth route currently supports text-to-image at 1K or 2K.
It rejects 4K, reference images, masks, negative_prompt, style, and
seed explicitly instead of silently dropping them. Use a model documented
for image editing when reference-image fidelity is required.
Output format note: the gateway preserves the MIME type of the bytes the
provider actually returned; it does not label every image .png. With
response_format:"url", every item has a url: normally a hosted URL, or a
data:<actual-mime>;base64,… URL if the uploader is unavailable or fails.
With response_format:"b64_json", every item has raw standard base64 in
b64_json. PNG, JPEG, and WebP are all possible when supported upstream.
Endpoint
POST /v1/images/generations
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
model |
string | No | nano-banana |
Model ID from table above (the default when omitted) |
prompt |
string | Yes | — | Text description of the image |
n |
integer | No | 1 |
Number of images (1–8). Some models always return 1 regardless. |
size |
string | No | 1024x1024 |
Image dimensions, used for the shape: 1536x1024 → 3:2, 1024x1536 → 2:3, 1792x1024 → 16:9, 1024x1792 → 9:16; any other WIDTHxHEIGHT uses the nearest supported aspect ratio. aspect_ratio overrides it. |
aspect_ratio |
string | No | — | 1:1, 16:9, 9:16, 4:3, 3:4 |
resolution |
string | No | 1K |
Output tier: 1K (default), 2K, 4K. Aliases: standard, hd, ultra. Also accepts image_size / imageSize. See 4K notes below. |
quality |
string | No | — | OpenAI-style tier: standard → 1K, hd → 2K, ultra → 4K. |
image_config |
object | No | — | Nested Google image configuration. Accepts snake_case or camelCase forms of image_size, aspect_ratio, negative_prompt, output_mime_type, and person_generation. Also accepts imageConfig. Top-level wins when both forms are supplied; a non-object returns 422. Supplying outputMimeType or personGeneration makes the request Vertex-only. |
response_format |
string | No | url |
url or b64_json |
outputMimeType / output_mime_type |
string | No | Provider default | Requested Google output MIME: image/png, image/jpeg, or image/webp. Forwarded through a Vertex-backed credential; the response still reports the MIME actually returned. |
personGeneration / person_generation |
string | No | Provider default | Google person-generation policy: ALLOW_ALL, ALLOW_ADULT, ALLOW_NONE, or equivalent Imagen spelling DONT_ALLOW. The gateway translates the deny value for the selected Google model family and forwards it through a Vertex-backed credential. |
background |
string | No | — | For the Codex gpt-image-2 route, use opaque or auto. Transparency requires separately verified provider support. |
output_format |
string | No | png |
For gpt-image-2: png, jpeg, or webp when honored upstream. |
output_compression |
integer | No | — | For jpeg / webp, 0-100 when honored upstream. |
moderation |
string | No | auto |
For GPT Image compatibility: auto or low. |
image |
string | No | — | Reference image (base64, URL, or data URI) |
reference_images |
array | No | — | Multiple reference images — see format below |
negative_prompt |
string | No | — | What to avoid |
Vertex-only image controls. When
outputMimeTypeorpersonGenerationis present at the top level or insideimageConfig, the gateway automatically selects a usable Vertex-backed Google credential. These fields are not sent to the Gemini Developer API. If no Vertex-backed credential is available, the request fails clearly with HTTP503instead of silently dropping the fields or retrying through an incompatible API. Requests for non-Google image models fail with HTTP400because their provider routes cannot honor these Google-specific controls.
Requesting 2K / 4K output
All three of these are equivalent:
{"model": "gemini-3-pro-image", "prompt": "...", "resolution": "4K"}
{"model": "gemini-3-pro-image", "prompt": "...", "image_size": "4K"}
{
"model": "gemini-3-pro-image",
"prompt": "...",
"image_config": {"image_size": "4K", "aspect_ratio": "16:9"}
}
Using the OpenAI SDK:
client.images.generate(
model="gemini-3-pro-image",
prompt="...",
extra_body={"image_size": "4K"},
)
Model support for 2K / 4K:
| Model | 1K | 2K | 4K | Source |
|---|---|---|---|---|
gemini-3-pro-image (Nano Banana Pro) |
✅ | ✅ | ✅ | ai.google.dev |
gemini-3.1-flash-lite-image (Nano Banana 2 Lite) |
✅ | — | — | ai.google.dev |
gemini-3.1-flash-image (Nano Banana 2) |
✅ | ✅ | ✅ | ai.google.dev — gemini-3.1 flash-image |
gemini-2.5-flash-image (Nano Banana) |
✅ | — | — | legacy; Google lists shutdown no earlier than 2026-10-02 |
imagen-4 |
✅ | ✅ | — | Imagen 4 / Imagen 4 Ultra cap at 2048×2048 |
FLUX.2-pro |
yes | yes | yes | Azure FLUX.2 pro; billed by rounded-up generated/reference MP |
grok-imagine-image |
yes | yes | — | Native xAI Images API; text-to-image |
grok-imagine-image-quality / grok-image |
yes | yes | — | Native xAI quality model; grok-image is the compatibility alias |
- The balancer forwards the requested tier to the selected image model. If a model does not support the requested tier, the upstream may return HTTP 400. We do not silently downgrade between tiers the model understands.
- Non-Google image models may use different native size primitives; see the caveats below.
Provider caveats for non-Google backends:
FLUX.2-proaccepts either explicit pixel-shapedsize(for example"1024x1024","2048x2048") orresolution/image_size/qualitytiers.quality:"standard"maps to 1K,quality:"hd"maps to 2K, andquality:"ultra"maps to 4K.aspect_ratiois used when deriving dimensions from a tier.- Other non-Google image providers may use different native size primitives.
If your workflow strictly needs 4K, pin model to one of the 4K-capable entries above (gemini-3-pro-image, gemini-3.1-flash-image).
Azure FLUX.2-pro references and billing
FLUX.2-pro supports up to 8 reference images on the JSON image-generation endpoint. References may be supplied through reference_images, or through OpenAI-compatible image / images fields. Extra references above 8 are ignored after the first 8.
Billing is based on rounded-up megapixels:
- generated output: first MP $0.030, each additional MP $0.015;
- each reference image: $0.015 per rounded-up MP;
- 1 MP is treated as 1024x1024 pixels.
Example with two references:
{
"model": "FLUX.2-pro",
"prompt": "Create a premium studio product image using the references",
"quality": "hd",
"aspect_ratio": "16:9",
"reference_images": [
{"image_url": "https://cdn.example.com/ref-1.png"},
{"image_base64": "data:image/jpeg;base64,..."}
],
"n": 1,
"response_format": "url"
}
Image editing (reference images + edit prompt)
For edit/reference-image workflows, prefer gemini-3-pro-image when visual fidelity to the input image is
critical. Flash image models remain suitable for fresh generations and
lower-cost drafts, but Pro is the safer choice for production edits.
If you want Pro explicitly from the caller side, pin
model: "gemini-3-pro-image". The older names remain input aliases only.
reference_images format
Accepts either structured objects or bare URL strings in the same array:
{
"reference_images": [
"https://cdn.example.com/ref_1.jpg",
{
"name": "ref_2",
"image_base64": "<base64-without-data-uri-prefix>",
"mime_type": "image/png"
},
{
"image_url": "https://cdn.example.com/ref_3.webp"
}
]
}
- A bare string is treated as
{"image_url": "<string>"}— the server fetches the URL and base64-encodes it at provider boundary. - Object form requires at least one of
image_base64/image_url.nameandmime_typeare optional. - Base64 inputs may use standard base64 or URL-safe base64, with or without padding. API429 validates the bytes and canonicalizes forwarded/output base64 to padded standard base64 (
+,/,=), so a gateway response can be sent back unchanged in a later edit request. image_urlfetch timeout is controlled byIMAGE_INPUT_FETCH_TIMEOUT_SECONDS(default 30s). A failed fetch returns HTTP 400 with the underlying error message.
Examples
Python (OpenAI SDK)
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY"
)
response = client.images.generate(
model="gemini-2.5-flash-image",
prompt="A futuristic city at sunset, cyberpunk style",
n=1,
size="1024x1024"
)
print(response.data[0].url)
Python (FLUX)
response = client.images.generate(
model="FLUX.2-pro",
prompt="Product photography of a ceramic teapot, studio light",
n=1,
quality="hd",
extra_body={
"aspect_ratio": "16:9",
"reference_images": [
{"image_url": "https://cdn.example.com/ref-1.png"},
],
},
)
print(response.data[0].url)
Python (Base64 Response)
response = client.images.generate(
model="gemini-3-pro-image",
prompt="A cute robot reading a book",
n=1,
size="1024x1024",
response_format="b64_json"
)
import base64
image_data = base64.b64decode(response.data[0].b64_json)
with open("robot.png", "wb") as f:
f.write(image_data)
cURL
curl https://gateway.api429.com/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-2.5-flash-image",
"prompt": "A mountain landscape at sunrise",
"n": 1,
"size": "1024x1024"
}'
Response Format
{
"created": 1712345678,
"data": [
{
"url": "https://storage.googleapis.com/generated/...",
"revised_prompt": "A futuristic city at sunset, cyberpunk style"
}
]
}
With response_format: "b64_json":
{
"created": 1712345678,
"data": [
{
"b64_json": "/9j/4AAQSkZJRgABAQ...",
"revised_prompt": "A futuristic city at sunset"
}
]
}
With response_format: "url", the response always uses the url field. If
object storage upload is unavailable or fails, the value is a valid data URI
using the actual returned MIME type; the gateway does not silently switch the
field to b64_json.
nobalancerapi models
A separate catalogue enabled per account rather than served by default. If you
do not see these models in GET /v1/models, your token is not entitled to
them — ask us to enable it.
Pricing: on request. These models are billed from the actual cost of each
job rather than a flat per-image rate, so the price depends on the model,
size, speed tier and — for Midjourney — how many images a job returns. We
quote per account; your effective charge always appears in
/api/client/usage/daily and in the request log.
Image models on Chat Completions
Any Gemini image model (gemini-2.5-flash-image, gemini-3.1-flash-image,
gemini-3-pro-image, …) can be called through POST /v1/chat/completions.
The text of the messages becomes the prompt; image_url parts in the messages
are used as the edit source. The reply carries the generated picture twice for
compatibility:
{
"object": "chat.completion",
"model": "gemini-2.5-flash-image",
"choices": [{
"index": 0,
"finish_reason": "stop",
"message": {
"role": "assistant",
"content": "",
"images": [{"type": "image_url", "image_url": {"url": "data:image/png;base64,..."}}]
}
}],
"usage": {
"prompt_tokens": 14,
"completion_tokens": 1290,
"total_tokens": 1304,
"completion_tokens_details": {"reasoning_tokens": 0, "image_tokens": 1290},
"image_count": 1
}
}
message.imagesis the field to read programmatically;contentkeeps the markdown rendering for clients that only display text.usagemirrors Google's accounting the same way the Gemini-native endpoint does: the prompt's text tokens plus 1290 per reference image inprompt_tokens, and 1290 per generated image incompletion_tokens/completion_tokens_details.image_tokens.image_countis the number of generated pictures — the unit the request is billed by.- Billing is per generated image at the model's catalog
imagerate; the token figures are for reconciliation and are not charged separately. - With
stream: truethe response is one SSE event carryingdelta.contentanddelta.images, a finish chunk anddata: [DONE]. Passstream_options: {"include_usage": true}to receive a usage chunk (emptychoices) before[DONE]. - If the model returns no image the request fails with
502and is not billed.
Image generation
| Model | Notes |
|---|---|
midjourney |
Midjourney, current default version (8.1, standard queue). Returns 4 images per job |
midjourney-6.1-relax / midjourney-6.1-fast |
Version 6.1 |
midjourney-7.0-relax / midjourney-7.0-fast |
Version 7.0 |
midjourney-8.1-relax / midjourney-8.1-fast |
Version 8.1 |
flux-1 |
FLUX.1; optional checkpoint_id, sampler_id, steps, and style controls |
qwen-image |
Qwen Images, text-to-image |
sora-images |
Sora Images |
dalle-3 |
DALL·E 3 |
Midjourney flags (--ar, --s, --cref, --sref, --ow, …) are written
inside prompt and passed through unchanged, so references and blends work as
they do upstream. The request-level size / aspect_ratio fields are ignored
for these models — use --ar in the prompt instead.
A generation job always produces 4 images, you are billed for the job as a
whole, and all four are returned by default. Pass n explicitly only if you
want fewer back — it does not reduce the price.
FLUX.1 controls
Use either flux-1 or flux.1 with POST /v1/images/generations. When
omitted, the defaults are checkpoint_id=1, sampler_id=1, and steps=20.
| Field | Accepted value |
|---|---|
checkpoint_id |
Positive integer. checkpointId is an alias. |
sampler_id |
Positive integer. samplerId is an alias. |
steps |
Integer from 10 through 30. |
style |
One to three unique comma-separated indices from 0 through 49. 0 and 1 may only be used alone. |
curl https://gateway.api429.com/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"flux-1","prompt":"A sunlit botanical illustration of native wildflowers, delicate ink lines and soft watercolor washes","checkpoint_id":5,"sampler_id":6,"steps":25,"style":"3,6,12"}'
The following authenticated discovery endpoints are non-billable:
GET /v1/yesai/flux/checkpointsGET /v1/yesai/flux/samplersGET /v1/yesai/flux/lora/models
LoRA remains prompt syntax: <lora:model_id:weight>. These controls add no
public model and do not change routing for Qwen, Nano Banana, Veo, or Gemini
Omni.
Midjourney modifications
Every generated image comes back with an id. Pass it as source_image_id
together with one of the models below to act on that image. No prompt is
needed except for mj-remix.
| Model | Result |
|---|---|
mj-upscale |
Upscale ×2, faithful to the original. Returns 1 image |
mj-upscale-creative |
Upscale ×2, adds invented detail. Returns 1 image |
mj-outpaint-x2 |
Extend on all four sides, area ×2 |
mj-outpaint-x1.5 |
Extend on all four sides, area ×1.5 |
mj-outpaint-left / mj-outpaint-right / mj-outpaint-up / mj-outpaint-down |
Extend in one direction |
mj-variations-subtle |
Variations close to the original |
mj-variations-strong |
Variations only loosely related |
mj-remix |
Re-render from new text — requires prompt |
# 1) generate — note the id on each returned image
curl https://gateway.api429.com/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "midjourney", "prompt": "a red fox in the snow --ar 16:9"}'
# 2) upscale the one you liked
curl https://gateway.api429.com/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "mj-upscale", "source_image_id": "103"}'
source_image_id is the numeric image id, not the image URL. An id we cannot
act on returns 400 rather than quietly producing something else.
Queue speed. Generations and modifications run on the relax queue by
default (1–12 minutes). Add "speed": "fast" to any Midjourney request to use
the fast queue (1–3 minutes) — it works for the mj-* modification models
too, which carry no speed word of their own. speed beats the speed in the
model alias, so midjourney-7.0-relax with "speed": "fast" runs fast.
Image editing
| Model | Result |
|---|---|
qwen-image-edit |
Edit by text instruction |
qwen-image-remove-bg |
Remove the background |
qwen-image-remove-watermark |
Remove watermarks |
qwen-image-colorize-1 / qwen-image-colorize-2 |
Colourise |
qwen-image-restore |
Restore damaged or low-quality photos |
qwen-image-contour |
Contour / line extraction |
qwen-image-depth |
Depth map |
qwen-image-extract-clothing |
Extract clothing |
qwen-image-make-old / qwen-image-make-young |
Age the subject up or down |
qwen-image-stylize |
Apply a style |
qwen-image-3d |
3D-style render |
acc-upper / acc-lower / acc-full |
Replace clothing from a photo — upper body, lower body, or full outfit |
Video
| Model | Result |
|---|---|
veo |
Text-to-video |
kling |
Animate a still image |
pika |
Animate a still image, Pika engine |
deepface-video |
Face replacement in video |
video-upscale |
Upscale an existing video |
Video jobs are long-running: submit, then poll for the result the same way as the other asynchronous media endpoints.
Embeddings
POST /v1/embeddings
POST /openai/v1/embeddings
POST /hf/v1/embeddings
OpenAI-compatible embedding endpoint backed by Google's Gemini embedding models. Load is spread across multiple backend pools automatically — you get high availability without managing keys or quotas.
| Model | Status | Cost | Output dim |
|---|---|---|---|
gemini-embedding-001 |
Stable | Free | 3072 (default), configurable via dimensions |
gemini-embedding-2-preview |
Preview | Free | 3072 (default) |
Single input
response = client.embeddings.create(
model="gemini-embedding-001",
input="Hello world"
)
print(response.data[0].embedding[:5])
Batch (list input)
input accepts an array of strings — all of them are embedded in a
single call:
response = client.embeddings.create(
model="gemini-embedding-001",
input=["First document", "Second document", "Third document"]
)
for emb in response.data:
print(emb.index, len(emb.embedding))
Custom output dimensionality
Pass dimensions to reduce vector size — useful for hybrid search,
nearest-neighbour indexes, or storage-constrained applications. Supported
values for gemini-embedding-001: 128, 256, 512, 768, 1536, 3072 (default).
response = client.embeddings.create(
model="gemini-embedding-001",
input="Hello world",
dimensions=768
)
assert len(response.data[0].embedding) == 768
cURL
curl https://gateway.api429.com/v1/embeddings \
-H "Authorization: Bearer $YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"model": "gemini-embedding-001",
"input": "Hello world",
"dimensions": 768
}'
Response shape
{
"object": "list",
"model": "gemini-embedding-001",
"data": [
{
"object": "embedding",
"index": 0,
"embedding": [-0.0343, 0.0116, -0.0214, ...]
}
],
"usage": {
"prompt_tokens": 2,
"total_tokens": 2
}
}
Notes
- Endpoint is optimised for query-time embeddings (search input, RAG retrieval). Documents-for-index embeddings work the same way — vector quality is identical.
- Empty
inputreturns HTTP 400. - No streaming — embedding responses are always returned in full.
Music Generation
Music generation is asynchronous. Submit a job, poll until it finishes, then
use the returned HTTPS URL. The API token must have the async audio scope.
New active external-customer tokens receive this scope by default. Existing
managed customer and project-token policies are upgraded automatically;
explicit policies remain unchanged. A restricted model allowlist must also
contain lyria-3-pro-preview.
Available model
| Model | Output | Maximum requested duration | Price |
|---|---|---|---|
lyria-3-pro-preview |
MP3 | 184 seconds | $0.08 per completed song |
duration_seconds guides the composition but is not a frame-exact duration
guarantee. A generated song can be shorter or longer than requested.
Create a music job
curl https://gateway.api429.com/v1/music/generations \
-H "Authorization: Bearer $API429_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: launch-theme-001" \
-d '{
"model": "lyria-3-pro-preview",
"prompt": "Cinematic synth-pop at 112 BPM, restrained verse, wide uplifting chorus",
"duration_seconds": 120,
"lyrics": "[Verse]\nCity lights begin to glow\n\n[Chorus]\nWe are ready, let it show",
"instrumental": false,
"output_format": "mp3"
}'
| Field | Type | Required | Notes |
|---|---|---|---|
model |
string | No | Defaults to lyria-3-pro-preview. |
prompt |
string | Yes | Musical direction, genre, mood, instruments, tempo and structure. |
duration_seconds |
integer | No | 1..184; treated as an approximate target. |
lyrics |
string | No | May include [Verse], [Chorus] and similar section tags. |
instrumental |
boolean | No | true cannot be combined with lyrics. |
output_format |
string | No | Currently mp3 only. |
google/lyria-3-pro-preview is accepted as an input compatibility alias and
is normalized to the canonical lyria-3-pro-preview ID in job responses.
Idempotency-Key is required. Reusing the same key with the same authenticated
client returns the original job instead of creating and charging for another
generation. A new key starts a new paid generation.
The submit response is HTTP 202:
{
"id": "job_...",
"object": "music.generation.job",
"status": "queued",
"model": "lyria-3-pro-preview"
}
Poll and retrieve the song
curl https://gateway.api429.com/v1/music/generations/job_... \
-H "Authorization: Bearer $API429_TOKEN"
While work is pending, the endpoint returns the current job status. A completed job returns:
{
"object": "music.generation",
"model": "lyria-3-pro-preview",
"data": [
{
"url": "https://cdn.example/song.mp3",
"mime_type": "audio/mpeg",
"bytes": 1544920,
"sha256": "..."
}
],
"billing": {
"charged_amount_usd": "0.08",
"unit_price_usd": "0.08",
"currency": "USD",
"pricing_status": "charged"
}
}
If the final upstream outcome cannot be determined safely, the job is marked
ambiguous and is not retried automatically. This prevents a second paid song
from being created behind the same job. Use a new idempotency key only after
checking the final status.
Video Generation Models
Video generation is asynchronous. Submit a job, poll until it finishes, then use the returned HTTPS CDN URL. The gateway does not return direct upstream storage URLs to clients.
The API token must have the async video scope. New active tokens classified
as external customers receive both video and audio by default; either can
be revoked in the admin UI. Async text and image remain opt-in, and existing
explicit token policies are never overwritten by the managed customer
default.
Available Models
| Model | Mode | Price per second, audio | Price per second, no audio | Durations | Samples | Resolutions |
|---|---|---|---|---|---|---|
gemini-omni-1.1-flash |
Omni 1.1 | resolution-dependent token usage, plus input/thinking | Not supported; audio is always generated | 3-10 sec | 1 | 360p, 720p, 1080p, 4k |
veo-3.1-generate-001 |
Standard | $0.40 (720p/1080p), $0.60 (4k) |
$0.20 (720p/1080p), $0.40 (4k) |
4, 6, 8 sec | 1-4 | 720p, 1080p, 4k |
veo-3.1-fast-generate-001 |
Fast | $0.10 (720p), $0.12 (1080p), $0.30 (4k) |
$0.08 (720p), $0.10 (1080p), $0.25 (4k) |
4, 6, 8 sec | 1-4 | 720p, 1080p, 4k |
veo-3.1-lite-generate-001 |
Lite | $0.05 (720p), $0.08 (1080p) |
$0.03 (720p), $0.05 (1080p) |
4, 6, 8 sec | 1-4 | 720p, 1080p |
veo-3-fast |
Fast | n/a | $0.50 base (5s) | 5 sec | 1 | 9:16, 16:9, auto |
veo-3-quality |
Quality | n/a | $1.50 base (5s) | 5 sec | 1 | 9:16, 16:9, auto |
pika-2.2 |
Image-animation | n/a | $0.50 per video | up to 6s | 1 | image-driven |
kling-1.6 / kling-2.0 / kling-2.5 / kling-3.0 |
Image+prompt → video | n/a | $0.375 base (5s); scales linearly for 10s/15s | 5, 10, 15 sec (15s on kling-3.0 only) |
1 | 1:1, 9:16, 16:9 |
deepface-video |
Face swap in video | n/a | $0.05 base | input video length | 1 | inherits input |
upscale-video-hd / -fhd / -4k |
Video upscaler | n/a | $0.30 / $0.60 / $2.40 base (30s clip) | input video length | 1 | output: 720p / 1080p / 2160p |
Gemini Omni 1.1 Flash
Use the stable client model ID gemini-omni-1.1-flash. The deprecated
gemini-omni-flash-preview and short gemini-omni-flash spellings are accepted
as input-only aliases and resolve to the new canonical ID. API429 does not
silently substitute Veo or another video provider.
API429 currently authenticates this route through Google Cloud Enterprise
Agent Platform, where Google exposes the 1.1 model under the provider-specific
wire ID gemini-omni-1.1-flash-preview. The job response therefore keeps
model:"gemini-omni-1.1-flash" as the client contract and reports the actual
Google wire ID separately in metadata.actual_model. The no-suffix ID is the
stable Gemini Developer API ID; the transport distinction is intentional and
observable rather than hidden.
Supported Omni workflows:
mode / task |
Required input | Notes |
|---|---|---|
text_to_video |
prompt |
Default when no media is supplied. |
image_to_video / first_last_frame / interpolation |
image |
Animate one image, or send image plus last_frame for first/last-frame interpolation. The aliases normalize to image_to_video. |
reference_to_video |
reference_images |
Up to 10 image references. |
edit |
video or previous_job_id |
Edit one source video under 10 seconds or continue a prior Omni result. |
extend / video_extension |
video |
Generate a 3-10 second continuation at the end of one source video. |
Omni media can be supplied as a public HTTPS URL, a gs:// URI, a base64/data
URI string, or an object such as
{"url":"https://.../image.png","mime_type":"image/png"}. API429 stages
external inputs privately before calling Google.
Omni accepts duration from 3 through 10 seconds, aspect_ratio of 16:9 or
9:16, one output, and resolution of 360p, 720p (default), 1080p, or
4k. The 1080p and 4k outputs are upscaled by Google. Optional controls are
temperature (0..2), top_p (0..1), and thinking_level (minimal, low,
medium, high). Audio is always generated: omit audio or send
audio:true; audio:false is rejected.
seed exists in the generic Interactions schema but is not documented as a
Gemini Omni model parameter, so API429 rejects it instead of pretending the
result is reproducible.
Official Agent Platform list rates used by API429 are $1.50 per 1M input tokens,
$9.00 per 1M text/thought output tokens, and $17.50 per 1M video output tokens.
Google accounts for video output at 1,931 tokens/sec for 360p, 5,792 for
720p, 8,688 for 1080p, and 17,376 for 4k (about $0.0338, $0.1014,
$0.1520, and $0.3041 per generated second respectively). API429 reserves a
conservative resolution-aware maximum before the worker calls Google and
refunds the difference after Google returns native usage. If native usage is
unavailable, the resolution-specific fallback is retained and the job is
marked accordingly instead of being billed as zero.
The Omni model does not support Chat Completions, system instructions, structured/JSON output, context caching, grounding/search, function calling, code execution, or audio references. Unsupported combinations return a validation error rather than silently degrading to another behavior.
Omni Submit Example
curl -X POST "https://gateway.api429.com/v1/videos/generations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: omni-video-001" \
-d '{
"model": "gemini-omni-1.1-flash",
"prompt": "A cinematic five-second product shot of a blue cup",
"duration": 5,
"aspect_ratio": "16:9",
"resolution": "720p",
"thinking_level": "high"
}'
Image-to-video changes only the mode and input:
{
"model": "gemini-omni-1.1-flash",
"mode": "image_to_video",
"prompt": "The camera slowly moves around the product",
"image": {
"url": "https://example.com/product.png",
"mime_type": "image/png"
},
"duration": 6,
"aspect_ratio": "9:16"
}
To continue editing a completed Omni result, submit a new request owned by the
same API key with mode:"edit" and previous_job_id set to the previous API429
job ID. API429 follows Google's official multi-turn format: it loads the prior
safe Agent Platform history (user_input, thought signature/summary, and
model_output) from encrypted, owner-checked job state and appends the new
instruction as a user_input step. Inline media bytes are not retained in the
history; private gs:// references are used instead. Clients never submit a
raw Google interaction ID or upstream GCS path. Continuation availability
follows the API429 async-job and GCS lifecycle configured by the operator.
Veo 3.1
For Veo, total estimated charge is
price_per_second * duration_seconds * sample_count. The gateway reserves the
estimated amount when the job is accepted. If the request fails before upstream
video generation starts, the reservation is released. If the upstream operation
has started, billing is finalized even if the final status is ambiguous.
Supported aspect ratios are 16:9 and 9:16. seed, when supplied, must be
an unsigned 32-bit integer. audio / generateAudio is forwarded to Vertex as
generateAudio.
Supported API429 mode values:
mode |
Required input | Notes |
|---|---|---|
text_to_video |
prompt |
Used when no media input is provided. |
image_to_video |
image |
Uses Vertex instances[].image. |
first_last_frame |
image, last_frame |
Uses Vertex instances[].image and instances[].lastFrame. |
frame_interpolation |
image, last_frame |
Alias for the same first/last frame Vertex shape. |
video_extension |
video |
Uses Vertex instances[].video. |
reference_guided |
reference_images |
Veo 3.1 supports referenceType: "asset" subject/product/person references. Style references are rejected for Veo 3.1. |
first_last_frame requires image and last_frame and is executed only by
Google Vertex Veo. video_extension requires video; clients must omit both
duration_seconds and duration, and the balancer omits Vertex
durationSeconds because extension adds a fixed seven seconds. Neither mode
falls back to an alternate video backend. After an uncertain upstream submit the async
job may become ambiguous; poll that original job and do not automatically
create a replacement paid request.
If mode is omitted or set to auto, API429 infers it from the supplied media
fields: video → video_extension, reference_images → reference_guided,
image + last_frame → first_last_frame, image → image_to_video, and no
media → text_to_video.
API429/OpenAI-style Endpoint
POST /v1/videos/generations
GET /v1/videos/generations/{job_id}
Request Body
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
model |
string | Yes | - | One of the video model IDs above |
mode / task |
string | No | auto |
Workflow supported by the selected model. Omni: text_to_video, image_to_video (first_last_frame / interpolation aliases), reference_to_video, edit, extend (video_extension / extension aliases). Veo modes are listed above. |
prompt |
string | Yes | - | Text prompt |
duration / duration_seconds |
integer | No | 8 |
Omni: 3-10. Veo: 4, 6, or 8; omit both fields for video_extension. |
n / sampleCount / sample_count |
integer | No | 1 |
Omni: exactly 1. Veo: 1-4. |
aspectRatio / aspect_ratio |
string | No | 16:9 |
16:9 or 9:16 |
resolution |
string | No | 720p |
Omni: 360p, 720p, 1080p, or 4k. Veo: 720p, 1080p, or 4k where supported. |
audio / generateAudio |
boolean | No | model-specific | Omni always generates audio. Veo forwards this control where supported. |
resizeMode / resize_mode |
string | No | - | crop or pad for image inputs |
cameraControl / camera_control |
string | No | - | Image-driven modes only; forwarded to Vertex as-is so preview/advanced camera controls can work when supported |
compressionQuality / compression_quality |
string | No | - | Advanced passthrough to Vertex; unsupported combinations return the Vertex error |
negativePrompt / negative_prompt |
string | No | - | Content to avoid |
personGeneration / person_generation |
string | No | - | Person generation policy |
seed |
integer | No | - | Veo only: unsigned 32-bit seed. Omni rejects it. |
temperature |
number | No | provider default | Omni only, 0..2. |
top_p / topP |
number | No | provider default | Omni only, 0..1. |
thinking_level / reasoning_effort |
string | No | provider default | Omni: minimal, low, medium, or high. |
previous_job_id |
string | No | - | Continue editing a prior Omni job owned by the same API key. |
image, lastFrame, referenceImages, video, inputs |
string/object/array | No | - | Optional media references. Public HTTPS URLs, gs://, data/base64, and media objects are accepted for Omni. |
Submit Example
curl -X POST "https://gateway.api429.com/v1/videos/generations" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: video-job-001" \
-d '{
"model": "veo-3.1-fast-generate-001",
"mode": "text_to_video",
"prompt": "A calm ocean wave at sunrise, cinematic",
"duration": 4,
"n": 1,
"aspectRatio": "16:9",
"resolution": "720p",
"audio": false
}'
Image-to-video uses the same endpoint with mode: "image_to_video":
{
"model": "veo-3.1-generate-001",
"mode": "image_to_video",
"prompt": "A slow cinematic push-in over the product",
"image": {"gcsUri": "gs://client-inputs/product.png", "mimeType": "image/png"},
"cameraControl": "push_in",
"resizeMode": "crop",
"duration_seconds": 8,
"resolution": "1080p",
"audio": false
}
First/last frame generation uses mode: "first_last_frame" with image and
last_frame. Video extension uses mode: "video_extension" with video and
no duration field.
Reference-guided subject/product generation uses mode: "reference_guided" and
up to three reference_images entries with referenceType: "asset".
API429 does not silently downgrade requested Veo capabilities. Preview-gated
features such as 4k, advanced camera controls, or account/region-specific
model behavior are forwarded when the request is syntactically valid. If Vertex
rejects the combination, the async job fails with the upstream validation error
and a sanitized summary of the requested model, mode, media fields, and
parameters. Reservations are released when rejection happens before the Vertex
operation starts.
Successful submit returns 202 with a job object:
{
"id": "01HYVIDEOJOB",
"object": "video.generation.job",
"status": "queued",
"endpoint": "videos.generations"
}
Poll until status is succeeded:
curl "https://gateway.api429.com/v1/videos/generations/01HYVIDEOJOB" \
-H "Authorization: Bearer YOUR_API_KEY"
Completed jobs return data[].url values that point to downloadable video/mp4
files on the gateway CDN. A completed Omni result can also include native usage
and settled billing:
{
"object": "video.generation",
"model": "gemini-omni-1.1-flash",
"data": [
{"url": "https://cdn.example.com/video.mp4", "mime_type": "video/mp4"}
],
"usage": {
"input_tokens": 312,
"output_tokens": 28960,
"thought_tokens": 144,
"total_tokens": 29416,
"input_tokens_by_modality": {"text": 24, "image": 288},
"output_tokens_by_modality": {"video": 28960}
},
"billing": {
"charged_amount_usd": "0.508564",
"currency": "USD",
"pricing_status": "usage"
},
"metadata": {
"route_provider": "google",
"actual_model": "gemini-omni-1.1-flash-preview"
}
}
Token values above illustrate the response shape; actual usage and price depend on the request and Google's returned accounting.
Vertex-compatible Endpoints (Veo only)
These routes are intended for clients migrating from a Vertex-style SDK or REST
integration. Keep the same request body shape and change the base URL/token.
Gemini Omni uses the API429/OpenAI-style endpoint above and is not exposed as a
Vertex predictLongRunning model.
POST /v1/projects/{project}/locations/{location}/publishers/google/models/{model}:predictLongRunning
POST /v1/projects/{project}/locations/{location}/publishers/google/models/{model}:fetchPredictOperation
Auth can be sent as x-goog-api-key: YOUR_API_KEY, ?key=YOUR_API_KEY, or
Authorization: Bearer YOUR_API_KEY.
Submit Example
curl -X POST "https://gateway.api429.com/v1/projects/gateway/locations/us-central1/publishers/google/models/veo-3.1-fast-generate-001:predictLongRunning" \
-H "x-goog-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"instances": [{"prompt": "A calm ocean wave at sunrise, cinematic"}],
"parameters": {
"durationSeconds": 4,
"sampleCount": 1,
"aspectRatio": "16:9",
"resolution": "720p"
}
}'
The gateway returns an API429-managed operation name:
{
"name": "api429/jobs/01HYVIDEOJOB",
"done": false,
"metadata": {"api429JobId": "01HYVIDEOJOB", "status": "queued"}
}
Fetch operation state:
curl -X POST "https://gateway.api429.com/v1/projects/gateway/locations/us-central1/publishers/google/models/veo-3.1-fast-generate-001:fetchPredictOperation" \
-H "x-goog-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"operationName":"api429/jobs/01HYVIDEOJOB"}'
If the feature is not enabled for your account, the route returns 403, 404,
or 503. If your balance is too low for the estimated video cost, submit
returns 402.
Speech-to-Text
POST /v1/audio/transcriptions
OpenAI-compatible transcription with gemini-3.5-transcribe. Send a
multipart/form-data body:
| Field | Required | Notes |
|---|---|---|
file |
yes | Audio file up to 25 MB, for example MP3 or WAV. Larger files return 413. |
model |
yes | gemini-3.5-transcribe |
language |
no | Expected language as an ISO-639-1 code (en, ru, …). Omit to auto-detect. |
response_format |
no | json (default), text, verbose_json, srt, vtt |
timestamp_granularities[] |
no | segment and/or word, for verbose_json |
prompt |
no | Accepted for SDK compatibility; not used by this model. |
verbose_json returns segments with start, end, text and a speaker
label (speaker_0, speaker_1, …), plus word timestamps when requested.
| Model | Audio in / 1M tokens | Text out / 1M tokens | Official ≈ / audio minute | API429 ≈ / audio minute* |
|---|---|---|---|---|
gemini-3.5-transcribe |
$2.00 | $12.00 | $0.005 | $0.0015 |
* The standard 70% client discount. Audio is billed at 32 tokens per second of audio; the transcript at its token count.
curl https://gateway.api429.com/v1/audio/transcriptions \
-H "Authorization: Bearer YOUR_API_KEY" \
-F model=gemini-3.5-transcribe \
-F response_format=verbose_json \
-F file=@meeting.mp3
{
"task": "transcribe",
"language": "unknown",
"duration": 3.44,
"text": "Hello. Your order has shipped and will arrive on Thursday.",
"segments": [
{"id": 0, "start": 0.2, "end": 3.1, "speaker": "speaker_0",
"text": "Hello. Your order has shipped and will arrive on Thursday."}
]
}
The OpenAI SDK works unchanged:
client.audio.transcriptions.create(model="gemini-3.5-transcribe", file=open("meeting.mp3", "rb")).
Text-to-Speech
POST /v1/audio/speech
GET /v1/audio/voices
POST /v1/audio/voices
DELETE /v1/audio/voices/{voice_id}
Single OpenAI-compatible endpoint for TTS. The Gemini models supported here
are gemini-3.8-flash-tts, gemini-3.8-flash-lite-tts,
gemini-3.1-flash-tts-preview and gemini-2.5-flash-preview-tts. The request
surface is intentionally small:
required model and input, plus optional voice and response_format.
Omitting model fails request validation with HTTP 422; the gateway does
not silently substitute a Gemini TTS model.
For Gemini TTS models the response is a full WAV body (audio/wav,
24 kHz mono PCM-16). ElevenLabs models return MP3 (audio/mpeg).
response_format is accepted for SDK compatibility, but it does not change
Gemini output.
TTS surface support matrix
| Surface | Route / API | Supported controls | Output / caveats |
|---|---|---|---|
| OpenAI-compatible gateway | POST /v1/audio/speech |
model, input, voice, response_format, delivery |
Full-body response. Gemini returns WAV; ElevenLabs returns MP3. No temperature, languageCode, first-class multi-speaker, streaming, or Cloud audioConfig passthrough. |
| Voices | GET / POST / DELETE /v1/audio/voices |
Catalogue lookup (language, q, limit, offset), cloning from an uploaded sample, scope=mine |
Fish models only. A cloned voice is private to the key that created it. |
| Gemini-native gateway | POST /gemini/v1beta/models/{model}:generateContent |
responseModalities: ["AUDIO"], speechConfig.voiceConfig, multiSpeakerVoiceConfig, languageCode, temperature |
Non-streaming through this balancer. Response is Gemini JSON with base64 raw PCM; wrap into WAV client-side. |
| Cloud Text-to-Speech direct | Google Cloud text:synthesize / text:streamingSynthesize |
prompt + text, audioEncoding, sampleRateHertz, speed, volume gain, MultiSpeakerMarkup, streaming, advancedVoiceOptions.safetySettings |
Use Google Cloud auth directly. These controls are not proxied by /v1/audio/speech. |
Available models
| Model | Status | Text in / 1M | Audio out / 1M tokens | Derived base / 1K chars | API429 / 1K chars* | Output |
|---|---|---|---|---|---|---|
gemini-3.8-flash-tts |
Newest Gemini TTS, most natural delivery | $0.50† | $9† | $0.0167 | $0.0050 | audio/wav |
gemini-3.8-flash-lite-tts |
Cheapest Gemini TTS, low latency | $0.50† | $6† | $0.0111 | $0.0033 | audio/wav |
gemini-3.1-flash-tts-preview |
Expressive, supports audio tags | $1.00 | $20 | $0.0370 | $0.0111 | audio/wav |
gemini-2.5-flash-preview-tts |
Previous generation, Flash | $0.50 | $10 | $0.0185 | $0.0056 | audio/wav |
† Google's promotional price through 2026-12-31; from 2027-01-01 Google lists
gemini-3.8-flash-ttsat $1.00 / $18 andgemini-3.8-flash-lite-ttsat $1.00 / $12 per 1M tokens.
Google API surface matters.
gemini-2.5-flash-ttsis a model ID for Google's separate Cloud Text-to-Speech API. It is not valid on GeminigenerateContent, and API429 does not currently proxy Cloud TTStext:synthesizeortext:streamingSynthesize. A400 INVALID_ARGUMENTfromgenerateContentfor that ID is an endpoint/model mismatch, not a missing Cloud API switch on the API429 gateway.
ElevenLabs models
| Model | Best for | Official / 1K chars | API429 / 1K chars* | Output |
|---|---|---|---|---|
elevenlabs-gen |
Expressive ElevenLabs speech and character voices, 70+ languages | $0.100 | $0.030 | audio/mpeg |
eleven_v4 |
Newest ElevenLabs model: most expressive delivery, 90+ languages, IPA pronunciation control | $0.100 | $0.030 | audio/mpeg |
eleven_v4_turbo |
Eleven v4 quality with lower latency, for live and conversational use | $0.050 | $0.015 | audio/mpeg |
* The API429 column applies the standard 70% client discount to the $0.0370 base rate: $0.0370 × 30% = $0.0111 per 1K characters. A per-client billing profile may override the discount shown here.
elevenlabs-gen is the single canonical ElevenLabs model. Pass the native
ElevenLabs voice ID in the standard OpenAI-compatible voice field; if you
omit it or pass an unrecognized name, a default voice is used.
It is served by three interchangeable backends tried in order until one
returns audio. You are always billed at the elevenlabs-gen rate above no
matter which backend served the request, so the price is identical every
time. Long input is chunked and returned as a single joined MP3 — you never
receive an archive.
The legacy ids eleven_v3, eleven_multilingual_v2, eleven_flash_v2_5
and api429-tts remain accepted for backward compatibility but are no
longer listed in GET /v1/models; new integrations should use
elevenlabs-gen.
Eleven v4 and v4 Turbo
eleven_v4 and eleven_v4_turbo are ElevenLabs' newest speech models
(released 2026-09-28): more expressive delivery, 90+ languages and phonetic
(IPA) pronunciation control. v4 Turbo trades a little quality for lower
latency. Both are listed in GET /v1/models; request them by exact id on
POST /v1/audio/speech. Prices are in the table above. Voices work as for
elevenlabs-gen: pass a native ElevenLabs voice ID in voice, or omit it
for the default voice. Output is MP3 (audio/mpeg).
Unlike elevenlabs-gen, the v4 models have no automatic standby backend: if
the provider is unavailable the request fails instead of being retried
elsewhere. eleven_v3 is still available and unchanged; pick the model
explicitly in each request.
curl https://gateway.api429.com/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "eleven_v4",
"voice": "hpp4J3VqNfWAUOO0d1Us",
"input": "Hello! This is Eleven v4 through API429."
}' \
--output speech.mp3
If the speech provider's content filter blocks part of your text, the
request returns 422 naming how many fragments were rejected; rephrase
the flagged wording and retry.
curl https://gateway.api429.com/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "elevenlabs-gen",
"voice": "hpp4J3VqNfWAUOO0d1Us",
"input": "Привет! Это озвучка ElevenLabs через API429."
}' \
--output speech.mp3
Fish Audio model
| Model | Best for | Official / 1M UTF-8 bytes | API429 / 1M UTF-8 bytes* | Output |
|---|---|---|---|---|
fish-s2.1-pro |
Long-form narration, 80+ languages, large public voice library | $15.00 | $4.50 | audio/mpeg |
* The API429 column shows the standard 70% client discount. A per-client billing profile may override the discount shown here.
Fish Audio bills the UTF-8 byte length of the input text, and so do we: 1 byte per Latin character, 2 per Cyrillic, 3 per Chinese, Japanese or Korean character. 1,000 Russian characters therefore cost the same as 2,000 English ones ($0.03 official, $0.009 after the standard discount).
voice is required for this model. Pass the 32-character hex id of a
voice from the catalogue (see below), or the id of a voice you cloned. There
is no default: omitting voice, sending an empty string, or sending a voice
name such as "Sarah" all return 400 with the id format spelled out. That
is deliberate. A substituted default produced perfectly good audio in the
wrong voice and answered 200, so a typo looked like the gateway ignoring
voice altogether — one client spent a day on exactly that. Voices carry
their own language tags, and many are multilingual, so one voice often covers
several markets.
An id that has the right shape but does not exist is currently reported as
502("could not be served by any configured provider") rather than a4xx, because the provider's rejection is relayed as an upstream failure. If you get a502from/v1/audio/speech, check the voice id against the catalogue before reporting an outage.
Output format. fish-s2.1-pro honours response_format: mp3 (default),
wav, pcm and opus. Use wav when the consumer requires RIFF/WAVE — some
post-processing pipelines reject MP3. WAV is roughly six times larger than the
same audio as MP3, so prefer mp3 unless you specifically need RIFF.
Long input is handled for you. Text longer than a few thousand characters
is split on sentence boundaries, synthesised in parallel and returned as a
single joined clip — never an archive, and never a word cut in half. An hour of
narration (~60 000 characters) takes roughly three minutes end to end. opus
is the one exception: it cannot be joined safely, so long input in that format
returns 400 — use mp3, wav or pcm instead.
Billing note. The provider meters UTF-8 bytes, while the rate above is per character. Latin text is one byte per character, but Cyrillic is two and CJK three, so non-Latin narration costs proportionally more upstream than the per-character figure suggests. Always use the authoritative bill in
/api/client/usage/dailyfor budgeting.
curl https://gateway.api429.com/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "fish-s2.1-pro",
"input": "Привет! Это озвучка Fish Audio через API429.",
"voice": "90e65eaaf50e4470b8e6d43ee6afd7d5",
"response_format": "wav"
}' \
--output speech.wav
Voice catalogue
GET /v1/audio/voices
Since voice is required and a wrong one is a 400, this is how you find a
valid id. Over a thousand public voices are available, in many languages.
| Parameter | Default | Meaning |
|---|---|---|
model |
fish-s2.1-pro |
Which model's catalogue to list. Models without one answer 400. |
language |
— | Keep voices tagged with this language. Most voices are multilingual, so a voice usually appears under several. |
q |
— | Substring match on the voice name, case-insensitive. |
limit / offset |
100 / 0 |
Page window; limit is capped at 1000. |
scope |
catalogue |
mine lists your own cloned voices instead (see below). |
curl "https://gateway.api429.com/v1/audio/voices?language=ru&q=narrator&limit=5" \
-H "Authorization: Bearer YOUR_API_KEY"
{
"object": "list",
"model": "fish-s2.1-pro",
"total": 37,
"offset": 0,
"data": [
{
"id": "90e65eaaf50e4470b8e6d43ee6afd7d5",
"name": "Documentary narrator",
"languages": ["ru", "en"],
"tags": ["narration", "calm"],
"description": "Warm, unhurried delivery…",
"author": "…",
"popularity": 48213
}
]
}
Take id from any entry and pass it as voice on POST /v1/audio/speech.
Results are ordered by popularity — how many jobs the voice has served — so
the first page is a reasonable shortlist rather than an arbitrary slice.
total counts everything matching the filter, not the page. Only public,
finished voices appear.
Cloned voices
POST /v1/audio/voices
GET /v1/audio/voices?scope=mine
DELETE /v1/audio/voices/{voice_id}
Upload a recording of a voice once and synthesise with it from then on. The
returned id behaves like any catalogue voice — pass it in voice — except
that it is private to the API key that created it.
Send the audio as multipart/form-data:
| Field | Required | Meaning |
|---|---|---|
file |
yes | The voice sample. WAV, MP3, FLAC, OGG/Opus or M4A. Ten to thirty seconds of clear speech with little background noise gives the best result; more audio does not help. |
name |
yes | Your own label for the voice. |
transcript |
no | Exactly what is said in the sample. The clone works without it and matches the original more closely with it. |
curl https://gateway.api429.com/v1/audio/voices \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@narrator.mp3" \
-F "name=House narrator" \
-F "transcript=I have been recording audiobooks for eleven years."
{
"id": "voice_b3b86385ec1b489f9d16183f603ee25c",
"object": "audio.voice",
"name": "House narrator",
"created": 1789661983,
"sample_bytes": 197431,
"sample_format": "audio/mpeg",
"has_transcript": true
}
curl https://gateway.api429.com/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "fish-s2.1-pro",
"input": "This text is read in the cloned voice.",
"voice": "voice_b3b86385ec1b489f9d16183f603ee25c"
}' \
--output cloned.mp3
A cloned voice works everywhere a catalogue voice does, long-form splitting included: every chunk of a long narration is produced in the same voice.
Your voices are yours. A cloned voice is bound to the API key that created
it. Another key using the id gets 404, the same answer as an id that never
existed, and cannot see it in its own scope=mine listing. DELETE removes
the voice and the stored recording; afterwards the id answers 404.
Limits and errors.
| Situation | Response |
|---|---|
| File is not recognisable audio | 400 |
| Sample larger than 8 MB | 413 — ten to thirty seconds is plenty, and MP3 is far smaller than WAV |
| 25 voices already registered | 409 — delete one first |
| Cloned voice used with a model that has no cloning | 400 |
| Cloning not enabled for the deployment | 503 |
Cloned synthesis is billed exactly like any other synthesis on the model —
per character of input, at the same rate. Registering, listing and deleting
a voice are free.
Getting a link instead of a file
An hour of narration is about 10 MB as MP3 and far more as WAV, which is
awkward to carry in a synchronous response body. Set "delivery": "url" and
the clip is uploaded to our CDN and described by a small JSON body instead:
curl https://gateway.api429.com/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "fish-s2.1-pro",
"input": "…длинный текст ролика…",
"delivery": "url"
}'
{
"url": "https://api429.lon1.cdn.digitaloceanspaces.com/api429/tts/…mp3",
"mime": "audio/mpeg",
"bytes": 10452992
}
Omit delivery (or send "inline") and you get the raw audio bytes exactly as
before — the default is unchanged.
gemini-3.1-flash-tts-preview currently has a documented 8,192 input-token
limit and 16,384 output-token limit. Upstream Batch API is supported for that
model, while caching, function calling, Live API, structured output, code
execution, grounding, and URL context are not.
* How we derive the effective rate. Google bills TTS per audio token: 1 second of output = 25 audio tokens. English speech averages 13.5 chars/sec, so 1M audio tokens ≈ 40 000 s ≈ 540 000 chars.
$20 / 1M audio tokens × (1M / 540K) = $0.03704 per 1K chars (Gemini 3.1) $0.0370 rounded base rate × 30% after the standard 70% discount = $0.0111 billedRussian / CJK speech is slower (~10–12 chars/sec) → our per-char rate slightly under-bills non-English traffic (error <25%). For budget planning always use the authoritative bill reported by
/api/client/usage/daily— it reflects the actual Google charge, not this estimate.Text input ($1.00 / 1M text tokens) adds <5 % to the total for typical TTS requests, so clients can usually plan on just the audio-output rate.
Quick start (OpenAI-compatible)
from openai import OpenAI
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY",
)
response = client.audio.speech.create(
model="gemini-3.1-flash-tts-preview", # current Gemini TTS model
voice="Kore",
input="Hello, welcome to our API."
)
response.stream_to_file("output.wav")
curl https://gateway.api429.com/v1/audio/speech \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-o output.wav \
-d '{
"model": "gemini-3.1-flash-tts-preview",
"voice": "Kore",
"input": "Hello, welcome to our API."
}'
// Node.js / TypeScript via the official OpenAI SDK
import OpenAI from "openai";
import { writeFile } from "node:fs/promises";
const client = new OpenAI({
baseURL: "https://gateway.api429.com/v1",
apiKey: process.env.BALANCER_API_KEY!,
});
const speech = await client.audio.speech.create({
model: "gemini-3.1-flash-tts-preview",
voice: "Kore",
input: "Hello, welcome to our API.",
});
await writeFile("output.wav", Buffer.from(await speech.arrayBuffer()));
// Node.js / browser via plain fetch (no SDK dependency)
const res = await fetch("https://gateway.api429.com/v1/audio/speech", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.BALANCER_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gemini-3.1-flash-tts-preview",
voice: "Kore",
input: "Hello, welcome to our API.",
}),
});
if (!res.ok) {
const err = await res.json();
throw new Error(`TTS failed: ${err.error?.message ?? res.status}`);
}
const wav = Buffer.from(await res.arrayBuffer());
require("node:fs").writeFileSync("output.wav", wav);
OpenAI SDK example with expressive tags
Gemini 3.1 Flash TTS Preview adds expressive bracket tags for narrative control. Keep the tags in English even when the spoken text is Russian or another language.
response = client.audio.speech.create(
model="gemini-3.1-flash-tts-preview",
voice="Puck",
input=(
"Прочитай как тревожный рассказчик: "
"Я открыл дверь. [short pause] Там никого не было. [gasp]"
),
)
response.stream_to_file("tagged.wav")
response_formatfield. All Gemini TTS calls returnaudio/wavregardless of whatresponse_formatyou pass. The OpenAI SDK exposesresponse_formatfor compatibility, but the upstream doesn't honourmp3/opus/aac/flac/pcm— you'll always get the same 24 kHz mono PCM-16 WAV body. Convert withffmpegclient-side if you need a different container.
Voice library (30 prebuilt voices)
Gemini TTS ships with 30 distinct voices. Each carries a unique tonal character; pick one that matches your use case.
All previews speak the same English pangram ("The quick brown fox jumps over the lazy dog.") so you can A/B them by ear. Russian / CJK delivery sounds slightly different but maintains the same character.
Female voices (14):
| Voice | Character | Preview |
|---|---|---|
Achernar |
Soft | |
Aoede |
Breezy | |
Autonoe |
Bright | |
Callirrhoe |
Easy-going | |
Despina |
Smooth | |
Erinome |
Clear | |
Gacrux |
Mature | |
Kore ⭐ |
Firm | |
Laomedeia |
Upbeat | |
Leda |
Youthful | |
Pulcherrima |
Forward | |
Sulafat |
Warm | |
Vindemiatrix |
Gentle | |
Zephyr |
Bright |
Male voices (16):
| Voice | Character | Preview |
|---|---|---|
Achird |
Friendly | |
Algenib |
Gravelly | |
Algieba |
Smooth | |
Alnilam |
Firm | |
Charon |
Informative | |
Enceladus |
Breathy | |
Fenrir |
Excitable | |
Iapetus |
Clear | |
Orus |
Firm | |
Puck |
Upbeat | |
Rasalgethi |
Informative | |
Sadachbia |
Lively | |
Sadaltager |
Knowledgeable | |
Schedar |
Even | |
Umbriel |
Easy-going | |
Zubenelgenubi |
Casual |
⭐ Kore is the balancer default if voice is omitted or unknown.
Unknown voice names silently fall back to Kore — the balancer
whitelists names before forwarding to upstream.
Note for offline / GitHub readers. The previews above are hosted at
https://hostkey24760.api429.com/admin-panel/front-max/voice-samples/<Voice>.mp3— public, no auth required. If you're reading this on GitHub or in an offline mirror, pop the URLs into your browser to listen. Alternative: Google's interactive AI Studio Voice Library plays each voice with multiple sample phrases.
Voice picker by use-case
Quick guide to narrow 30 → 1 by what you're building. All recommendations are subjective — listen to the previews and trust your ears.
| Use-case | Recommended voices | Why |
|---|---|---|
| Audiobook narration (calm, sustained) | Sulafat, Charon, Rasalgethi, Vindemiatrix |
Warm, even, easy to listen to for hours |
| Podcast / talk-show host (energetic) | Puck, Zephyr, Laomedeia, Sadachbia |
Upbeat, engaging, expressive intonation |
| News / weather / formal | Kore, Charon, Algieba, Schedar |
Firm, neutral, "anchor"-like delivery |
| Voice assistant / chatbot | Kore, Orus, Aoede, Achird |
Friendly, balanced, doesn't fatigue |
| Children's content | Leda, Aoede, Achird |
Youthful, breezy, approachable |
| Suspense / dramatic narration | Enceladus, Algenib, Gacrux, Fenrir |
Breathy, gravelly, mature, excitable — can carry tension |
| Russian / CJK | Kore, Charon, Sulafat, Puck |
These four hold their character cleanest in non-English |
| Two-speaker dialogue | One bright (Puck/Zephyr/Aoede) + one firm (Kore/Charon) |
Maximum tonal contrast for clarity |
Languages
Gemini TTS auto-detects the language from the input text. 24 languages GA:
Arabic (Egypt), Bangla (Bangladesh), Dutch, English (India, US), French, German, Hindi, Indonesian, Italian, Japanese, Korean, Marathi, Polish, Portuguese (Brazil), Romanian, Russian, Spanish (Spain), Tamil, Telugu, Thai, Turkish, Ukrainian, Vietnamese.
50+ more in Preview (Chinese Mandarin, Greek, Hebrew, Norwegian, Swedish, Czech, and more — see Google's official list).
# Russian — just write the text, no extra parameter needed
response = client.audio.speech.create(
model="gemini-3.1-flash-tts-preview",
voice="Kore",
input="Привет, как твои дела сегодня?",
)
Style control
Two mechanisms can shape delivery:
1. Natural-language style prefix
Prepend a style instruction to the text.
client.audio.speech.create(
model="gemini-3.1-flash-tts-preview",
voice="Enceladus",
input="Say in a spooky whisper: Something wicked this way comes.",
)
client.audio.speech.create(
model="gemini-3.1-flash-tts-preview",
voice="Puck",
input="Read excitedly, like breaking news: The rocket has landed!",
)
2. Expressive audio tags
Square-bracket tags mid-sentence control non-speech sounds and pacing. Google does not publish an exhaustive taxonomy; treat the list below as official/common examples from Gemini API and Cloud TTS docs, then test the exact phrasing with your voice and language.
client.audio.speech.create(
model="gemini-3.1-flash-tts-preview",
voice="Puck",
input="That joke was amazing. [laughs] I cannot stop thinking about it. [short pause] But seriously…",
)
Common modes:
Non-speech sounds — vocal inserts:
| Tag | Effect |
|---|---|
[sigh] / [sighs] |
Exhale |
[laughs] / [laughing] / [giggles] |
Chuckle or laughter |
[gasp] |
Surprised inhale |
[uhm] |
Filler sound |
[cough] / [coughs] |
Cough |
[chuckling] |
Low laugh while speaking |
Style modifiers — change delivery characteristics:
| Tag | Effect |
|---|---|
[whispers] / [whispering] |
Lower volume, breathy |
[shouting] |
Higher energy, louder |
[sarcasm] / [sarcastically] |
Dry, deadpan delivery |
[robotic] |
Synthetic, flat affect |
[extremely fast] / [very fast] |
Accelerated pace |
[very slow] |
Slower delivery |
Vocalized markup — emotional colouring:
| Tag | Effect |
|---|---|
[amazed] |
Amazed tone |
[crying] |
Crying tone |
[excited] / [excitedly] |
Raised pitch and pace |
[scared] |
Trembling, higher pitch |
[curious] |
Questioning intonation |
[bored] |
Flat, drawn out |
[reluctantly] / [mischievously] |
Hesitant or playful tone |
[serious] / [tired] / [panicked] / [trembling] |
Mood modifiers |
Pacing — silence gaps:
| Tag | Effect |
|---|---|
[short pause] |
~250 ms silence |
[medium pause] |
~500 ms silence |
[long pause] |
~1 s silence |
Language note: keep audio tags in English regardless of the spoken language.
[laughs]works inside a Russian sentence;[смеётся]may be read aloud literally.
Temperature (creativity control)
Gemini TTS supports a temperature parameter in the range (0.0, 2.0].
Higher values give more expressive / varied reads; lower values stay
predictable. The OpenAI-compatible endpoint doesn't expose it yet — use
the Gemini-native non-streaming endpoint if you need it:
curl "https://gateway.api429.com/gemini/v1beta/models/gemini-3.1-flash-tts-preview:generateContent" \
-H "x-goog-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{"parts": [{"text": "Tell me about the stars"}]}],
"generationConfig": {
"responseModalities": ["AUDIO"],
"temperature": 1.5,
"speechConfig": {
"voiceConfig": {"prebuiltVoiceConfig": {"voiceName": "Kore"}}
}
}
}'
The Gemini-native response contains base64 raw PCM in
candidates[0].content.parts[0].inlineData.data; decode it and wrap as
24 kHz mono PCM-16 WAV client-side.
Sane starting points:
- 0.2–0.5 — narration, consistent reads, audiobooks
- 0.8–1.2 — conversational, default feel
- 1.5–2.0 — theatrical, emotional, podcast hosts
Multi-speaker dialogue
Gemini TTS can voice a conversation between up to 2 speakers in a
single call. The balancer's OpenAI-compatible endpoint doesn't
expose speaker_voice_configs yet — use the Gemini-native
non-streaming endpoint for multi-speaker output:
curl "https://gateway.api429.com/gemini/v1beta/models/gemini-3.1-flash-tts-preview:generateContent" \
-H "x-goog-api-key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"contents": [{"parts": [{"text":
"TTS the following conversation:\nJoe: How is it going today Jane?\nJane: Not too bad, how about you?"
}]}],
"generationConfig": {
"responseModalities": ["AUDIO"],
"speechConfig": {
"multiSpeakerVoiceConfig": {
"speakerVoiceConfigs": [
{"speaker": "Joe", "voiceConfig": {"prebuiltVoiceConfig": {"voiceName": "Kore"}}},
{"speaker": "Jane", "voiceConfig": {"prebuiltVoiceConfig": {"voiceName": "Puck"}}}
]
}
}
}
}' | jq -r '.candidates[0].content.parts[0].inlineData.data' \
| base64 --decode > dialogue.pcm
# Wrap raw PCM 16-bit 24kHz mono into a WAV:
ffmpeg -f s16le -ar 24000 -ac 1 -i dialogue.pcm dialogue.wav
Two ways to format the dialogue in contents.parts[0].text:
(a) Freeform (shown above) — Speaker: … line prefixes in plain text.
Simplest to generate from an LLM.
(b) Structured — explicit turn list (Python SDK only):
from google import genai
from google.genai import types
client = genai.Client(
vertexai=True,
project="YOUR_GCP_PROJECT",
location="global",
)
turns = [
types.Content(role="user", parts=[
types.Part(text="Joe: How's it going today Jane?"),
]),
types.Content(role="user", parts=[
types.Part(text="Jane: Not too bad, how about you?"),
]),
]
response = client.models.generate_content(
model="gemini-3.1-flash-tts-preview",
contents=turns,
config=types.GenerateContentConfig(
response_modalities=["AUDIO"],
speech_config=types.SpeechConfig(
multi_speaker_voice_config=types.MultiSpeakerVoiceConfig(
speaker_voice_configs=[
types.SpeakerVoiceConfig(speaker="Joe",
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Kore"))),
types.SpeakerVoiceConfig(speaker="Jane",
voice_config=types.VoiceConfig(
prebuilt_voice_config=types.PrebuiltVoiceConfig(voice_name="Puck"))),
]
)
),
temperature=1.5,
),
)
Pro tip: if you want multi-speaker via the OpenAI-compatible
endpoint, pre-format the text with Speaker: prefixes and let a
single voice read both parts — the model still uses the speaker
context to vary intonation slightly. Open a ticket if you need
first-class speaker_voice_configs on /v1/audio/speech.
Audio output format
| Field | Value |
|---|---|
| Container | WAV (our gateway wraps raw PCM) |
| Codec | PCM linear 16-bit little-endian |
| Sample rate | 24 000 Hz |
| Channels | Mono (1) |
| Upstream raw | 16-bit PCM 24 kHz (no header) — we prepend the 44-byte WAV header |
Input / output limits
| Constraint | Limit |
|---|---|
Recommended /v1/audio/speech chunk |
3.5–4 KB UTF-8 for reliable prosody and retries; no local 4 KB limiter was found in the gateway code |
Cloud Text-to-Speech direct prompt + text |
Up to 8 000 bytes total upstream; prompt and text are each limited to 4 000 bytes |
Vertex direct contents |
Up to 8 000 bytes upstream |
| Speech generation session/context | 32k tokens upstream |
| Gemini 3.1 Flash TTS Preview | 8,192 input tokens, 16,384 output tokens |
| Output audio duration | Around 655 seconds upstream; quality can degrade after several minutes |
| Per-minute rate | Coordinated by the balancer; no per-client cap configured by default |
Latency profile
Measured 2026-04-23 against production (median of 5 cold-start requests, 60 chars input, Kore voice):
| Model | p50 | typical | Notes |
|---|---|---|---|
gemini-3.1-flash-tts-preview |
2.2 s | 2–5 s | Current API429 Gemini TTS model |
Voice / model compatibility
All five Gemini TTS models support the 30 voices listed above.
Error responses
All errors follow the OpenAI error envelope: HTTP status + a JSON body
of {"error": {"message": "...", "type": "...", "code": "..."}}. The
table covers what you'll actually encounter from /v1/audio/speech
under normal operation:
| Status | When it happens | Example body | Retryable? |
|---|---|---|---|
| 400 | A syntactically valid request is rejected by the selected TTS provider, for example empty input or an unsupported non-Gemini provider model | {"error":{"message":"input must not be empty","type":"invalid_request_error","code":"invalid_request"}} |
No — fix the request |
| 422 | Missing or blank required model, missing input, unsupported Gemini TTS ID, malformed JSON, or invalid field types |
FastAPI validation error envelope | No — fix the request |
| 401 | Missing or invalid Authorization: Bearer … header |
{"error":{"message":"Invalid authentication token","type":"invalid_request_error","code":"invalid_token"}} |
No — rotate the key |
| 413 | Provider rejects oversized input, for example Cloud/Vertex prompt + text beyond upstream byte limits |
Upstream-shaped 413 — pre-chunk, see Long-form audio below | No — split client-side |
| 429 | Per-key or per-binding rate limit hit upstream. Response carries Retry-After (seconds) |
{"error":{"message":"Rate limit exceeded","type":"rate_limit_error","code":"rate_limit"}} + Retry-After: 30 |
Yes — sleep Retry-After then retry |
| 500 | Upstream Gemini returned a 5xx, or balancer Python exception un-wrapped to FastAPI | {"error":{"message":"Internal server error","type":"internal_error","code":"500"}} |
Yes — exponential backoff, see Retry pattern |
| 502 | host nginx couldn't reach the balancer (deploy window, ~35 s) — the host nginx auto-translates this to 503 + Retry-After: 10 | (already converted to 503; see below) | n/a |
| 503 | Backend temporarily unavailable: balancer redeploy or upstream queue timeout | {"error":{"message":"Backend temporarily unavailable, retry in 10 seconds","type":"backend_unavailable","code":503,"retry_after":10}} + Retry-After: 10 |
Yes — sleep Retry-After then retry |
| 504 | Long upstream stall — rare for TTS (single-shot is short) | OpenAI-shaped 504 | Yes with caution — at most 1 retry |
How to read errors safely (Python):
from openai import OpenAI, APIError, RateLimitError, APIStatusError
client = OpenAI(base_url="https://gateway.api429.com/v1", api_key="...")
try:
resp = client.audio.speech.create(model="gemini-3.1-flash-tts-preview", voice="Kore", input=text)
except RateLimitError as e: # 429 — respect Retry-After
retry_after = int(e.response.headers.get("retry-after", "30"))
...
except APIStatusError as e:
if e.status_code in (502, 503, 504): # transient — retry
retry_after = int(e.response.headers.get("retry-after", "10"))
...
elif e.status_code in (400, 401, 413): # permanent — surface
raise
else:
raise
Retry pattern
Three rules that keep retries safe and cheap:
- Honour
Retry-Afterwhen the server sets it (429 / 503 always do). That value reflects current capacity — beating it just queues you server-side without speedup. - Exponential backoff with jitter for transient 5xx without
Retry-After. Recommended schedule:
2 s → 8 s → 30 s(max 3 attempts, ±20 % jitter). - Don't retry 400/401/413 — re-issuing the same request with the same input gets the same error and burns budget. Surface it.
Reference Python implementation
import asyncio
import random
from openai import AsyncOpenAI, APIStatusError, RateLimitError
client = AsyncOpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY",
)
async def synthesize_with_retry(*, model: str, voice: str, input: str,
max_attempts: int = 4) -> bytes:
"""Synthesize speech with bounded retry. Honours Retry-After.
Returns the full WAV bytes. Raises on permanent errors or after
``max_attempts`` transient failures.
"""
backoff_s = [2, 8, 30, 60]
for attempt in range(max_attempts):
try:
resp = await client.audio.speech.create(
model=model, voice=voice, input=input,
)
return await resp.aread()
except RateLimitError as e: # 429
wait = int(e.response.headers.get("retry-after", "30"))
except APIStatusError as e:
if e.status_code in (400, 401, 413): # permanent
raise
if e.status_code in (429, 502, 503, 504, 500) and attempt < max_attempts - 1:
wait = int(e.response.headers.get("retry-after",
str(backoff_s[attempt])))
else:
raise
wait *= (1 + random.uniform(-0.2, 0.2)) # ±20 % jitter
await asyncio.sleep(wait)
raise RuntimeError("synthesize_with_retry: all attempts failed")
Reference TypeScript implementation
import OpenAI, { APIError } from "openai";
const client = new OpenAI({
baseURL: "https://gateway.api429.com/v1",
apiKey: process.env.BALANCER_API_KEY!,
});
const BACKOFF_S = [2, 8, 30, 60];
const sleep = (ms: number) => new Promise((r) => setTimeout(r, ms));
export async function synthesizeWithRetry(args: {
model: string;
voice: string;
input: string;
maxAttempts?: number;
}): Promise<Buffer> {
const max = args.maxAttempts ?? 4;
for (let attempt = 0; attempt < max; attempt++) {
try {
const r = await client.audio.speech.create({
model: args.model,
voice: args.voice,
input: args.input,
});
return Buffer.from(await r.arrayBuffer());
} catch (e) {
if (!(e instanceof APIError)) throw e;
const status = e.status ?? 0;
if ([400, 401, 413].includes(status)) throw e; // permanent
if (![429, 500, 502, 503, 504].includes(status)) throw e;
if (attempt === max - 1) throw e;
const headerRetry = Number(e.headers?.["retry-after"]) || BACKOFF_S[attempt];
const jittered = headerRetry * (1 + (Math.random() - 0.5) * 0.4);
await sleep(jittered * 1000);
}
}
throw new Error("synthesizeWithRetry: exhausted");
}
Cloud-only technical controls
Google Cloud Text-to-Speech exposes lower-level controls that are useful for
direct Cloud integrations, but they are not fields on our /v1/audio/speech
route.
curl -X POST "https://texttospeech.googleapis.com/v1/text:synthesize" \
-H "Authorization: Bearer $(gcloud auth application-default print-access-token)" \
-H "x-goog-user-project: $PROJECT_ID" \
-H "Content-Type: application/json" \
-d '{
"input": {
"prompt": "Read the following in a curious, restrained tone.",
"text": "OK, so... tell me about this [uhm] AI thing."
},
"voice": {
"languageCode": "en-us",
"name": "Kore",
"model_name": "gemini-2.5-flash-tts"
},
"audioConfig": {
"audioEncoding": "LINEAR16",
"sampleRateHertz": 24000,
"speakingRate": 1.0,
"volumeGainDb": 0.0
},
"advancedVoiceOptions": {
"safetySettings": []
}
}'
advancedVoiceOptions.safetySettings is a Cloud Text-to-Speech direct API
feature. It is intentionally not documented as a balancer request field.
Legacy relax_safety_filters / safety_settings knobs are not passed through
by the gateway.
What /v1/audio/speech does NOT expose
For completeness, these controls are not fields on the narrow OpenAI-compatible speech endpoint. Some are available through the Gemini-native gateway as shown above; Cloud-only controls require a direct Google Cloud integration:
| Feature | Upstream support | Why not exposed |
|---|---|---|
temperature |
✅ Gemini-native generateContent |
Use /gemini/v1beta/models/{model}:generateContent; /v1/audio/speech stays OpenAI-compatible |
languageCode |
✅ Gemini-native / Cloud TTS direct | Gemini auto-detects on /v1/audio/speech; explicit BCP-47 is not exposed there |
| First-class multi-speaker config | ✅ Gemini-native multiSpeakerVoiceConfig / Cloud MultiSpeakerMarkup |
Use Gemini-native route or Cloud direct for speaker-to-voice mapping |
| Alternate audio encodings (MP3, OGG_OPUS, ALAW, MULAW, PCM) | ✅ Cloud TTS direct unary calls | Gemini path returns a WAV container; some alternate aliases may return MP3 |
Custom sample rate (sampleRateHertz) |
✅ Cloud TTS direct | Gemini gateway path is fixed 24 kHz mono PCM |
| Streaming TTS (chunked audio) | ✅ Cloud TTS StreamingSynthesize; ✅ Vertex direct streaming |
Gemini Developer API TTS and our /v1/audio/speech are non-streaming full responses |
| Batch API (async bulk TTS) | ✅ Upstream for gemini-3.1-flash-tts-preview |
Not proxied by the balancer |
advancedVoiceOptions.safetySettings |
✅ Cloud TTS direct | Not a /v1/audio/speech request field |
| Custom voice cloning | ❌ Not supported by Google | Only 30 prebuilt voices — Google has no voice-cloning public API |
Full Google reference:
- Gemini Developer API: https://ai.google.dev/gemini-api/docs/speech-generation
- Vertex AI Gemini TTS: https://cloud.google.com/text-to-speech/docs/gemini-tts
- Interactive voice library: https://aistudio.google.com/apps/bundled/voice-library
Long-form audio (10+ minutes)
For audiobooks, podcasts, or any narration over several minutes, the client should split the script into chunks, synthesize them in parallel, and concatenate the WAV files locally. The balancer does not chunk, batch, or stream-merge automatically.
Use 3.5–4 KB UTF-8 as a safe recommended chunk size. The old docs
overstated this as a local cap, but no such gateway limiter was found; the real
upstream Cloud/Vertex direct prompt + text limit is 8,000 bytes, and long
single requests can degrade in quality after several minutes. Upstream output
is around 655 seconds at the high end, but chunking remains the safer
production pattern.
Sizing math
| Target audio duration | Approximate chars (English, 13.5 ch/s) | Chunks at 3 500 bytes | Wall-clock at 8 parallel × 4 s/chunk |
|---|---|---|---|
| 30 min | ~24 000 | 7 | ~4 s |
| 60 min | ~49 000 | 14 | ~8 s |
| 90 min | ~73 000 | 21 | ~12 s |
| 120 min | ~97 000 | 28 | ~16 s |
Russian / CJK speech is slower (~10–12 ch/s), so character counts run ~25 % lower for the same duration. Cost scales linearly with input characters at the rate listed in Available models above (e.g. 90 min Flash ≈ $1.35).
Chunking strategy
- Split at sentence boundaries so prosody isn't broken mid-phrase.
- Bin-pack chunks around 3 500 bytes UTF-8 (leaving head-room for style prefixes, transcript tags, and retries).
- Preserve order — parallel synthesis must reassemble in input order on concat, not in completion order.
Parallel synthesis
5–10 concurrent requests is a safe ceiling. The balancer spreads parallel calls across multiple bindings automatically; pushing past 10 just queues server-side without speedup.
Concatenation
All Gemini TTS responses are 24 kHz mono PCM-16 WAV (see Audio output format above). Identical sample rate / channel layout means you can concatenate the audio payloads directly without re-encoding. Two practical options:
- Python
wavestdlib — read all WAVs, write one combined file. Zero external dependencies. - ffmpeg —
ffmpeg -f concat -safe 0 -i list.txt -c copy out.wavwithlist.txtlisting chunk filenames in order.
Full Python example (split → gather → concat)
import asyncio
import io
import re
import wave
from openai import AsyncOpenAI
client = AsyncOpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY",
)
CHUNK_BUDGET_BYTES = 3500 # leave 500 B for the balancer's style prefix
PARALLELISM = 8 # 5-10 is safe; >10 just queues server-side
def split_into_chunks(text: str, budget: int = CHUNK_BUDGET_BYTES) -> list[str]:
"""Split text at sentence boundaries, bin-pack to ≤budget bytes UTF-8."""
sentences = re.split(r"(?<=[.!?])\s+", text.strip())
chunks: list[str] = []
buf = ""
for sent in sentences:
candidate = (buf + " " + sent).strip()
if len(candidate.encode("utf-8")) > budget and buf:
chunks.append(buf)
buf = sent
else:
buf = candidate
if buf:
chunks.append(buf)
return chunks
async def synthesize_one(idx: int, text: str, sem: asyncio.Semaphore) -> tuple[int, bytes]:
async with sem:
resp = await client.audio.speech.create(
model="gemini-3.1-flash-tts-preview",
voice="Kore",
input=text,
)
return idx, await resp.aread()
async def synthesize_long(text: str, out_path: str) -> None:
chunks = split_into_chunks(text)
sem = asyncio.Semaphore(PARALLELISM)
results = await asyncio.gather(
*(synthesize_one(i, c, sem) for i, c in enumerate(chunks))
)
# Reassemble in original order (gather preserves input order, but
# we tag explicitly so partial-result paths stay safe).
results.sort(key=lambda x: x[0])
with wave.open(out_path, "wb") as out_wav:
params_set = False
for _, wav_bytes in results:
with wave.open(io.BytesIO(wav_bytes), "rb") as in_wav:
if not params_set:
out_wav.setparams(in_wav.getparams())
params_set = True
out_wav.writeframes(in_wav.readframes(in_wav.getnframes()))
# Usage:
# asyncio.run(synthesize_long(open("script.txt").read(), "narration.wav"))
Failure handling tips
- Wrap
synthesize_onein afor attempt in range(3)retry loop — individual chunks may hit upstream 429 / 5xx independently. The balancer already retries internally, but a top-level client retry protects against rare wall-clock timeouts. - If one chunk consistently fails after retries, you can either fail
the whole job, or skip with silence padding (
b"\x00" * bytes_per_second * estimated_seconds) so the WAV stays the expected length — depends on whether your downstream tolerates gaps. - Track per-chunk usage: each call is billed independently
(
/api/client/usage/dailyaggregates them).
When to ask for server-side support
If you're regularly generating audio over ~30 minutes and the
client-side concat is operationally painful (e.g. mobile clients,
browser environments without wave stdlib), open a ticket — we can
prioritise a server-side /v1/audio/speech/long endpoint that
chunks, fans-out, and returns one WAV in a single HTTP response.
Integration recipes
End-to-end snippets for common products. Each is self-contained and
uses only the public /v1/audio/speech endpoint.
1. Telegram bot — voice replies
# pip install python-telegram-bot openai
import io, os
from openai import OpenAI
from telegram import Update
from telegram.ext import Application, MessageHandler, ContextTypes, filters
tts = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key=os.environ["BALANCER_API_KEY"],
)
async def voice_reply(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
text = update.message.text or "Hello!"
if len(text.encode("utf-8")) > 4000:
await update.message.reply_text("Sorry, message too long for TTS.")
return
speech = tts.audio.speech.create(
model="gemini-3.1-flash-tts-preview",
voice="Kore",
input=text,
)
# Telegram accepts WAV directly via send_voice (or send_audio for file).
await update.message.reply_voice(io.BytesIO(speech.read()))
app = Application.builder().token(os.environ["TELEGRAM_BOT_TOKEN"]).build()
app.add_handler(MessageHandler(filters.TEXT & ~filters.COMMAND, voice_reply))
app.run_polling()
2. Audiobook from a .txt file
Reuses the chunking helper from Long-form audio — wires it to a
plain text file and produces one WAV. Picks Sulafat (warm, sustained)
which works well for hours of narration.
import asyncio
from pathlib import Path
# ...split_into_chunks, synthesize_one, synthesize_long defined in
# the "Long-form audio" section above...
async def audiobook(in_path: str, out_path: str, voice: str = "Sulafat") -> None:
text = Path(in_path).read_text(encoding="utf-8")
# Override the default voice in synthesize_one by using a partial
# or just pass it through — see Long-form Python example.
await synthesize_long(text, out_path, voice=voice, model="gemini-3.1-flash-tts-preview")
# CLI: python audiobook.py book.txt narration.wav
if __name__ == "__main__":
import sys
asyncio.run(audiobook(sys.argv[1], sys.argv[2]))
3. Chat narration — LLM reply read aloud
Pipes a chat-completions response through TTS. Uses two streams in parallel: the text stream is consumed by the speaker, the audio job runs on the assembled chunks.
import os
from openai import OpenAI
llm = OpenAI(base_url="https://gateway.api429.com/v1",
api_key=os.environ["BALANCER_API_KEY"])
# 1) Get a chat reply
chat = llm.chat.completions.create(
model="claude-sonnet-4-5",
messages=[{"role": "user", "content": "Tell me a 3-sentence bedtime story."}],
max_tokens=200,
)
reply_text = chat.choices[0].message.content
# 2) TTS it (single-shot — short replies fit comfortably)
speech = llm.audio.speech.create(
model="gemini-3.1-flash-tts-preview",
voice="Despina", # smooth, calming for bedtime
input=reply_text,
)
with open("story.wav", "wb") as f:
f.write(speech.read())
4. Web-app preview button
Browser fetches via the same Bearer token. Keep the token server-side in production — this snippet is for an authenticated admin UI where the token is already in scope.
<button id="preview" data-text="Hello, this is a preview." data-voice="Puck">▶</button>
<audio id="player" controls></audio>
<script>
document.getElementById("preview").addEventListener("click", async (e) => {
const btn = e.currentTarget;
const res = await fetch("https://gateway.api429.com/v1/audio/speech", {
method: "POST",
headers: {
"Authorization": `Bearer ${window.YOUR_TOKEN}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
model: "gemini-3.1-flash-tts-preview",
voice: btn.dataset.voice,
input: btn.dataset.text,
}),
});
if (!res.ok) {
const err = await res.json().catch(() => ({}));
alert("TTS failed: " + (err.error?.message ?? res.status));
return;
}
const blob = await res.blob();
document.getElementById("player").src = URL.createObjectURL(blob);
document.getElementById("player").play();
});
</script>
Integration Cookbook
Use this section when adapting an existing client or debugging a request that works against one vendor SDK but fails through the gateway.
Pick the endpoint by workload
| Workload | Endpoint | Model examples | Notes |
|---|---|---|---|
| Text chat | POST /v1/chat/completions |
gemini-3.1-pro, claude-sonnet-5, gpt-5.4 |
Standard OpenAI Chat Completions shape. |
| GPT reasoning / tool workflows | POST /v1/responses |
gpt-5.5, gpt-5.4, gpt-5.3-codex |
Recommended for GPT-5.x reasoning and tool state. |
| Text-to-image | POST /v1/images/generations |
gpt-image-2, gemini-3-pro-image, FLUX.2-pro |
JSON request body. |
| Image edit / image-to-image | POST /v1/images/edits |
gpt-image-2, gemini-3-pro-image |
Multipart form request with one or more image files. |
| Embeddings | POST /v1/embeddings |
gemini-embedding-001 |
Non-streaming vector output. |
| TTS | POST /v1/audio/speech |
gemini-3.1-flash-tts-preview |
Full audio body response; Gemini returns WAV. |
| Gemini native multimodal | /gemini/v1beta/models/{model}:generateContent |
gemini-* |
Use when your client already sends Google contents.parts with inline_data or fileData. |
Always call GET /v1/models with the same API key you will use in production
before exposing a model in your UI. The response is filtered by the token's
allowed models.
Multimodal request formats
OpenAI-compatible chat vision:
{
"model": "gemini-3.1-pro",
"messages": [{
"role": "user",
"content": [
{"type": "text", "text": "Describe this image"},
{"type": "image_url", "image_url": {"url": "https://example.com/photo.jpg"}}
]
}]
}
Gemini-native multimodal:
{
"contents": [{
"role": "user",
"parts": [
{"text": "Describe this image"},
{"inline_data": {"mime_type": "image/jpeg", "data": "<BASE64_IMAGE_DATA>"}}
]
}]
}
Use the native Gemini route only when your client already speaks Gemini's
contents.parts format. OpenAI SDK clients should use the OpenAI-compatible
messages[].content[] format above.
For Gemini-native media, inlineData.data / inline_data.data and
thoughtSignature inputs accept either standard base64 or URL-safe base64,
with or without padding. API429 responses use canonical padded standard
base64. This makes response → next-request round trips safe without a client
re-encoding step.
Streaming clients
- Read SSE until
data: [DONE]. - Ignore SSE comments and empty lines.
- Do not convert "stream returned 0 chunks" into an immediate second non-streaming request for long jobs; that can duplicate work and cost.
- If the HTTP request fails before any SSE data is processed, retry with exponential backoff.
- If an
event: errorarrives after text/audio/image work has started, treat it as a failed attempt and retry only according to your product's idempotency policy.
Retries and rate limits
- Respect
Retry-Afterwhen present. - Retry 429, 503, 504 and transient network errors with backoff.
- Do not hot-loop retries. Use jitter and cap retries.
- For long Claude text jobs, prefer
stream:truefor interactive UX orX-Async-Jobs-Optin: truefor non-streaming durable execution.
Common request fixes
| Symptom | Likely cause | Fix |
|---|---|---|
404 on a documentation .md link |
Separate markdown guides are not served publicly | Use this /documentation page; all public examples are here. |
model_not_found or model_not_allowed |
Token allowlist does not include the requested model | Call GET /v1/models with the same key and use one of those IDs. |
| Image edit fails with JSON body | /v1/images/edits expects multipart form |
Send -F "image=@file.png" and -F "prompt=...". |
| Gemini image-to-image payload is rejected | Client sends Google inline_data to an OpenAI-compatible endpoint |
Use /gemini/v1beta/models/{model}:generateContent for Gemini-native payloads, or use /v1/images/edits multipart. |
| TTS response cannot be parsed as JSON | /v1/audio/speech returns binary audio |
Read the response as bytes/blob and save/play it as WAV or MP3. |
| Claude streaming appears idle | Client waits for final response instead of reading SSE | Use stream:true, parse chunks incrementally, and keep a long read timeout. |
temperature rejected on a reasoning model |
Some reasoning modes require provider-specific sampling rules | Omit temperature unless you need it; use reasoning_effort for reasoning depth. |
Files API
Native Gemini Files API, proxied 1:1. Useful for uploading large inputs
(video, long PDFs) that will be referenced from generateContent calls.
| Method | Path | Description |
|---|---|---|
POST |
/upload/v1beta/files |
Initialise a resumable upload |
GET/POST/PUT |
/upload/{upload_path} |
Continue a resumable upload |
GET |
/v1beta/files |
List files |
GET |
/v1beta/files/{file_id} |
Get file metadata |
DELETE |
/v1beta/files/{file_id} |
Delete a file |
The same routes are exposed under /gemini/upload/v1beta/files and
/gemini/v1beta/files[/…]. Auth is x-goog-api-key: <token> or ?key=<token>.
Client Usage & Balance
These endpoints describe the state of the Bearer token that called them — no admin access required.
| Method | Path | Description |
|---|---|---|
GET |
/api/client/balance |
Current balance state for the calling token |
GET |
/api/client/usage/daily |
Last 24h: call counts, token usage, image counts, top models |
GET |
/api/client/usage/summary |
Day/week/month usage and cost rollups |
POST |
/api/client/usage/daily/telegram |
Send the last-24h report to Telegram (server-managed bot) |
curl https://gateway.api429.com/api/client/balance \
-H "Authorization: Bearer YOUR_API_KEY"
{
"token_id": "tok_…",
"token_last4": "a1b2",
"balance": {
"currency": "USD",
"available": "12.3400",
"spent_today": "0.5120"
}
}
The POST /api/client/usage/daily/telegram body accepts:
{
"chat_id": "123456789",
"message_thread_id": 42
}
chat_id is required on first send; subsequent calls may omit it and reuse
the stored one.
Client Portal (Web)
A browser-based self-service dashboard is available at:
https://client.api429.com/
Sign in. Paste your bearer token (the same gb_… value you use for API
calls) into the Sign in input and click the button. The token is kept only
in sessionStorage of the current browser tab and is cleared as soon as you
close the tab — no cookies, no password, no separate account.
What it shows.
- Current balance in USD, with a low-balance warning when you approach the threshold configured on your token.
- Day / week / month breakdown: total calls, success vs. failure counts, input / output / image tokens, official price and your discounted price.
- Top 10 models over the last 30 days — requests, tokens, cost.
Refresh / sign out. The Refresh button re-fetches balance and usage. Sign out clears the token from the tab and returns you to the login view.
Error Handling
HTTP Status Codes
| Code | Meaning | What to Do |
|---|---|---|
200 |
Success | — |
400 |
Bad request | Fix request body or model name |
401 |
Unauthorized | Check your API key |
402 |
Insufficient balance | Top up the client token |
403 |
Forbidden / token context missing | Check token scope |
429 |
Rate limited | Retry after 30–60 seconds |
500 |
Server error | Retry request |
503 |
No keys available | Wait for key cooldown (1–10 min) |
Error Response Format
{
"error": {
"code": "http_error",
"message": "Human-readable error description"
}
}
Provider content filtering
An AGY-backed chat request whose provider reports a content block returns HTTP 400 with error.code: "content_filter", rather than an empty successful completion. The message includes the provider reason, such as PROHIBITED_CONTENT, without exposing withheld text. It is not charged to the client and is not automatically replayed on another account/provider. A legitimate empty answer with STOP remains successful.
For streaming, a block before the first emitted chunk returns the same HTTP error. If the stream already started, its HTTP status stays 200; an SSE error frame carries code: "content_filter" and status: 400 before [DONE]. Treat that response as incomplete.
Common Errors
| Error Message | Cause | Fix |
|---|---|---|
Missing Authorization header |
No Bearer token | Add Authorization: Bearer KEY header |
Capacity exhausted, please retry shortly |
All capacity for the requested model is temporarily saturated | Back off and retry (see strategy below) |
Model not found |
Invalid model name | Check model tables above |
Content blocked by safety filters |
Prompt flagged | Modify your prompt |
Retry Strategy
import time
from openai import OpenAI, APIError
client = OpenAI(
base_url="https://gateway.api429.com/v1",
api_key="YOUR_API_KEY"
)
for attempt in range(3):
try:
response = client.chat.completions.create(
model="gemini-3-flash-preview",
messages=[{"role": "user", "content": "Hello"}]
)
break
except APIError as e:
if e.status_code in (429, 503):
time.sleep(30)
continue
raise
Rate Limits
- The gateway multiplexes requests across a pool of capacity and retries transient errors transparently on your behalf.
- If capacity is briefly saturated you'll receive an HTTP
429or503. Back off with exponential jitter and retry — in practice a second or two is usually enough. - Very long-running generations (certain audio / image models) may
return
504past the internal timeout; retry with the same prompt. - Per-client quotas, if configured, are enforced via HTTP
403with a descriptive message. Contact your administrator to raise your limit.
Supported SDK Clients
Any OpenAI-compatible SDK works out of the box:
| Language | SDK | Compatibility |
|---|---|---|
| Python | openai |
Full |
| JavaScript/TS | openai |
Full |
| Go | go-openai |
Full |
| Rust | async-openai |
Full |
| Ruby | ruby-openai |
Full |
| Java | OpenAI Java SDK | Full |
| cURL | — | Full |
Set base_url / baseURL to https://gateway.api429.com/v1 and use your
API key. For Gemini-native or Vertex Express SDKs, point them at
https://gateway.api429.com/v1beta or
https://gateway.api429.com/vertex-express/v1beta respectively and use
the x-goog-api-key header (or ?key= query parameter).
Customer discounts on Google video
Veo generation uses the official Google tariff for the requested model, resolution, audio, duration and number of clips. Your configured customer discount applies to the video quote: with a 70% discount you pay 30% of Google's price. For example, Veo 3.1 Fast at 720p with audio is $0.03/second, or $0.24 for one eight-second clip, at that discount. Provider fallback does not change this customer tariff. A failed generation before a chargeable result releases the reserved customer amount. Successful job results include billing.charged_amount_usd, billing.official_amount_usd and billing.discount_percent. Standard Veo rates are available from GET /api/public/catalog with video_second and resolution/audio conditions; your account's terms may differ. Google pricing.