{
  "name": "apizt video task - query existing ID once",
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "nodes": [
    {
      "id": "manual",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ],
      "parameters": {}
    },
    {
      "id": "context",
      "name": "Task context",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        240,
        0
      ],
      "parameters": {
        "jsCode": "const row = {input_id:'DEMO-PRODUCT-01',task_id:'REPLACE_WITH_EXISTING_TASK_ID',model:'doubao-seedance-2-0-260128'};\nif (row.task_id==='REPLACE_WITH_EXISTING_TASK_ID' || !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,255}$/.test(row.task_id)) throw new Error('Set one existing task ID before running');\nreturn [{json:row}];"
      }
    },
    {
      "id": "query",
      "name": "Query existing task once",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        480,
        0
      ],
      "retryOnFail": false,
      "onError": "continueRegularOutput",
      "parameters": {
        "method": "GET",
        "url": "={{ \"https://api.apizt.com/api/v3/contents/generations/tasks/\" + encodeURIComponent($json.task_id) }}",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "options": {
          "timeout": 30000,
          "redirect": {
            "redirect": {
              "followRedirects": false
            }
          },
          "response": {
            "response": {
              "fullResponse": true,
              "neverError": true,
              "responseFormat": "json"
            }
          }
        }
      }
    },
    {
      "id": "classify",
      "name": "Keep ID and classify status",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        720,
        0
      ],
      "parameters": {
        "jsCode": "const context = $('Task context').first().json;\nconst response = $input.first().json;\nconst httpStatus = Number(response.statusCode ?? 0);\nconst body = response.body ?? {};\nconst rawStatus = typeof body.status==='string' ? body.status : null;\nconst sameId = body.id===context.task_id;\nconst mapping={queued:'processing',running:'processing',succeeded:'succeeded',failed:'failed',expired:'failed',cancelled:'failed',canceled:'failed'};\nconst status=httpStatus>=200 && httpStatus<300 && sameId && Object.hasOwn(mapping,rawStatus) ? mapping[rawStatus] : 'unknown';\nconst url=body.content?.video_url;\nlet validUrl=false;\ntry {const parsed=new URL(url); validUrl=parsed.protocol==='https:' && Boolean(parsed.hostname) && !parsed.username && !parsed.password;} catch {}\nreturn [{json:{input_id:context.input_id,task_id:context.task_id,model:context.model,status,download_status:'no',acceptance_status:'pending',billed_usd:'unknown',remote_status:rawStatus,http_status:httpStatus || null,video_url:status==='succeeded' && validUrl ? url : null,usage:body.usage ?? null,manual_follow_up:true}}];"
      }
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Task context",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Task context": {
      "main": [
        [
          {
            "node": "Query existing task once",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query existing task once": {
      "main": [
        [
          {
            "node": "Keep ID and classify status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "templateNote": "Query-only reference template. No create POST, Key or credentials. Offline shape and routing checks only; validate imported options in your n8n version."
  }
}
