ByteDance
Seedream 4.0
ByteDance's image generation and editing model. One model covers both text-to-image and instruction-based editing, with output up to 4K. Available as a hosted endpoint; weights are not publicly released.
Capabilities
Characteristics reported by ByteDance. Treat them as vendor claims rather than independent measurements.
Generation and editing in one model
The same checkpoint handles text-to-image and instruction-driven editing, so a generate-then-refine loop stays within one model.
High-resolution output
Native output up to 4K without a separate upscaling pass.
Reference-guided consistency
Accepts reference images to keep a subject or style stable across a set of generations โ the basis for batch and series work.
Text rendering
Handles typography inside the image, including Chinese, which most image models still degrade to unreadable glyphs.
Endpoints
| Endpoint | Task |
|---|---|
bytedance/seedream-v4 | Text-to-image |
bytedance/seedream-v4/edit | Instruction-based editing |
bytedance/seedream-v4.5 | Updated 4.5 checkpoint |
Run it
Use bytedance/seedream-v4/edit with an additional images array to edit rather than generate.
# 1. submit the job
curl -X POST "https://api.wavespeed.ai/api/v3/bytedance/seedream-v4" \
-H "Authorization: Bearer $WAVESPEED_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"prompt": "An architectural photograph of a concrete stairwell, hard afternoon light, 35mm",
"size": "2048*2048",
"enable_base64_output": false,
"enable_sync_mode": false
}'
# -> {"code": 200, "data": {"id": "<request-id>", "status": "created", ...}}
# 2. poll until status is "completed"
curl "https://api.wavespeed.ai/api/v3/predictions/<request-id>/result" \
-H "Authorization: Bearer $WAVESPEED_API_KEY"
# -> {"code": 200, "data": {"status": "completed", "outputs": ["https://..."]}}
import os, time, requests
API = "https://api.wavespeed.ai/api/v3"
KEY = os.environ["WAVESPEED_API_KEY"]
HEADERS = {"Authorization": f"Bearer {KEY}"}
# submit
res = requests.post(
f"{API}/bytedance/seedream-v4",
headers={**HEADERS, "Content-Type": "application/json"},
json={
"prompt": "An architectural photograph of a concrete stairwell, hard afternoon light, 35mm",
"size": "2048*2048",
"enable_base64_output": false,
"enable_sync_mode": false
},
timeout=30,
)
res.raise_for_status()
request_id = res.json()["data"]["id"]
# poll
while True:
data = requests.get(
f"{API}/predictions/{request_id}/result",
headers=HEADERS,
timeout=30,
).json()["data"]
if data["status"] == "completed":
print(data["outputs"][0])
break
if data["status"] == "failed":
raise RuntimeError(data.get("error", "generation failed"))
time.sleep(1.5)
const API = "https://api.wavespeed.ai/api/v3";
const KEY = process.env.WAVESPEED_API_KEY;
const headers = { Authorization: `Bearer ${KEY}` };
// submit
const submit = await fetch(`${API}/bytedance/seedream-v4`, {
method: "POST",
headers: { ...headers, "Content-Type": "application/json" },
body: JSON.stringify({
"prompt": "An architectural photograph of a concrete stairwell, hard afternoon light, 35mm",
"size": "2048*2048",
"enable_base64_output": false,
"enable_sync_mode": false
}),
});
const { data: { id } } = await submit.json();
// poll
for (;;) {
const res = await fetch(`${API}/predictions/${id}/result`, { headers });
const { data } = await res.json();
if (data.status === "completed") {
console.log(data.outputs[0]);
break;
}
if (data.status === "failed") throw new Error(data.error ?? "generation failed");
await new Promise((r) => setTimeout(r, 1500));
}
Requests are asynchronous: POST returns a request id, then you poll /predictions/<id>/result until status is completed. Set enable_sync_mode: true to have the call block and return outputs directly.
API keys are created in the WaveSpeed dashboard.