Documentation

Gemini Balance

API Reference

Version: 3.20.3 | Last Updated: 2026-09-04

Current Gemini Flash models (2026-09-03): gemini-3.8-flash is the latest stable Flash model published by API429. gemini-3.7-flash remains 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/models is 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 and trace_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.20.3

  • Gemini 3.5 Flash serving route: on 2026-09-03 the upstream that served the gemini-3.5-flash-low / -medium / -high effort variants retired Gemini 3.5 Flash and began answering with a text notice instead of an error. gemini-3.5-flash is now served on Google's own transports only, and the three effort IDs remain accepted as compatibility aliases of gemini-3.5-flash at the same price. The suffix no longer changes the reasoning budget — pass thinking_level (low / medium / high) on gemini-3.5-flash instead. gemini-3.5-flash-low is no longer listed in GET /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_customer tokens receive both async video and audio scopes 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-preview before the token can generate music.

What's new in 3.20.0

  • Lyria 3 Pro music generation: added lyria-3-pro-preview through the durable async POST /v1/music/generations API.
  • 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-Key is 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 / high reasoning effort with medium as the default.
  • Canonical-only requests: do not append -non-thinking or effort suffixes to the model ID. Custom temperature, top_p, top_k, and n / native candidateCount are unsupported.
  • Strict request validation: generation must end with a non-empty user text turn; model-prefill turns are rejected. Native FunctionResponse parts 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 retired gemini-omni-flash-preview and short gemini-omni-flash spellings remain input-only compatibility aliases.
  • New Omni controls: added 360p, 1080p, and 4k alongside 720p, 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 video scope by default. Text, image, and audio async scopes remain explicit admin opt-ins.
  • Native TTS billing parity: Gemini generateContent speech 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-preview is the current Gemini speech model on both API429 TTS surfaces. Cloud TTS model IDs are no longer presented as Gemini generateContent models.
  • 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 returns url (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.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 n explicitly to receive fewer. Request-level size/aspect_ratio are ignored — use --ar inside prompt.
  • Midjourney modifications: every generated image returns an id; pass it as source_image_id with mj-upscale, mj-upscale-creative, mj-outpaint-*, mj-variations-subtle, mj-variations-strong or mj-remix to act on that image.

What's new in 3.14.0

  • Fish Audio TTS: new fish-s2.1-pro on POST /v1/audio/speech — 80+ languages, a large public voice library, $0.015 / 1K chars official ($0.0045 after the standard 70% discount).
  • Output formats: fish-s2.1-pro honours response_formatmp3 (default), wav, pcm, opus. Use wav when 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; opus cannot be joined and returns 400 for long input.
  • Link delivery: send "delivery": "url" on /v1/audio/speech to 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.6 after production probes confirmed text, vision, reasoning, function calling, structured output, Chat Completions, and Responses API.
  • Reasoning: reasoning_effort accepts low, medium, high, or xhigh; omit it for xAI's high default. 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-flash model, 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_k and thinking_budget; API429 removes those unsupported controls before dispatch. Use thinking_level or reasoning_effort with low, medium, or high (default: medium).

What's new in 3.11.0

  • Nano Banana Pro is GA: use canonical ID gemini-3-pro-image. The retired gemini-3-pro-image-preview ID and friendly names nano-banana-pro / nana-bana-pro remain accepted as compatibility aliases and are rewritten before the Google request.
  • Model catalogue re-audited: every Available Models table (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 in GET /v1/models at $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 the elevenlabs-gen rate no matter which backend served the request.
  • Legacy ids still accepted: eleven_v3, eleven_multilingual_v2, eleven_flash_v2_5, and api429-tts keep routing for backward compatibility but are no longer advertised in the catalogue; new integrations should use elevenlabs-gen.

What's new in 3.9.0

  • Claude Opus 5 and Claude Fable 5: claude-opus-5 and claude-fable-5 are 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-tts requests 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/speech and the Gemini-native gateway is gemini-3.1-flash-tts-preview.
  • Content filter: TTS input rejected by the speech provider's content filter now returns 422 naming how many fragments were blocked, instead of a generic failure.
  • Fixed reasoning-effort Gemini variants: gemini-3.5-flash-low and gemini-3.1-pro-low are documented and billed at their base model's rate.
  • Catalogue cleanup: GET /v1/models no 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 a ccw- twin, and gemini-3.5-flash or gemini-3.1-pro-preview instead of a -high/-medium variant.

What's new in 3.8.0

  • ElevenLabs TTS: added eleven_v3, eleven_multilingual_v2, and eleven_flash_v2_5 on the OpenAI-compatible POST /v1/audio/speech endpoint.
  • Native voices: pass an ElevenLabs voice_id through the standard voice field; 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-preview generation through the async /v1/videos/generations API. The accepted compatibility alias is gemini-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_id are 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/models for availability on your token.

What's new in 3.6.0

  • GPT-5.6 family: added gpt-5.6 (alias of gpt-5.6-sol), gpt-5.6-sol, and gpt-5.6-terra for Chat Completions and Responses API.
  • Reasoning: GPT-5.6 supports none, low, medium, high, xhigh, and max; the default is medium.
  • 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-luna is not yet listed because it is not currently available through the gateway. Check GET /v1/models for 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 on POST /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/messages for Claude clients that already use the official Anthropic Messages API shape. Use x-api-key auth and the same API429 client token.
  • Claude usage transparency: clarified usage.input_tokens / usage.output_tokens on native Messages responses and prompt_tokens / completion_tokens on OpenAI-compatible responses.
  • Claude native streaming: documented Anthropic SSE event order for stream:true on /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 standard POST /v1/chat/completions endpoint.
  • Extended text catalogue: additional vendor-prefixed chat IDs are now selectable — openai/gpt-5, openai/gpt-5-instant, openai/gpt-5-thinking, and google/gemini-3-pro, google/gemini-2.5-pro, google/gemini-2.5-flash.
  • New image models: nano-banana-2 (alias of gemini-3.1-flash-image), flower-image, gpt-image-1, and grok-image (xAI Aurora) added to POST /v1/images/generations.
  • Confirm availability with GET /v1/models using 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/completions using OpenAI-compatible message content parts.
  • Supported video input shapes: input_video with base64 data, and direct video_url inputs that the gateway stages temporarily before sending to Gemini.
  • Streaming support: stream:true works 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, and veo-3.1-lite-generate-001.
  • Native migration paths: clients can use the API429/OpenAI-style /v1/videos/generations route or Vertex-compatible predictLongRunning / fetchPredictOperation routes 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-flash is 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 .md guides 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/models catalogue. 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/models remains the authoritative per-token allowlist.

What's new in 3.5.1

  • GPT Image 2 client guide: clarified how to call gpt-image-2 through 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/generations and /v1/images/edits is documented as a dedicated GPT Image path, not a Gemini image alias.
  • GPT Image edits/reference images: /v1/images/edits and Responses image_generation guidance now covers input_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:true chat requests. Text deltas stream through OpenAI-compatible SSE. stream:true + tools remains synthetic SSE.

What's new in 3.2.0

  • Claude long-gen optional headers for batch screenwriter / multi-turn workflows: X-Session-Key for conversation continuity and X-Async-Jobs-Optin: true for 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).


Quick Start

Base URL:  https://gateway.api429.com/v1
Auth:      Authorization: Bearer YOUR_API_KEY

The previous address https://hostkey24760.api429.com continues to work; existing integrations do not need to change anything. New integrations should use https://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

  1. Endpoints & Auth Matrix
  2. Authentication
  3. Text Models (Chat Completions)
  4. Responses API
  5. GPT Models
  6. Grok & Extended Catalogue
  7. Claude Models
  8. Image Generation Models
  9. Embeddings
  10. Video Generation Models
  11. Text-to-Speech
  12. Integration Cookbook
  13. Files API
  14. Client Usage & Balance
  15. Error Handling
  16. Rate Limits
  17. 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-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. Select low, medium, or high with thinking_level or reasoning_effort; the default is medium. 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 (including web_search_preview, web_search, and file_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, and n / native candidateCount are not supported. Omit them rather than relying on a provider default. frequency_penalty and presence_penalty remain valid.

Gemini 3.8 tool turns. The OpenAI-compatible route rejects tools, tool_choice, assistant tool_calls, and role:"tool" messages for this model. Use the native Gemini route when function calling is required. Native requests support client-executed functionDeclarations and urlContext. 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. generateContent and OpenAI-compatible chat requests must end with a user turn containing non-whitespace text; assistant or model prefill is rejected. Native FunctionResponse objects must include both a call identifier (call_id or REST id) and name. countTokens accepts 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-flash ID; 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 / native candidateCount and thinking_budget are not forwarded. Choose reasoning with thinking_level or OpenAI-style reasoning_effort: low, medium, or high. minimal and disabled thinking are not supported.

Gemini 3.7 tool turns. OpenAI-compatible tools / tool_choice requests 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-flash accepts 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-pro and gemini-3.1-pro-preview switch 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-progemini-3.1-pro-preview
  • gemini-3-flashgemini-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_effort field (low / medium / high) maps to each model's native reasoning budget. On Claude thinking-enabled models temperature must be absent — the gateway strips it automatically.
  • Compatible Gemini models additionally honour a -non-thinking suffix on the model id to disable reasoning entirely. gemini-3.8-flash and gemini-3.7-flash are excluded: their canonical IDs accept only low, medium, or high thinking levels.
  • GPT reasoning models accept suffixes like -high, -low on the model id as shorthand for reasoning_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 with type: "video_url" and video_url.url.
  • API429 OpenAI-compatible chat extension: content[] item with type: "input_video" and base64 input_video.data.
  • Gemini native: contents[].parts[].fileData.fileUri with mimeType: "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, prepares temporary media storage, and sends provider-readable fileData to Gemini CLI where supported. 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 MB.
  • Maximum video parts passed to Gemini CLI: 4.
  • Large videos may be split into several temporary parts so Gemini CLI can fetch them.
  • If a video cannot be prepared without exceeding the part limit, the request returns a clear error instead of silently falling back to a provider that cannot see the video.

Other behavior:

  • stream:false and stream:true are both supported.
  • The response is text. Use /v1/videos/generations for video output.
  • The gateway temporarily stages video in storage, passes a signed file URL to Gemini, and deletes the staged object after the request finishes.
  • 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/generations
  • POST /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. background: "transparent" is not supported for gpt-image-2; use opaque or omit it.

GPT Image 2 billing is token-based. OpenAI publishes these token rates:

Component API429 list price
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 final request cost is the sum of text input tokens, image input tokens for edits/reference images, and output image tokens. For smoke tests and drafts, use quality:"low" and a 1024-class size.

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

All GPT-family models (including the Codex sub-family) are available through two endpoints:

  • POST /v1/chat/completions — standard Chat Completions format
  • POST /v1/responses — OpenAI Responses API format (recommended for GPT-5.x reasoning models)

The gateway picks the right path automatically based on the model id.

Available Models

Model Input $/1M Cached input Cache write Output $/1M Context Best For
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
Frontier (GPT-5.5)
gpt-5.5 $5.00 $30.00 Agentic coding, computer use and research
Flagship (GPT-5.4)
gpt-5.4 $2.50 $15.00 Reasoning, tool use and agentic workflows
gpt-5.4-mini $0.75 $4.50 Fast, efficient, lightweight tasks
Coding Specialists (GPT-5.3)
gpt-5.3-codex $1.75 $14.00 Coding workflows
Previous Gen
gpt-5.2 $1.75 $14.00 Deep debugging and analysis

Use the exact model IDs above for new integrations. Compatibility IDs gpt-5.6 resolves to gpt-5.6-sol. Compatibility IDs such as gpt-5, gpt-5-mini, and gpt-5.1 are still accepted for older clients and bill at the resolved gpt-5.2 rate, but they 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-5.6 accepts all six values; older GPT models may support a subset.

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.

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.6 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.6 $2.00 $0.50 $6.00 500K Current xAI flagship: reasoning, vision, function calling, structured output

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.6. 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.

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/models response 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)

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_preview were 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 passed web_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

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
gemini-2.5-flash-image Stable $0.039 Alias: nano-banana
gemini-3.1-flash-lite-image Stable $0.0336 Nano Banana 2 Lite. Alias: nano-banana-2-lite; compatibility alias: nana-banana-2-lite.
nano-banana-2 Stable alias $0.067 Alias of gemini-3.1-flash-image; identical routing, allowlist semantics, capabilities, and pricing.
imagen-4 Stable $0.040 Imagen 4
flower-image Stable $0.040 General-purpose text-to-image
gpt-image-1 Stable $0.040 OpenAI GPT Image 1
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; text-to-image
grok-image Stable alias $0.050 (1K), $0.070 (2K) Backward-compatible alias for grok-imagine-image-quality
gemini-3.1-flash-image Stable $0.067 Gemini 3.1 Flash Image (native). Higher-resolution output (up to 4K), balanced speed/quality. The retired gemini-3.1-flash-image-preview ID remains accepted as a compatibility alias.
gemini-3-pro-image Stable $0.134 Canonical GA Nano Banana Pro ID. Compatibility aliases: gemini-3-pro-image-preview, nano-banana-pro, nana-bana-pro. Highest visual fidelity for edits and 4K.
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).
sora-images Stable $0.040 OpenAI Sora Images (alias gpt-image-1); up to 4 per call via n
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]

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-4 has Fast / Standard / Ultra tiers ($0.02 / $0.04 / $0.06). FLUX.2-pro uses 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. xAI grok-imagine-image costs $0.020 at either 1K or 2K; grok-imagine-image-quality costs $0.050 at 1K and $0.070 at 2K. Pick aspect_ratio / size accordingly.

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
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 gpt-image-2, use opaque or omit. transparent is not supported.
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 outputMimeType or personGeneration is present at the top level or inside imageConfig, 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 HTTP 503 instead of silently dropping the fields or retrying through an incompatible API. Requests for non-Google image models fail with HTTP 400 because their provider routes cannot honor these Google-specific controls.

