How to Track Async Image Generation Jobs with the Seedream Tasks API
Generating an image is only half of the integration. In a real product, you also need to know whether the job finished, how long it took, which prompt produced the result, and where the final image URL lives. This guide
Generating an image is only half of the integration. In a real product, you also need to know whether the job finished, how long it took, which prompt produced the result, and where the final image URL lives.
This guide shows how to build that job-tracking layer with the Seedream Tasks API. The workflow is intentionally simple: start an image generation request elsewhere, save the returned task ID, then query task status until you have a stable result.
What you can do
The Seedream Tasks API is designed to retrieve execution details for tasks created by the Seedream Images Generation API.
The documented task endpoint is:
-
Base URL:
https://api.acedata.cloud -
Endpoint:
POST /seedream/tasks -
Auth header:
authorization: Bearer {token} -
Accept header:
accept: application/json -
Content type:
content-type: application/json
The request body changes depending on whether you are looking up one task or multiple tasks:
- Single task:
idplusaction: "retrieve" - Batch lookup:
idsplusaction: "retrieve_batch"
That makes the API a good fit for backend queues, admin dashboards, cron-based polling, or any UI where users can return later and see whether their generated image is ready.
Store the task ID first
When your image-generation call returns, persist the task ID immediately. The Seedream image response documented by Ace Data Cloud includes fields such as success, task_id, trace_id, and data. The task API uses that task ID as the lookup key.
A minimal table for your own app might look like this:
image_jobs
- id
- provider_task_id
- trace_id
- prompt
- status
- output_image_url
- created_at
- finished_at
- elapsed
The exact database does not matter. What matters is that provider_task_id stores the value you will later send as id to /seedream/tasks.
Retrieve one task
For a single job detail page, query one task by ID. The request body contains the task id and an action value of retrieve.
curl -X POST 'https://api.acedata.cloud/seedream/tasks' \
-H 'accept: application/json' \
-H 'authorization: Bearer {token}' \
-H 'content-type: application/json' \
-d '{
"id": "a6e0d456-189b-4c78-9232-2fe72166ab39",
"action": "retrieve"
}'
A successful response can include the generated result directly:
{
"success": true,
"task_id": "84d1544a-9043-4dde-a98b-e889dacd75f6",
"trace_id": "176acf03-7ca7-4fc6-85db-e3724d4f59eb",
"data": [
{
"prompt": "a white siamese cat",
"size": "2048x2048",
"image_url": "https://platform.cdn.acedata.cloud/seedream/6e5f9085-cc4a-4801-b77b-31550129ff19.jpg"
}
]
}
For a user-facing UI, the important field is data[].image_url. Once that is present, you can mark your local job as complete and render the image. Keep trace_id too; it is useful when debugging a failed or unexpected task.
Retrieve many tasks at once
Single-task polling is fine for a detail page. For an admin dashboard or worker process, batch retrieval is more efficient. The body uses ids and action: "retrieve_batch".
{
"ids": [
"84d1544a-9043-4dde-a98b-e889dacd75f6",
"84d1544a-9043-4dde-a98b-e889dacd75f6"
],
"action": "retrieve_batch"
}
The documented batch response contains an items array and a count. Each item includes task metadata such as id, api_id, application_id, created_at, started_at, finished_at, elapsed, credential_id, request, trace_id, type, user_id, and response.
That structure is useful because you can update local records in one pass:
for item in response.items:
job = find_job_by_provider_task_id(item.id)
job.trace_id = item.trace_id
job.started_at = item.started_at
if item.finished_at exists:
job.finished_at = item.finished_at
job.elapsed = item.elapsed
job.status = "finished"
job.output_image_url = item.response.data[0].image_url
The documentation notes that finished_at and elapsed are not returned if the task is not complete. That is a clean signal for your polling loop: if finished_at is missing, leave the job in a running state and check again later.
A practical polling loop
A basic backend loop can be conservative:
- Insert a local job before or immediately after creating the image task.
- Save the returned
task_idasprovider_task_id. - Poll
/seedream/taskswithaction: "retrieve"for one item, orretrieve_batchfor many pending jobs. - If
finished_atexists, copyelapsedandresponse.data[0].image_urlinto your database. - If an error comes back, store the
error.code,error.message, andtrace_id.
The task API is especially helpful when you do not want to expose provider-specific details to your frontend. Your frontend can call your own /jobs/:id endpoint, while your backend handles the Ace Data Cloud task lookup.
Error handling
The documented error examples include:
400 token_mismatched400 api_not_implemented401 invalid_token429 too_many_requests500 api_error
A failed response follows this shape:
{
"success": false,
"error": {
"code": "api_error",
"message": "fetch failed"
},
"trace_id": "2cf86e86-22a4-46e1-ac2f-032c0f2a4e89"
}
In practice, handle these as job states rather than raw exceptions. A 401 means the integration needs configuration. A 429 should trigger backoff. A 500 should be stored with the trace ID so the job can be retried or inspected.
Where this fits in an app
This pattern works well for tools where users do not expect instant completion: image editors, CMS media libraries, ecommerce asset tools, internal creative review systems, or batch generation scripts.
The main idea is to separate creation from retrieval. The image generation endpoint starts the work; the task endpoint gives your application a reliable way to observe it.
For the complete field reference and examples, see the source document: Seedream Tasks API integration guide.
Originally published by Dev.to AI. Aggregated on AIWithGhost for educational purposes โ full credit and traffic to the original publisher.