Access top image generation models through a unified API -- text-to-image, image editing, mask inpainting, and multi-image fusion.
Add Authorization header to all requests:
Authorization: Bearer YOUR_API_KEY
/api/v1/images/generationsCreate an image generation task
/api/v1/images/generations?task_id=xxxQuery task status and get image URL
Select a provider to see its parameters and examples
ByteDance's Doubao Seedream series. Multiple model tiers with text-to-image, image editing, and multi-image fusion capabilities.
doubao-seedream-5-0-260128doubao-seedream-4-5-251128# 5.0 Lite official channel: same endpoint for T2I and I2I.
# Provide image_url for image-to-image; omit it for text-to-image.
# size: "2K" (default) or "4K" — aspect_ratio is ignored by 5.0 Lite.
# Step 1a: Text-to-image
curl -X POST https://apimodels.app/api/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedream-5-0-260128",
"prompt": "A cherry blossom tree by a tranquil river, impressionist painting style",
"size": "2K"
}'
# Step 1b: Image-to-image (same endpoint, just add image_url)
curl -X POST https://apimodels.app/api/v1/images/generations \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "doubao-seedream-5-0-260128",
"prompt": "Change the season to winter with snow",
"image_url": "https://example.com/landscape.jpg",
"size": "4K"
}'
# Step 2: Poll status
curl "https://apimodels.app/api/v1/images/generations?task_id=TASK_ID" \
-H "Authorization: Bearer YOUR_API_KEY"{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "pending"
}
}{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "completed",
"resultUrls": ["https://r2.apimodels.app/images/xxx.jpeg"],
"createTime": 1705123450000,
"completeTime": 1705123465000
}
}{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"state": "failed",
"failMsg": "Content policy violation"
}
}Pass callback_url in the create request. When the task reaches the completed or failed terminal state, our server sends a single HTTP POST to that URL with Content-Type: application/json (no signing header). Delivery is retried up to 3 times (exponential backoff 1s/2s/4s, 10s per attempt); if still unsuccessful, a background job keeps retrying for up to 30 minutes until your endpoint returns 2xx.
POST {your callback_url}
Content-Type: application/json
{
"code": 200,
"msg": "success",
"data": {
"taskId": "clxxx...",
"model": "<provider>/<model_name>",
"state": "completed" | "failed",
"param": "<JSON string>", // request params, JSON.parse once
"resultJson": "<JSON string> | null", // result object, JSON.parse once
"failCode": null | "string",
"failMsg": null | "string",
"costTime": 12345, // duration in ms
"completeTime": 1705123465000, // ms epoch
"createTime": 1705123450000 // ms epoch
}
}Note: data.param and data.resultJson are both JSON strings — call JSON.parse once on each to get the underlying object.
{
"resultUrls": [
"https://r2.apimodels.app/images/xxx.png"
]
}resultUrls is an array of Cloudflare R2-hosted image URLs. Multi-image models (SparkPix Image Edit, GPT Image 2 Lite with n>1) return more than one. When state=failed, resultJson is typically null or {"resultUrls":[]} — do not assume a link is present.
app.post('/webhook/image', express.json(), (req, res) => {
const { taskId, state, param, resultJson, failMsg } = req.body.data
if (state === 'completed') {
const { resultUrls } = JSON.parse(resultJson)
console.log('image ready', taskId, resultUrls[0])
} else {
console.warn('image failed', taskId, failMsg)
}
res.status(200).end() // must be 2xx, otherwise we retry
})pendingQueued, waiting to startprocessingImage is being generatedcompletedDone -- image URLs availablefailedGeneration failed400Bad Request -- invalid or missing parameters401Unauthorized -- invalid API key402Payment Required -- insufficient credits404Not Found -- task ID not found500Internal Server Error