Requesting 2K / 4K output

All three of these are equivalent:

{"model": "nano-banana-pro", "prompt": "...", "resolution": "4K"}
{"model": "nano-banana-pro", "prompt": "...", "image_size": "4K"}
{
  "model": "nano-banana-pro",
  "prompt": "...",
  "image_config": {"image_size": "4K", "aspect_ratio": "16:9"}
}

Using the OpenAI SDK:

client.images.generate(
    model="nano-banana-pro",
    prompt="...",
    extra_body={"image_size": "4K"},
)

Model support for 2K / 4K:

Model 1K 2K 4K Source
gemini-3-pro-image (nano-banana-pro alias) ai.google.dev
gemini-3.1-flash-lite-image / nano-banana-2-lite ai.google.dev
gemini-3.1-flash-image 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-pro accepts either explicit pixel-shaped size (for example "1024x1024", "2048x2048") or resolution / image_size / quality tiers. quality:"standard" maps to 1K, quality:"hd" maps to 2K, and quality:"ultra" maps to 4K. aspect_ratio is 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. name and mime_type are 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_url fetch timeout is controlled by IMAGE_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 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/checkpoints
  • GET /v1/yesai/flux/samplers
  • GET /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 input returns 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: videovideo_extension, reference_imagesreference_guided, image + last_framefirst_last_frame, imageimage_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.


