{
  "name": "HiAPI GPT Image 2/2.5 async task workflow (credential required)",
  "id": "hiapi-gpt-image-async-20260920",
  "nodes": [
    {
      "parameters": {},
      "id": "1",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        -1000,
        0
      ]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "baseUrl",
              "type": "string",
              "value": "https://api.hiapi.ai"
            },
            {
              "id": "a2",
              "name": "model",
              "type": "string",
              "value": "gpt-image-2.5-flare/text-to-image"
            },
            {
              "id": "a3",
              "name": "prompt",
              "type": "string",
              "value": "A clean product photo of an orange retro handheld game console on a warm ivory studio surface, no text, no watermark."
            },
            {
              "id": "a4",
              "name": "aspect_ratio",
              "type": "string",
              "value": "1:1"
            },
            {
              "id": "a5",
              "name": "resolution",
              "type": "string",
              "value": "1K"
            },
            {
              "id": "a6",
              "name": "maxPolls",
              "type": "number",
              "value": 36
            },
            {
              "id": "a7",
              "name": "pollIntervalSeconds",
              "type": "number",
              "value": 5
            }
          ]
        },
        "options": {}
      },
      "id": "2",
      "name": "Workflow Input",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        -800,
        0
      ]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "={{$json.baseUrl + '/v1/tasks'}}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "contentType": "json",
        "specifyBody": "json",
        "jsonBody": "={{ { model: $json.model, input: { prompt: $json.prompt, aspect_ratio: $json.aspect_ratio, resolution: $json.resolution } } }}",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "3",
      "name": "Submit Task",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        -560,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "hiapi-api-key-local",
          "name": "HiAPI API Key (create locally)"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "const input = $('Workflow Input').first().json;\nconst taskId = $json?.data?.taskId;\nif (!taskId) throw new Error('Submit response did not contain data.taskId; no polling started.');\nconst maxPolls = Number(input.maxPolls || 36);\nconst pollIntervalSeconds = Number(input.pollIntervalSeconds || 5);\nreturn [{json:{baseUrl: input.baseUrl, taskId, pollCount:0, maxPolls, pollIntervalSeconds, status:'queued', terminal:false, timedOut:false, lastResponse:$json}}];"
      },
      "id": "4",
      "name": "Initialize Poll State",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -320,
        0
      ]
    },
    {
      "parameters": {
        "amount": "={{$json.pollIntervalSeconds}}",
        "unit": "seconds"
      },
      "id": "5",
      "name": "Wait Before Poll",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        -80,
        0
      ]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{$json.baseUrl + '/v1/tasks/' + $json.taskId}}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        }
      },
      "id": "6",
      "name": "Get Task",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        160,
        0
      ],
      "credentials": {
        "httpHeaderAuth": {
          "id": "hiapi-api-key-local",
          "name": "HiAPI API Key (create locally)"
        }
      }
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "id": "11",
      "name": "Merge Poll State",
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        280,
        0
      ]
    },
    {
      "parameters": {
        "jsCode": "const state = $json || {};\nconst response = state.data ? {data: state.data} : {};\nconst data = response.data || {};\nconst status = String(data.status || '');\nconst pollCount = Number(state.pollCount || 0) + 1;\nconst maxPolls = Number(state.maxPolls || 36);\nconst terminal = status === 'success' || status === 'fail' || pollCount >= maxPolls;\nconst timedOut = terminal && pollCount >= maxPolls && status !== 'success' && status !== 'fail';\nreturn [{json:{baseUrl:state.baseUrl, taskId:state.taskId, pollCount, maxPolls, pollIntervalSeconds:Number(state.pollIntervalSeconds || 5), status, terminal, timedOut, lastResponse:response}}];"
      },
      "id": "7",
      "name": "Record Poll Result",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        400,
        0
      ]
    },
    {
      "parameters": {
        "conditions": {
          "combinator": "and",
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "leftValue": "={{$json.terminal}}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ]
        }
      },
      "id": "8",
      "name": "Terminal?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        640,
        0
      ]
    },
    {
      "parameters": {
        "amount": "={{$json.pollIntervalSeconds}}",
        "unit": "seconds"
      },
      "id": "9",
      "name": "Wait Next Poll",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        880,
        180
      ]
    },
    {
      "parameters": {
        "jsCode": "const response = $json.lastResponse || {};\nconst data = response.data || {};\nconst outputs = Array.isArray(data.output) ? data.output : [];\nconst status = $json.timedOut ? 'timeout' : ($json.status || 'unknown');\nreturn [{json:{taskId:$json.taskId,status,pollCount:$json.pollCount,resultUrl:outputs[0]?.url || null,outputs,error:data.error || null,raw:data}}];"
      },
      "id": "10",
      "name": "Final Output",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        880,
        -80
      ]
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Workflow Input",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Input": {
      "main": [
        [
          {
            "node": "Submit Task",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Submit Task": {
      "main": [
        [
          {
            "node": "Initialize Poll State",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Initialize Poll State": {
      "main": [
        [
          {
            "node": "Wait Before Poll",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait Before Poll": {
      "main": [
        [
          {
            "node": "Get Task",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Poll State",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Task": {
      "main": [
        [
          {
            "node": "Merge Poll State",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Poll State": {
      "main": [
        [
          {
            "node": "Record Poll Result",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Record Poll Result": {
      "main": [
        [
          {
            "node": "Terminal?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Terminal?": {
      "main": [
        [
          {
            "node": "Final Output",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait Next Poll",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait Next Poll": {
      "main": [
        [
          {
            "node": "Get Task",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Poll State",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "hiapi-gpt-image-async-20260920",
  "meta": {
    "templateCredsSetupCompleted": false
  },
  "tags": []
}
