Image API Quickstart
Generate and edit images
A beginner-friendly guide to creating an image task, checking its status, retrieving the result and editing an existing image.
curl https://api.seedanceapi.app/v1/images/generations \ -X POST \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "nano-banana-2-lite", "prompt": "A premium white ceramic coffee mug on a light wooden table, soft morning window light, realistic product photography, no text", "aspect_ratio": "1:1", "image_size": "1K", "response_format": "url"}'img_01k2abc123example{ "id": "img_01k2abc123example", "object": "image.generation", "model": "nano-banana-2-lite", "operation": "generation", "status": "queued", "credits": { "charged": 20, "refund_status": "none" }, "created_at": 1786900000, "updated_at": 1786900000}When the task succeeds, read result.images[0].url to get your image.
Before you run the first request
You only need an account with credits, an API key and a terminal. The examples use an environment variable so the key is not copied into source code.
- Create an account, add credits and create an API key in the Dashboard.
- Open Terminal on macOS or Linux, or PowerShell on Windows.
- Replace
sk_live_xxxbelow with the key you copied.
export SEEDANCE_API_KEY="sk_live_xxx"$env:SEEDANCE_API_KEY = "sk_live_xxx"From task ID to image URL
HTTP 202 means the task was accepted, not that the image is ready. Copy the returned img_* ID and call the task endpoint with the same API key. While the status is queued orrunning, wait about three seconds and try the GET request again.
curl https://api.seedanceapi.app/v1/images/img_01k2abc123example \ -H "Authorization: Bearer $SEEDANCE_API_KEY"Stop polling when the task reaches a final state. A successful task puts every generated image inside result.images.
{ "id": "img_01k2abc123example", "object": "image.generation", "model": "nano-banana-2-lite", "operation": "generation", "status": "succeeded", "result": { "images": [ { "url": "https://cdn.example.com/generated/coffee-mug.png" } ] }, "credits": { "charged": 20, "refund_status": "none" }, "created_at": 1786900000, "updated_at": 1786900042, "completed_at": 1786900042}curl -L "https://cdn.example.com/generated/coffee-mug.png" -o coffee-mug.pngEditing an existing image
Switch the interactive example above to Edit an image. A useful edit prompt names both what must stay the same and what should change—for example, keep the product unchanged but replace the background and lighting.
Choose the correct size fields
Nano Banana and GPT Image use different size parameters. Mixing them is one of the most common first-request errors.
| Model family | Use these fields | Do not send |
|---|---|---|
| Nano Banana | aspect_ratio and image_size | size |
gpt-image-2-vip | size, such as 1024x1024 | aspect_ratio and image_size |
gpt-image-2-text-to-image, gpt-image-2-image-to-image | aspect_ratio and image_size; optional background | size |
curl https://api.seedanceapi.app/v1/images/generations \ -X POST \ -H "Authorization: Bearer $SEEDANCE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "gpt-image-2-vip", "prompt": "A friendly watercolor illustration of a small bookstore in spring", "size": "1024x1024", "response_format": "url" }'gpt-image-2-text-to-image uses /v1/images/generations.gpt-image-2-image-to-image uses /v1/images/edits and requires 1–16 public HTTPS URLs in image_urls. Both default to image_size: 1K and aspect_ratio: auto. At 2K and 4K, ratios 5:4, 4:5, 3:1, 1:3 and 9:21 are unavailable. Background supports auto, opaque or transparent. Each task costs 40 credits at 1K, 60 at 2K or 90 at 4K.
{ "model": "gpt-image-2-text-to-image", "prompt": "A ceramic mug on a transparent background", "image_size": "2K", "aspect_ratio": "1:1", "background": "transparent"}Model-specific resolutions and current credit costs are listed in the image model table.
Complete JavaScript example
This dependency-free script works with Node.js 18 or newer. Save it asgenerate-image.mjs; it creates a task, polls every three seconds and prints the final image URL.
const API_BASE_URL = "https://api.seedanceapi.app";const API_KEY = process.env.SEEDANCE_API_KEY; if (!API_KEY) { throw new Error("Set SEEDANCE_API_KEY before running this script.");} async function readJson(response) { const body = await response.json(); if (!response.ok) throw new Error(JSON.stringify(body, null, 2)); return body;} // 1. Submit the generation request.const createResponse = await fetch(API_BASE_URL + "/v1/images/generations", { method: "POST", headers: { Authorization: "Bearer " + API_KEY, "Content-Type": "application/json", }, body: JSON.stringify({ model: "nano-banana-2-lite", prompt: "A premium white ceramic coffee mug on a light wooden table, soft morning window light, realistic product photography, no text", aspect_ratio: "1:1", image_size: "1K", response_format: "url", }),}); let task = await readJson(createResponse);console.log("Task created:", task.id); // 2. Poll every 3 seconds until the task reaches a final state.while (task.status === "queued" || task.status === "running") { await new Promise((resolve) => setTimeout(resolve, 3000)); const pollResponse = await fetch(API_BASE_URL + "/v1/images/" + task.id, { headers: { Authorization: "Bearer " + API_KEY }, }); task = await readJson(pollResponse); console.log("Current status:", task.status);} // 3. Read the image URL, or show the task-level failure.if (task.status === "succeeded") { console.log("Image URL:", task.result.images[0].url);} else { console.error("Generation did not succeed:", task.error ?? task.status); process.exitCode = 1;}node generate-image.mjsCommon first-request problems
| What you see | What it means | What to do |
|---|---|---|
401 invalid_api_key | The key is missing, mistyped or revoked. | Reset the environment variable and keep the Bearer prefix. |
402 insufficient_credits | The account cannot reserve this model's cost. | Add credits or choose a lower-cost model. |
400 unsupported_parameter | A field does not belong to this model family or endpoint. | Check the size-field table above and remove unknown fields. |
400 invalid_request for image_urls | The edit URL is not public HTTPS or more than 16 URLs were sent. | Use a direct, publicly reachable HTTPS URL. |
404 task_not_found | The task ID is wrong or a different API key created it. | Copy the full img_* ID and use the original key. |
429 rate_limited | Requests are being sent too quickly. | Wait for the Retry-After delay, then retry. |
502 or 503 with retryable: true | The generation service or network is temporarily unavailable. | Retry GET polling after a delay. Before repeating a POST, inspect the Dashboard log to avoid duplicate work. |
See Error codes and troubleshooting for the complete response envelope and retry rules.