Image, video, speech and 3D by API
101 media models on the same key as the chat models: 46 image, 44 video, 6 speech and music, 5 3D. Priced per image, per second or per clip; failed generations are refunded.
Two ways in. The image models answer OpenAI's image API, so the OpenAI SDK's images.generate works unchanged with the base URL set to https://api.relayswitch.io/v1. Every media model, images included, also answers one generations endpoint: submit, get a generation id and the charge, poll until it succeeds, download the file. Prices below are read live; the full list with every tier is on the media models page.
01Images: OpenAI's image API
from openai import OpenAI client = OpenAI(base_url="https://api.relayswitch.io/v1", api_key="YOUR_RELAYSWITCH_KEY")result = client.images.generate( model="nano-banana-2", prompt="A red paper boat on a calm blue pond, morning light", size="1536x1024",)print(result.data[0].url)The size maps to the model's aspect ratio and resolution; the price for the resolution you get is the tier in the table. The answer carries the file URL, served for 30 days.
02Everything: the generations endpoint
Submit:
curl https://api.relayswitch.io/v1/generations \ -H "Authorization: Bearer YOUR_RELAYSWITCH_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "veo-3.1-fast", "input": { "prompt": "A paper boat drifting across a pond at sunrise", "resolution": "1080p", "aspect_ratio": "16:9" } }'The answer is 202 with the generation and its charge, set before the clip renders:
{ "id": "gen_4f1c9a…", "object": "generation", "model": "veo-3.1-fast", "kind": "video", "status": "queued", "outputs": [], "charge": { "amount_usd": "0.5760", "units": 1, "unit": "generation", "refunded": false }}Poll until the status is succeeded or failed:
curl https://api.relayswitch.io/v1/generations/gen_4f1c9a… \ -H "Authorization: Bearer YOUR_RELAYSWITCH_KEY"{ "id": "gen_4f1c9a…", "status": "succeeded", "outputs": [ { "url": "https://api.relayswitch.io/v1/files/2026-10-26/gen_4f1c9a…/0.mp4", "content_type": "video/mp4", "bytes": 4810213 } ], "charge": { "amount_usd": "0.5760", "units": 1, "unit": "generation", "refunded": false }}Speech is the same call with text and a voice in the input:
curl https://api.relayswitch.io/v1/generations \ -H "Authorization: Bearer YOUR_RELAYSWITCH_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "elevenlabs-v3", "input": { "text": "Your order has shipped.", "voice": "Aria" } }'03A whole run in Python
import os, time, requests BASE = "https://api.relayswitch.io/v1"HEADERS = {"Authorization": f"Bearer {os.environ['RELAYSWITCH_KEY']}"} gen = requests.post( f"{BASE}/generations", headers=HEADERS, json={ "model": "veo-3.1-lite", "input": { "prompt": "A paper boat drifting across a pond at sunrise", "resolution": "720p", "aspect_ratio": "16:9", }, }, timeout=30,).json()print(gen["id"], "charged", gen["charge"]["amount_usd"]) # the price is set here, before the clip exists while gen["status"] not in ("succeeded", "failed"): time.sleep(5) gen = requests.get(f"{BASE}/generations/{gen['id']}", headers=HEADERS, timeout=30).json() if gen["status"] == "succeeded": url = gen["outputs"][0]["url"] # served from https://api.relayswitch.io/v1/files for 30 days with open("clip.mp4", "wb") as f: f.write(requests.get(url, headers=HEADERS, timeout=120).content)else: print("failed and refunded:", gen["charge"]["refunded"])04Image prices
| Model | Setting | Per image | Developer list |
|---|---|---|---|
| Nano Banana 2 | resolution 1K | $0.0402 | $0.067 (40% under) |
| Nano Banana 2 | resolution 2K | $0.0606 | $0.101 (40% under) |
| Nano Banana 2 | resolution 4K | $0.0906 | $0.151 (40% under) |
| Nano Banana Pro | resolution 1K | $0.0804 | $0.134 (40% under) |
| Nano Banana Pro | resolution 2K | $0.0804 | $0.134 (40% under) |
| Nano Banana Pro | resolution 4K | $0.144 | $0.24 (40% under) |
| GPT Image 2 | quality low, resolution 1K | $0.024 | — |
| GPT Image 2 | quality low, resolution 2K | $0.036 | — |
| GPT Image 2 | quality low, resolution 4K | $0.066 | — |
| Seedream 5.0 Pro | resolution 1K | $0.0938 | $0.045 |
| Seedream 5.0 Pro | resolution 2K | $0.0938 | $0.09 |
| FLUX.2 Pro | resolution 1K | $0.0563 | — |
| FLUX.2 Pro | resolution 2K | $0.0563 | $0.075 (24% under) |
| Qwen Image 3 | resolution 1K | $0.03 | — |
| Qwen Image 3 | resolution 2K | $0.045 | — |
| Qwen Image 3 Uncensored | any settings | $0.08 | — |
Up to three tiers per model shown; the media models page has every tier.
05Video prices
| Model | Setting | Unit | Price | Per second | Developer list |
|---|---|---|---|---|---|
| Veo 3.1 Fast | 720p, 8 s | per generation | $0.48 | $0.06 | $0.80 (40% under) |
| Veo 3.1 Fast | 1080p, 8 s | per generation | $0.576 | $0.072 | $0.96 (40% under) |
| Veo 3.1 | 1080p, 8 s | per generation | $1.92 | $0.24 | $3.20 (40% under) |
| Veo 3.1 Lite | 720p, 8 s | per generation | $0.24 | $0.03 | $0.40 (40% under) |
| Kling 3.0 Pro | without sound | per second | $0.2438 | $0.2438 | — |
| Seedance 2 | 720p | per second | $0.25 | $0.25 | — |
| Wan 3.0 Text to Video | 720p | per second | $0.40 | $0.40 | — |
| Wan 3.0 Video Uncensored | 720p | per second | $0.40 | $0.40 | — |
| Grok Imagine Video | 6 s | per generation | $0.2093 | $0.0349 | $0.30 (30% under) |
Veo 3.1 clips are 8 seconds; per-second is the clip price over 8. Per-second models bill the length you ask for.
06Speech, music and 3D
| Model | Kind | Unit | From |
|---|---|---|---|
| Eleven v3 (text to speech) | Speech and music | per 1,000 characters | $0.10 |
| Eleven Turbo v2.5 (text to speech) | Speech and music | per 1,000 characters | $0.05 |
| Suno Music | Speech and music | per generation | $0.40 |
| Tripo H3.1 Text to 3D | 3D | per generation | $0.0938 |
| Tripo H3.1 Image to 3D | 3D | per generation | $0.1875 |
Questions
- When is a generation charged?
- When the request is accepted, before the file exists: the submit answer carries charge.amount_usd. A generation that fails is refunded in full and the record says refunded: true.
- Which models answer the OpenAI images API?
- The image models answer https://api.relayswitch.io/v1/images/generations with the OpenAI SDK's images.generate; the size maps to the model's aspect ratio and resolution settings. Every model, image models included, also answers POST https://api.relayswitch.io/v1/generations with its own input fields.
- How do I know which input fields a model takes?
- GET https://api.relayswitch.io/v1/catalog/media lists every media model with its params: the field names, their allowed values and defaults, and the price for each combination. No key needed.
- How long are outputs kept?
- Finished files are served from the API for 30 days under the generation id, with your key. Download what you want to keep.
Images, video and every chat model on one key
Prepaid from $10. Card or crypto, no KYC.