Calling via API (Images / Video)
Standard OpenAI-style endpoints, authenticated by token. Images return base64 synchronously; video is an asynchronous task (create → poll → download).
Token Group
The token must belong to the media / media-gen group, otherwise you'll get a "No available channel" error. See Choosing a Group.
Images · Text-to-Image
POST https://byesu.com/v1/images/generations
Authorization: Bearer sk-your-token
Content-Type: application/json| Field | Required | Description |
|---|---|---|
model | ✅ | Model name, see Image Generation |
prompt | ✅ | Prompt |
size | Width x height in pixels — determines both the aspect ratio and the resolution tier: long side ≈1024 → 1K, ≈2048 → 2K, ≈3840 → 4K. E.g. "1024x1024" (1:1 · 1K), "2048x1152" (16:9 · 2K), "3840x3840" (1:1 · 4K). Defaults to 1:1 at the base tier if omitted |
curl https://byesu.com/v1/images/generations \
-H "Authorization: Bearer sk-your-token" \
-H "Content-Type: application/json" \
-d '{
"model": "nano-banana-2",
"prompt": "A golden retriever running through a golden wheat field at dusk, cinematic",
"size": "2048x1152"
}'Response (the image is a base64-encoded PNG):
{ "data": [ { "b64_json": "<base64 string>" } ] }Images · Image-to-Image (Reference Images)
Use POST /v1/images/edits with multipart/form-data; reference images are uploaded as files (field name image, repeatable for multiple images, each ≤8MB; the maximum count varies by model, see Image Generation):
curl https://byesu.com/v1/images/edits \
-H "Authorization: Bearer sk-your-token" \
-F model="nano-banana-2" \
-F prompt="Turn this photo into a watercolor painting" \
-F size="1024x1024" \
-F image=@ref1.png \
-F image=@ref2.pngThe response format is the same as text-to-image.
Video (Asynchronous, Sora-Style)
Three steps: create a task → poll its status → download the mp4.
import requests, time
BASE = "https://byesu.com"
H = {"Authorization": "Bearer sk-your-token"}
# 1. Create the task
task = requests.post(f"{BASE}/v1/videos", headers=H, json={
"model": "gemini-veo31",
"prompt": "Waves crashing against rocks, slow motion, cinematic",
"seconds": "6", # duration in seconds; available values vary by model
"size": "1280x720", # aspect ratio expressed as a size; 1920x1080 = 1080p (some models only)
}).json()
# 2. Poll until it finishes (tens of seconds to a few minutes)
while task["status"] not in ("completed", "failed"):
time.sleep(5)
task = requests.get(f"{BASE}/v1/videos/{task['id']}", headers=H).json()
# 3. Download the mp4
if task["status"] == "completed":
mp4 = requests.get(f"{BASE}/v1/videos/{task['id']}/content", headers=H)
open("out.mp4", "wb").write(mp4.content)Image-to-video: create the task with multipart/form-data instead, putting the first-frame image in the input_reference file field (pass model / prompt / seconds / size along as form fields). runway-gen4-turbo requires a first-frame image.
Videos Are Billed Per Second
Video price = per-second unit price × seconds. Failed tasks are automatically refunded.
Errors
- "No available channel" → the token's group is wrong, see Choosing a Group
too many reference images→ you exceeded that model's reference-image limit- 401 / insufficient balance / others → see Common Errors & Solutions