Text-to-Speech

POST /v1/audio/speech

Single OpenAI-compatible endpoint for TTS. The Gemini model currently supported here is gemini-3.1-flash-tts-preview. 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.
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.1-flash-tts-preview Current API429 Gemini TTS model $1.00 $20 $0.0370 $0.0111 audio/wav

Google API surface matters. gemini-2.5-flash-tts is a model ID for Google's separate Cloud Text-to-Speech API. It is not valid on Gemini generateContent, and API429 does not currently proxy Cloud TTS text:synthesize or text:streamingSynthesize. A 400 INVALID_ARGUMENT from generateContent for that ID is an endpoint/model mismatch, not a missing Cloud API switch on the API429 gateway.

ElevenLabs model

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

* 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.

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 / 1K chars API429 / 1K chars* Output
fish-s2.1-pro Long-form narration, 80+ languages, large public voice library $0.015 $0.0045 audio/mpeg

* The API429 column shows the standard 70% client discount. A per-client billing profile may override the discount shown here.

Pass a Fish voice id (the 32-character hex id of a voice) in the standard voice field. Omit it, or pass a name the provider does not recognize, and a default voice is used. Voices carry their own language tags, and many are multilingual — one voice often covers several languages, so you rarely need a separate voice per market.

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/daily for 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.",
    "response_format": "wav"
  }' \
  --output speech.wav

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 billed

