GPT Image Retrieve Task (Ace Data Cloud)
Your Paid Job Didn't Die, You Just Stopped Looking
- status
- task_id
- media_urls_json
- first_media_url
- result_json
- trace_id
The generate and edit nodes submit asynchronously, so the normal outcome of a run is pending and a task_id - not a picture. This node is how you turn that task ID into an image. It's also the single most important node in the pack when something goes wrong, because it's the difference between fetching a job you already paid for and paying for it twice.
What it's for
Two jobs, and the second one is underrated. The everyday one is polling: submit, then retrieve, then feed the URL into GPT Image Load Image. The urgent one is recovery. A submission that dies on a dropped connection is never retried by the client - deliberately, because a retry after an accepted request could bill you twice. The task itself almost certainly still exists on the service. Look it up instead of resubmitting. Keep the task_id you got back (it's the task_id output, and it's also inside result_json); it is the durable handle for the job, unlike the CDN URL.
How it behaves
Two inputs it needs: task_id is the one you set - paste it, or convert the widget to an input and wire the task_id output of a generate or edit node straight in. There's also a trace_id widget if you're holding a trace instead of a task ID; the lookup accepts either. With neither, it stops immediately with a clear "A task ID or supported trace ID is required."
Then wait_seconds, an integer from 0 to 240, and this is the node's whole personality. At 0 it asks once and returns whatever the service says right now. Above 0 it polls the task endpoint, checking every five seconds or so until the task leaves pending or the clock runs out, and it returns pending if you hit the limit. So 240 is the longest ComfyUI will sit blocked on this node - and blocked is the correct word: the queue is waiting on it, which is the price of doing a retry loop inside a graph instead of in your head. parameters_json exists too, but in practice you won't use it here.
Those polls are read-only queries, which is why the client is allowed to retry them three times on a network blip. Nothing about looking up a task should create a new charged job.
A failed task raises an exception rather than returning a failed status: you get "Task failed. Use its task or trace ID to inspect the service request," which is the package scrubbing upstream internals on purpose. When it does work, the six outputs are status (pending, succeeded, or partial), task_id, media_urls_json, first_media_url, result_json and trace_id. Point first_media_url at the IMAGE loader; if the service returned several images, parse media_urls_json. Nothing beats a PreviewAny on result_json the first few times you run this, because it shows you exactly what the service thinks it made.
A concrete loop
The pack ships this as an example - examples/01-configure-and-run.json, load it with File → Open. It's a two-node graph: this node wired into a PreviewAny, with a placeholder task ID (and the README is clear it submits nothing paid by itself). Set wait_seconds to something like 60, paste your ID, run. If you get pending back, don't conclude anything broke; query the same ID again. When status reads succeeded, the URLs are in the media_urls_json output, and that's the moment to switch to the loader.
Install
No separate install - it's part of the pack. Manager: search GPT Image, publisher acedatacloud, package GPT Image by Ace Data Cloud. Or:
cd ComfyUI/custom_nodes
git clone https://github.com/AceDataCloud/GPTImageComfyUI
python -m pip install -r GPTImageComfyUI/requirements.txt
Both dependencies are requests and jsonschema, so there's very little to go wrong. The key goes in the environment of the ComfyUI process - ACEDATACLOUD_API_KEY, or ACEDATACLOUD_API_TOKEN, followed by a restart - even though this node only reads. The client still needs a credential to talk to the API.
Where people trip
Setting wait_seconds to 240 and then wondering why the whole queue feels frozen: that's four minutes of a blocked worker per node, and if you have a few of these in one workflow they add up. Poll at 0 or a short interval and re-queue, or accept the wait for a single job.
The other one is treating a stale task ID as an error. If you submitted something a while ago and never looked, the task is probably still retrievable; run it before you spend credits re-generating the same prompt. And if a retrieve seems to be showing you the wrong job, check you didn't wire a trace_id widget alongside a task_id - supply one handle, not both.
Inputs (4)
| Name | Type | Default | Description |
|---|---|---|---|
| parameters_json | STRING | {} | — |
| trace_id | STRING | — | |
| task_id | STRING | — | |
| wait_seconds | INT | 00–240 | — |
Outputs (6)
| Name | Type | Description |
|---|---|---|
| status | STRING | — |
| task_id | STRING | — |
| media_urls_json | STRING | — |
| first_media_url | STRING | — |
| result_json | STRING | — |
| trace_id | STRING | — |