Genace

n8n image generation: submit once and recover a known job

·

For n8n image generation, connect to Genace through ordinary HTTP Request nodes. This is a custom workflow pattern, not a dedicated Genace node or an importable workflow template. Keep submission and observation separate so an operator can see which action creates work and which action only checks a known job.

1. Start with one deliberate input item

Use a Manual Trigger while developing and create one item containing a prompt. If an upstream node emits ten items, a downstream submission node may create ten generation jobs. Confirm the item count before enabling any scheduled or event trigger.

Store the Authorization header in an n8n credential using the credential type supported by your installation. Its value should be Bearer followed by your API key. Do not place the raw secret inside a JSON body, a Set node, or workflow notes that may be exported.

2. Configure the submission node

Create an HTTP Request node named Submit image. Use POST and the URL https://genace.ai/api/v1/images/generations. Send JSON with Content-Type: application/json and select the stored authentication credential. For the initial run, use this fixed body rather than mixing expression syntax with prompt text:

{
  "model": "nano-banana",
  "prompt": "A warm editorial photograph of a book beside a window",
  "aspect_ratio": "4:3",
  "n": 1
}

Leave automatic retry and pagination disabled on this POST. A repeated request can create a second job rather than resume the first. Configure these response options on Submit image:

OptionSetting and reason
Response FormatJSON, so the next node can inspect fields
Include Response Headers and StatusOn, retaining the HTTP status beside the response body
Never ErrorOn, so a non-2xx HTTP response can enter your explicit error branch

With this configuration, inspect $json.statusCode and $json.body, not a top-level $json.job_id. Never Error changes n8n’s node handling; it does not mean Genace accepted or completed the generation. Verify the returned envelope on your installed n8n version before enabling triggers.

3. Separate accepted, rejected, and uncertain submissions

Only route HTTP 202 with a nonempty body.job_id into normal observation. In a field-editing node on that branch, save generation_job_id using:

{{ $json.body.job_id }}

For a JSON error response, the local identifier is nested instead:

{{ $json.body.error.job_id }}

Read that expression only on an error branch after checking the body has an error object. Save the identifier and error code in your durable operation record before any recovery action.

Submission outcomeAction
202 with a local job IDStart observation of that ID; generation is not yet complete
502, UPSTREAM_SUBMISSION_FAILEDInspect the known failed job for credit reconciliation; do not automatically create another job
502, UPSTREAM_SUBMISSION_UNCERTAINPreserve the ID and held credits for reconciliation; do not resubmit or attempt cancellation to obtain a refund
Transport failure, invalid JSON, or a missing IDStop the submission path, retain execution context, and investigate acceptance before a deliberate retry

An unknown submission can still have been accepted upstream. A later GET is observation of the local record, not proof that upstream rejected the request. Unknown or missing-handle nonterminal cancellation returns 409 SUBMISSION_RECONCILIATION_REQUIRED; it is not a shortcut to release credits. Use the uncertain submission reference for this distinction.

4. Preserve identity before the status node

Add a field-editing node that retains job_id under your own field such as generation_job_id, plus an observation counter and a deadline. A status response uses id, so allowing each HTTP response to replace the entire item can lose the original field name and break the next iteration.

Configure another HTTP Request node for GET with this URL expression when its incoming item includes that saved field:

{{ 'https://genace.ai/api/v1/jobs/' +
   encodeURIComponent($json.generation_job_id) + '?wait=30' }}

Use the same stored credential and a client timeout longer than the wait window. The status instructions below assume this GET node returns only the JSON body, unlike the full-response submission node. Route non-2xx GET responses to an observation error path rather than the state switch. Configure response handling or a merge step so saved identity and observation metadata remain available after each GET; node output does not necessarily preserve input fields.

5. Branch on state and bound the loop

Use explicit branches for succeeded, failed, and canceled. Route both queued and running into one waiting branch; there is no API state named pending. A boolean condition for the waiting branch is:

{{ ['queued', 'running'].includes($json.state) }}

In that branch, check the saved deadline or maximum attempt count, then use a Wait node with a time interval before returning to the status node. Stop and investigate any unrecognized state instead of silently waiting forever. Never connect any observation branch back to Submit image.

On success, inspect the output list and select items whose type is image. On failure, record the job’s error object. A successful HTTP status does not imply a successful generation, and outputs may be null. An observation deadline should route to a resumable pending record rather than claim that the remote job was canceled.

Common mistakes and verification

Reexecuting the whole workflow from its trigger can repeat submission. For recovery, start from a known job identifier and an observation-only path. Disable production triggers while testing this recovery behavior.

Verify a single input item creates one submission, credentials stay out of exported fields, and every polling iteration preserves the same identifier. Use offline fixtures for 202, both submission-related 502 codes, a missing ID, and pending/succeeded/failed/canceled snapshots before a live generation. Ensure every non-accepted branch stops without returning to POST, the pending loop has a reachable stopping condition, and output consumers tolerate null lists. These checks do not require a paid generation.

Review image curl requests for the exact HTTP contract and nonblocking agent design for the same submit-now, collect-later lifecycle.

Continue with agents and automation

Models covered on this page

Where these facts come from