DEV Community

Cover image for How to Build an Image Generation and Editing Workflow with the Seedream Images API
Germey
Germey

Posted on • Originally published at platform.acedata.cloud

How to Build an Image Generation and Editing Workflow with the Seedream Images API

If you have ever tried to add image generation to a real product, you know the hard part is not only the prompt — it is designing a request shape, handling long-running jobs, and returning a usable image URL to the rest of your app.

In this guide, we will build a practical mental model for using the Seedream Images API through Ace Data Cloud. The goal is simple: send a prompt, optionally pass one or more input images for editing, and receive a generated image result that your backend can store, display, or pass to another workflow.

What you can do

The Seedream Images endpoint is useful when your application needs image generation or image editing from a structured API call. The documented endpoint is:

Base URL: https://api.acedata.cloud
Endpoint: POST /seedream/images
Authorization: Bearer <token>
Content-Type: application/json
Accept: application/json
Enter fullscreen mode Exit fullscreen mode

At the smallest level, a generation request uses action, model, and prompt:

{
  "action": "generate",
  "model": "doubao-seedream-5-0-260128",
  "prompt": "A photorealistic studio product shot of a frosted-glass perfume bottle on wet black slate, single softbox key light, water droplets, dark moody background, 85mm macro."
}
Enter fullscreen mode Exit fullscreen mode

The model string matters. For example, the docs use the complete model name doubao-seedream-5-0-260128; abbreviations such as doubao-seedream-5.0-lite are not accepted.

The same API family also supports richer fields depending on the model you choose: image, size, response_format, watermark, output_format, async, callback_url, and model-specific fields such as seed, guidance_scale, stream, sequential_image_generation, or tools.

Make your first request with curl

Here is the basic curl request I would start with in a backend prototype:

curl -X POST 'https://api.acedata.cloud/seedream/images' \
  -H 'accept: application/json' \
  -H 'authorization: Bearer ${token}' \
  -H 'content-type: application/json' \
  -d '{
    "action": "generate",
    "model": "doubao-seedream-5-0-260128",
    "prompt": "A photorealistic studio product shot of a frosted-glass perfume bottle on wet black slate, single softbox key light, water droplets, dark moody background, 85mm macro."
  }'
Enter fullscreen mode Exit fullscreen mode

A successful response includes a task identifier, a trace identifier, and a data array with the image result:

{
  "success": true,
  "task_id": "81246f86-05ff-4d7d-9553-1013e0c1cd32",
  "trace_id": "ab50a78d-ab1f-457f-a46b-c2259cd5d35b",
  "data": [
    {
      "prompt": "A photorealistic studio product shot of a frosted-glass perfume bottle on wet black slate, single softbox key light, water droplets, dark moody background, 85mm macro.",
      "size": "2048x2048",
      "image_url": "https://platform2.cdn.acedata.cloud/seedream/901c6af6-e83a-4849-b233-295f6c20bacb.jpg"
    }
  ]
}
Enter fullscreen mode Exit fullscreen mode

For an application, the important fields are success, task_id, trace_id, data[].image_url, data[].prompt, and data[].size. I usually persist task_id and trace_id together, because they make debugging much easier when a user reports a missing image.

Choose the right model and size

The docs list several supported model strings, including doubao-seedream-5-0-pro-260628, doubao-seedream-5-0-260128, doubao-seedream-4-5-251128, doubao-seedream-4-0-250828, doubao-seedream-3-0-t2i-250415, and doubao-seededit-3-0-i2i-250628.

Not every field works with every model, so treat the model as part of your API contract. For example, doubao-seedream-5-0-pro-260628 is documented as a flagship single-image model and does not support sequential_image_generation, stream, or tools. The seed field is only supported by doubao-seedream-3-0-t2i-250415.

The size field can be specified in two ways: a preset such as 1K, 2K, 3K, or 4K when the selected model supports presets, or an explicit pixel size such as 2048x2048. Preset support varies by model, so if you are building a UI, it is safer to make the allowed size options depend on the selected model rather than exposing one global dropdown.

Editing an existing image

For image editing, include the image field with the URL or Base64 input image. The documentation says some Seedream models support single or multiple image inputs, while doubao-seededit-3-0-i2i-250628 supports only a single image input and doubao-seedream-3-0-t2i-250415 does not support the image parameter.

A typical edit payload looks like this:

{
  "model": "doubao-seedream-4-0-250828",
  "prompt": "Keep the model pose and the liquid garment flowing shape unchanged. Change the clothing material from silver metal to completely transparent water (or glass). Through the liquid flow, the details of the model skin are visible. The light and shadow effect shifts from reflection to refraction.",
  "image": [
    "https://ark-project.tos-cn-beijing.volces.com/doc_image/seedream4_5_imageToimage.png"
  ],
  "size": "2K",
  "watermark": false
}
Enter fullscreen mode Exit fullscreen mode

This is the pattern I would use for product mockups, image variations, or controlled visual transformations: keep the source image in object storage, pass its URL in image, and make the prompt describe only the intended edit.

Handle long-running jobs cleanly

Image generation can take about one to two minutes. If you do not want a client request to stay open, the API supports asynchronous handling.

There are two documented approaches:

  1. Provide callback_url. The API returns a task_id, then POSTs the final JSON result to your callback URL when the job finishes.
  2. Set async to true without a callback URL. The API returns a task_id, and your application polls /seedream/tasks to fetch the final result.

A simple production pattern is to create an internal image_jobs table with columns like task_id, trace_id, status, prompt, and image_url. Your initial request creates the row. Your callback handler or polling worker updates it when data[].image_url arrives.

Error handling

The docs show errors such as 400 token_mismatched, 400 api_not_implemented, 401 invalid_token, 429 too_many_requests, and 500 api_error. A typical error response includes success: false, an error.code, an error.message, and a trace_id.

In practice, I would map these into three buckets: fix the request, refresh or check credentials, and retry later. Always log trace_id; it is the field you will want when debugging a failed generation.

Where this fits

This is not just a “generate me a picture” endpoint. With prompt, image, model-specific size handling, async execution, callbacks, and traceable task IDs, you can wire Seedream into a real builder workflow: product imagery, internal creative tooling, design previews, or background asset generation.

The full API reference is available in the Ace Data Cloud documentation: Seedream Images API integration guide.

Top comments (0)