Russian / 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_format field. All Gemini TTS calls return audio/wav regardless of what response_format you pass. The OpenAI SDK exposes response_format for compatibility, but the upstream doesn't honour mp3/opus/aac/flac/pcm — you'll always get the same 24 kHz mono PCM-16 WAV body. Convert with ffmpeg client-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

gemini-3.1-flash-tts-preview supports all 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:

  1. Honour Retry-After when the server sets it (429 / 503 always do). That value reflects current capacity — beating it just queues you server-side without speedup.
  2. Exponential backoff with jitter for transient 5xx without Retry-After. Recommended schedule: 2 s → 8 s → 30 s (max 3 attempts, ±20 % jitter).
  3. 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:

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

  1. Split at sentence boundaries so prosody isn't broken mid-phrase.
  2. Bin-pack chunks around 3 500 bytes UTF-8 (leaving head-room for style prefixes, transcript tags, and retries).
  3. 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 wave stdlib — read all WAVs, write one combined file. Zero external dependencies.
  • ffmpegffmpeg -f concat -safe 0 -i list.txt -c copy out.wav with list.txt listing 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_one in a for 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/daily aggregates 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: error arrives 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-After when 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:true for interactive UX or X-Async-Jobs-Optin: true for 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"
  }
}

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 429 or 503. 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 504 past the internal timeout; retry with the same prompt.
  • Per-client quotas, if configured, are enforced via HTTP 403 with 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).