{
  "id": "rlTUWIR7CUgFnvJHfQ4lr",
  "name": "Image Generation using Riverflow 2.0",
  "tags": [],
  "nodes": [
    {
      "id": "675c3116-a387-435a-8c87-d9094e1ceac1",
      "name": "On form submission",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        16,
        32
      ],
      "parameters": {
        "options": {},
        "formTitle": "Input data for Riverflow 2.0 Image Generation",
        "formFields": {
          "values": [
            {
              "fieldType": "dropdown",
              "fieldLabel": "Model",
              "fieldOptions": {
                "values": [
                  {
                    "option": "pro"
                  },
                  {
                    "option": "fast"
                  }
                ]
              }
            },
            {
              "fieldLabel": "Font Urls"
            },
            {
              "fieldLabel": "Font Texts"
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Resolution",
              "defaultValue": "1K",
              "fieldOptions": {
                "values": [
                  {
                    "option": "1K"
                  },
                  {
                    "option": "2K"
                  }
                ]
              }
            },
            {
              "fieldLabel": "Init Images"
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "Instruction",
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Aspect Ratio",
              "defaultValue": "auto",
              "fieldOptions": {
                "values": [
                  {
                    "option": "auto"
                  },
                  {
                    "option": "1:1"
                  },
                  {
                    "option": "4:3"
                  },
                  {
                    "option": "3:4"
                  },
                  {
                    "option": "16:9"
                  },
                  {
                    "option": "9:16"
                  },
                  {
                    "option": "3:2"
                  },
                  {
                    "option": "2:3"
                  },
                  {
                    "option": "7:3"
                  },
                  {
                    "option": "4:5"
                  },
                  {
                    "option": "5:4"
                  }
                ]
              }
            },
            {
              "fieldType": "checkbox",
              "fieldLabel": "Transparency",
              "fieldOptions": {
                "values": [
                  {
                    "option": "true"
                  }
                ]
              }
            },
            {
              "fieldType": "checkbox",
              "fieldLabel": "Enhance Prompt",
              "fieldOptions": {
                "values": [
                  {
                    "option": "true"
                  }
                ]
              }
            },
            {
              "fieldType": "number",
              "fieldLabel": "Max Iterations",
              "defaultValue": "1"
            },
            {
              "fieldType": "checkbox",
              "fieldLabel": "Safety Checker",
              "defaultValue": "true",
              "fieldOptions": {
                "values": [
                  {
                    "option": "true"
                  }
                ]
              }
            },
            {
              "fieldLabel": "Super Resolution Refs"
            },
            {
              "fieldType": "number",
              "fieldLabel": "Number of Outputs",
              "defaultValue": "1"
            }
          ]
        },
        "formDescription": "Select model and parameters. (for any field with multiple values, separate using commas)"
      },
      "typeVersion": 2.5
    },
    {
      "id": "67762d6f-c9d5-4509-aee7-b213cd272558",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -592,
        -64
      ],
      "parameters": {
        "width": 544,
        "height": 432,
        "content": "## Image Generation using Riverflow 2.0\n\n### How it works\n- **Input Form**  takes in the necessary data to be used for the image editing/prediction such the initial image, font url & text for any text to edit/modify (Riverflow 2.0 fast), instruction (required), and other parameters such as enhance prompt, etc.\n- **Sanitises the inputs** to ensure that the correct and valid json payload can be given to the Replicate API\n- **POST request** is made to generate the image along with a loop to see if the **GET request** gives a valid response.\n- Result then returned as a **URL + raw image output**.\n- **Sub-workflow** is used to allow for parallel processing where multiple output images are required.\n### How to setup\n- Add **Replicate API key** (https://replicate.com/)\n- Create a **Data Table** to store data for communication between parent and Sub-Workflow"
      },
      "typeVersion": 1
    },
    {
      "id": "2860e54e-bf3a-48f7-8074-e18c053cc38f",
      "name": "Parse inputs given from form",
      "type": "n8n-nodes-base.code",
      "position": [
        224,
        32
      ],
      "parameters": {
        "jsCode": "// Get input items from n8n\nconst items = $input.all();\nconst crypto = require('crypto');\n\n// Fields that should be treated as booleans\nconst booleanFields = [\"transparency\", \"enhance_prompt\", \"safety_checker\"];\n\n// Fields that should always be arrays\nconst arrayFields = [\"init_images\", \"font_urls\", \"font_texts\",\"super_resolution_refs\"];\nconst removeFields = [\"formmode\"]\n// Function to normalize field names: lowercase + underscores\nfunction normalizeFieldName(name) {\n  return name.toLowerCase().replace(/\\s+/g, \"_\");\n}\nconst outputItems = [];\nconst processId = crypto.randomUUID();\n// Process each item\nitems.forEach(item => {\n  const newJson = {};\n  let init_limit = 4;\n  let url = \"https://api.replicate.com/v1/models/sourceful/riverflow-2.0-fast/predictions\"\n  if (\n      typeof item.json.Model === \"string\" && item.json.Model === \"pro\"\n    ) {\n      url = \"https://api.replicate.com/v1/models/sourceful/riverflow-2.0-pro/predictions\"\n      init_limit = 10;\n    }\n  for (let key in item.json) {\n    let value = item.json[key];\n    const newKey = normalizeFieldName(key);\n    if (removeFields.includes(newKey)) continue;\n    // Validate max_iterations\n    if (newKey === \"max_iterations\") {\n      if (value > 3) {\n        throw new Error(`max_iterations cannot be greater than 3 (found ${value})`);\n      }\n    }\n    if (newKey == \"number_of_outputs\"){\n      if (value >4){\n        throw new Error(`number of outputs cannot be greater than 4 (found ${value})`);\n      }\n    }\n\n    // Convert comma-separated strings to arrays\n    if (arrayFields.includes(newKey)) {\n      if (typeof value === \"string\") {\n        // Split by commas if any, remove empty strings, always make it an array\n        value = value.split(\",\").map(s => s.trim()).filter(s => s.length > 0);\n      }\n      // Ensure single strings or empty values are also arrays\n      if (!Array.isArray(value)) {\n        value = value ? [value] : [];\n      }\n\n      // For font_urls, enforce max 2\n      if (newKey === \"font_urls\" && value.length > 2) {\n        throw new Error(`font_urls cannot have more than 2 entries (found ${value.length})`);\n      }\n      if(newKey == \"init_images\" && value.length > init_limit){\n        throw new Error(`init_images cannot have more than ${init_limit} entries (found ${value.length})`);\n      }\n      if(newKey == \"super_resolution_refs\"&& value.length > 4){\n        throw new Error(`super resolution refs cannot be more than 4 (found ${value.length})`);\n      }\n    }\n\n    // Convert n8n boolean array-style to actual booleans\n    if (booleanFields.includes(newKey)) {\n      if (Array.isArray(value) && value.length === 1 && value[0].toLowerCase() === \"true\") {\n        value = true;\n      } else {\n        value = false;\n      }\n    }\n\n    // Assign normalized key/value\n    newJson[newKey] = value;\n    \n  }\n  newJson.url = url;\n  newJson.processID = processId;\n  const count = Number(newJson.number_of_outputs || 1);\n\n  for (let i = 0; i < count; i++) {\n    outputItems.push({\n      json: JSON.parse(JSON.stringify(newJson))\n    });\n  }\n  // Replace item.json with normalized version\n  item.json = newJson;\n});\n\n// Return the modified input (compatible with n8n)\nreturn outputItems;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "d8c9758a-06a2-4f2a-b872-1bd81d7c5c4c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -32,
        -16
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 224,
        "content": "### Receiving and handling input"
      },
      "typeVersion": 1
    },
    {
      "id": "73e222fb-5edd-4de4-ae69-e6485364acdf",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        432
      ],
      "parameters": {
        "color": 5,
        "height": 320,
        "content": "### Initial Image\n\"make the text on the shampoo bottle say *Riverflow*\"\n![](https://replicate.delivery/pbxt/OVIMHUHWeaGC1B833lZPDdnTbFpVOuixPbT9Gn4WvEPo7xrh/shampoo-bottle-left.webp)"
      },
      "typeVersion": 1
    },
    {
      "id": "9967ec29-1ed0-481b-bb05-f82bacae1304",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -576,
        768
      ],
      "parameters": {
        "color": 5,
        "height": 272,
        "content": "### Output Image\n![](https://replicate.delivery/xezq/7hxGQNvBZHbtE1LJ5gui24oQWxxS0VT05VfbByhf0ynuOuCWA/tmp6e9pxgkv.webp)"
      },
      "typeVersion": 1
    },
    {
      "id": "571ab2a9-81d0-41b7-b67c-defba0b1ccc8",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -592,
        384
      ],
      "parameters": {
        "color": 4,
        "width": 544,
        "height": 672,
        "content": "## Examples\n"
      },
      "typeVersion": 1
    },
    {
      "id": "04dc45a6-ffdf-4f36-afc5-419f3b1c5394",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -304,
        432
      ],
      "parameters": {
        "color": 5,
        "height": 368,
        "content": "### Initial Image\n\"Create a landing page mockup for my product\"\n![](https://replicate.delivery/pbxt/OW2cwcgcKYI8R7XRYeNu3wNynKd3lxGDK9xaIMUKxQp5DoSr/Replicate%20x%20Sourceful.png)"
      },
      "typeVersion": 1
    },
    {
      "id": "a545e4d2-52e3-429a-8a5d-1b97505e3457",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -304,
        816
      ],
      "parameters": {
        "color": 5,
        "height": 224,
        "content": "### Output Image\n![](https://replicate.delivery/xezq/jO4We5vFXx1NMC7HUPEmU1JSmpK9C6zNehZ0zH0cdcgvjaDWA/tmpz9f0kmsf.webp)"
      },
      "typeVersion": 1
    },
    {
      "id": "156d2840-d1af-4ac5-a8d9-7aa5034179bf",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        -96
      ],
      "parameters": {
        "color": 5,
        "width": 368,
        "height": 320,
        "content": "### Sub-Flow\nRuns another work-flow which contains nodes to:\n- send POST request to Replicate \n- do a GET request to check for errors and status. \n- If no errors, the output url is returned."
      },
      "typeVersion": 1
    },
    {
      "id": "6898f33e-69d2-46bb-ba50-61c34a78170b",
      "name": "Call 'POST + GET requests sub-workflow'",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        544,
        32
      ],
      "parameters": {
        "mode": "each",
        "options": {
          "waitForSubWorkflow": false
        },
        "workflowId": {
          "__rl": true,
          "mode": "list",
          "value": "s5aseRc6thQFXxv4",
          "cachedResultUrl": "/workflow/s5aseRc6thQFXxv4",
          "cachedResultName": "HTTPs Requests for Riverflow 2.0 Image Generation"
        },
        "workflowInputs": {
          "value": {
            "url": "={{ $json.url }}",
            "process_id": "={{ $json.processID }}",
            "transparency": "={{ $json.transparency }}",
            "enhance_prompt": "={{ $json.enhance_prompt }}",
            "max_iterations": "={{ $json.max_iterations }}",
            "safety_checker": "={{ $json.safety_checker }}",
            "font_urls_toJsonString": "={{ $json.font_urls }}",
            "font_texts_toJsonString": "={{ $json.font_texts }}",
            "resolution_toJsonString": "={{ $json.resolution }}",
            "init_images_toJsonString": "={{ $json.init_images }}",
            "instruction_toJsonString": "={{ $json.instruction }}",
            "aspect_ratio_toJsonString": "={{ $json.aspect_ratio }}",
            "super_resolution_refs_toJsonString": "={{ $json.super_resolution_refs }}"
          },
          "schema": [
            {
              "id": "url",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "super_resolution_refs_toJsonString",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "super_resolution_refs_toJsonString",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "aspect_ratio_toJsonString",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "aspect_ratio_toJsonString",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "init_images_toJsonString",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "init_images_toJsonString",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "instruction_toJsonString",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "instruction_toJsonString",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "font_texts_toJsonString",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "font_texts_toJsonString",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "resolution_toJsonString",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "resolution_toJsonString",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "font_urls_toJsonString",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "font_urls_toJsonString",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "enhance_prompt",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "enhance_prompt",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "max_iterations",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "max_iterations",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "safety_checker",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "safety_checker",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "transparency",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "transparency",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "process_id",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "process_id",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": true
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "b3666735-5c7f-40bb-821d-a09888eb0e31",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        1360,
        32
      ],
      "parameters": {
        "amount": 10
      },
      "typeVersion": 1.1
    },
    {
      "id": "05231dae-c49c-43b4-b793-37f44513540d",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        944,
        -32
      ],
      "parameters": {
        "color": 7,
        "width": 944,
        "height": 256,
        "content": "### Polling process id till all complete"
      },
      "typeVersion": 1
    },
    {
      "id": "5036a475-94cb-4d77-8f84-6a5878915eda",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1920,
        0
      ],
      "parameters": {
        "color": 7,
        "width": 288,
        "height": 192,
        "content": "### Outputing Images"
      },
      "typeVersion": 1
    },
    {
      "id": "fa5fe18c-5dc0-4ab2-9a2b-b65c20177270",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        256
      ],
      "parameters": {
        "color": 6,
        "width": 288,
        "height": 144,
        "content": "### Data Table\nData table used as a way to **communicate between the sub-workflows and the parent workflow** so that we can keep track of if they are complete or not."
      },
      "typeVersion": 1
    },
    {
      "id": "4e66c4f7-00ed-450c-9a44-d2b2019930e6",
      "name": "Isolate 1 process id",
      "type": "n8n-nodes-base.code",
      "position": [
        816,
        32
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nif (items.length === 0) {\n  return [];\n}\n\nreturn [\n  {\n    json: items[0].json\n  }\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "51940d73-65fb-43ec-85d4-59583c795941",
      "name": "Isolate 1 process id1",
      "type": "n8n-nodes-base.code",
      "position": [
        1184,
        32
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nif (items.length === 0) {\n  return [];\n}\n\n// Return only the first item\nreturn [items[0]];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "0ad01966-9314-449b-8517-e81de1d233dc",
      "name": "Insert empty process id",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        992,
        32
      ],
      "parameters": {
        "columns": {
          "value": {
            "process": "={{ $input.first().json.process_id }}",
            "processcount": "={{ $input.first().json.number_of_outputs }}"
          },
          "schema": [
            {
              "id": "process",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "process",
              "defaultMatch": false
            },
            {
              "id": "time",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "time",
              "defaultMatch": false
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false
            },
            {
              "id": "output",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "output",
              "defaultMatch": false
            },
            {
              "id": "processcount",
              "type": "number",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "processcount",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "SdzSGfEAOeEmquQm",
          "cachedResultUrl": "/projects/hsGHyIoVWZxfZQOB/datatables/SdzSGfEAOeEmquQm",
          "cachedResultName": "Processes"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "7d9ab06f-d854-4ca5-882f-f90186962e2a",
      "name": "If number of processes is correct",
      "type": "n8n-nodes-base.if",
      "position": [
        1728,
        32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "60b23133-5537-4a00-b33a-9c801b21a3c4",
              "operator": {
                "type": "number",
                "operation": "notEquals"
              },
              "leftValue": "={{ $input.all().length }}",
              "rightValue": "={{$input.first().json.processcount +1}}"
            }
          ]
        }
      },
      "typeVersion": 2.3,
      "alwaysOutputData": false
    },
    {
      "id": "b459d9da-7d42-4ac0-a70b-d5ee44880f96",
      "name": "Output Filtering",
      "type": "n8n-nodes-base.code",
      "position": [
        1936,
        48
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\nconst outputUrls = [];\n\nfor (const item of items) {\n  const output = item.json.output;\n\n  if (typeof output === \"string\" && output.length > 0) {\n    outputUrls.push(output);\n  }\n}\n\n// Remove duplicates\nconst uniqueOutputs = [...new Set(outputUrls)];\n\n\nreturn uniqueOutputs.map(url => ({\n  json: { url }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "6562e051-4d46-4754-b69a-4eedf57b304a",
      "name": "Get how many processes done",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        1536,
        32
      ],
      "parameters": {
        "filters": {
          "conditions": [
            {
              "keyName": "process",
              "keyValue": "={{ $input.first().json.process }}"
            }
          ]
        },
        "operation": "get",
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "SdzSGfEAOeEmquQm",
          "cachedResultUrl": "/projects/hsGHyIoVWZxfZQOB/datatables/SdzSGfEAOeEmquQm",
          "cachedResultName": "Processes"
        }
      },
      "notesInFlow": false,
      "typeVersion": 1.1,
      "alwaysOutputData": false
    },
    {
      "id": "58c78e91-3ed6-48ce-b514-ff8a0a5ce0ed",
      "name": "Get image/s",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2080,
        48
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "options": {}
      },
      "typeVersion": 4.4
    },
    {
      "id": "580e6124-5950-4e49-b30e-f04852db4fd3",
      "name": "Return output image url",
      "type": "n8n-nodes-base.set",
      "position": [
        1280,
        592
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "19919cf8-e9a8-4a8d-be24-1db61cd4f4a1",
              "name": "output",
              "type": "array",
              "value": "={{ $json.output }}"
            },
            {
              "id": "24390454-2d86-4031-a53d-2ff390b0e984",
              "name": "time",
              "type": "string",
              "value": "={{ $json.created_at }}"
            },
            {
              "id": "a96b76af-5c10-41c9-a535-8883abf60436",
              "name": "status",
              "type": "string",
              "value": "={{ $json.status }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "215c3bd8-c541-4a5a-8ff9-613752aeceee",
      "name": "GET Request for Riverflow Predictions",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        848,
        576
      ],
      "parameters": {
        "url": "={{ $json.urls.get }}",
        "options": {
          "timeout": 6000
        },
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "2b972b30-0630-48c5-82f9-ad1c51b90809",
      "name": "Check if output is present",
      "type": "n8n-nodes-base.if",
      "position": [
        1056,
        576
      ],
      "parameters": {
        "options": {
          "ignoreCase": false
        },
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "f2b52cb5-6f4d-4a18-8acc-2ad50a9822d8",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.status }}",
              "rightValue": "=processing"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "b67dab2e-bce1-4e3f-916a-259c1fcf51a0",
      "name": "POST request to Replicate API",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        432,
        576
      ],
      "parameters": {
        "url": "={{ $json.url }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n    \"input\": {\n      \"font_urls\": {{ $json.font_urls_toJsonString.toJsonString() }},\n      \"font_texts\": {{ $json.font_texts_toJsonString.toJsonString() }},\n      \"resolution\": {{ $json.resolution_toJsonString.toJsonString() }},\n      \"init_images\": {{ $json.init_images_toJsonString.toJsonString() }},\n      \"instruction\": {{ $json.instruction_toJsonString.toJsonString() }},\n      \"aspect_ratio\": {{ $json.aspect_ratio_toJsonString.toJsonString() }},\n      \"transparency\": {{ $json.transparency }},\n      \"enhance_prompt\": {{ $json.enhance_prompt }},\n      \"max_iterations\": {{ $json.max_iterations }},\n      \"safety_checker\": {{ $json.safety_checker }},\n      \"super_resolution_refs\": {{ $json.super_resolution_refs_toJsonString.toJsonString() }}\n    }\n  }",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Prefer",
              "value": "wait"
            }
          ]
        },
        "nodeCredentialType": "httpBearerAuth"
      },
      "credentials": {
        "httpBearerAuth": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": false,
      "typeVersion": 4.4
    },
    {
      "id": "36fae70b-0f88-457c-bc84-b21334a85f4d",
      "name": "Start",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        176,
        752
      ],
      "parameters": {
        "workflowInputs": {
          "values": [
            {
              "name": "url",
              "type": "any"
            },
            {
              "name": "super_resolution_refs_toJsonString",
              "type": "any"
            },
            {
              "name": "aspect_ratio_toJsonString",
              "type": "any"
            },
            {
              "name": "init_images_toJsonString",
              "type": "any"
            },
            {
              "name": "instruction_toJsonString",
              "type": "any"
            },
            {
              "name": "font_texts_toJsonString",
              "type": "any"
            },
            {
              "name": "resolution_toJsonString",
              "type": "any"
            },
            {
              "name": "font_urls_toJsonString",
              "type": "any"
            },
            {
              "name": "enhance_prompt",
              "type": "any"
            },
            {
              "name": "max_iterations",
              "type": "any"
            },
            {
              "name": "safety_checker",
              "type": "any"
            },
            {
              "name": "transparency",
              "type": "any"
            },
            {
              "name": "process_id",
              "type": "any"
            }
          ]
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "9ecf34f8-09a4-4712-bedd-2b893c51ae98",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        480,
        880
      ],
      "parameters": {},
      "typeVersion": 3.2
    },
    {
      "id": "48db880a-d972-4565-a237-16fd627efa58",
      "name": "Code in JavaScript",
      "type": "n8n-nodes-base.code",
      "position": [
        656,
        880
      ],
      "parameters": {
        "jsCode": "const items = $input.all();\n\n// Extract process_id from any item that has it\nconst processId =\n  items.find(i => i.json.process_id)?.json.process_id ?? null;\n\n// Keep only items that are actual Replicate results\nconst resultItems = items.filter(\n  item => Array.isArray(item.json.output)\n);\n\n// Build clean output\nreturn resultItems.map(item => ({\n  json: {\n    process_id: processId,\n    status: item.json.status,\n    time: item.json.time,\n    output_url: item.json.output[0] // Replicate returns array\n  }\n}));\n"
      },
      "typeVersion": 2
    },
    {
      "id": "fd0911d7-b9c2-46cd-a9a1-2e27ea2575a7",
      "name": "Insert row",
      "type": "n8n-nodes-base.dataTable",
      "position": [
        864,
        880
      ],
      "parameters": {
        "columns": {
          "value": {
            "time": "={{ $json.time }}",
            "output": "={{ $json.output_url }}",
            "status": "={{ $json.status }}",
            "process": "={{ $json.process_id }}"
          },
          "schema": [
            {
              "id": "process",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "process",
              "defaultMatch": false
            },
            {
              "id": "time",
              "type": "dateTime",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "time",
              "defaultMatch": false
            },
            {
              "id": "status",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "status",
              "defaultMatch": false
            },
            {
              "id": "output",
              "type": "string",
              "display": true,
              "removed": false,
              "readOnly": false,
              "required": false,
              "displayName": "output",
              "defaultMatch": false
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "dataTableId": {
          "__rl": true,
          "mode": "list",
          "value": "SdzSGfEAOeEmquQm",
          "cachedResultUrl": "/projects/hsGHyIoVWZxfZQOB/datatables/SdzSGfEAOeEmquQm",
          "cachedResultName": "Processes"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "ce07d74b-589f-46c5-bf3f-d1cd9e5aedb8",
      "name": "Wait1",
      "type": "n8n-nodes-base.wait",
      "position": [
        640,
        576
      ],
      "parameters": {
        "amount": 2
      },
      "typeVersion": 1.1
    },
    {
      "id": "113d7671-0501-4dfc-b327-f09acba2a1f3",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        576,
        528
      ],
      "parameters": {
        "color": 7,
        "width": 640,
        "height": 240,
        "content": "### Loop to check get request till status is no longer processing"
      },
      "typeVersion": 1
    },
    {
      "id": "b4526246-34c4-4ea4-83c9-91c85a0705ef",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        528
      ],
      "parameters": {
        "color": 3,
        "width": 160,
        "height": 208,
        "content": "### Riverflow 2.0 call "
      },
      "typeVersion": 1
    },
    {
      "id": "256df2c9-5ab8-42c7-90bb-b9ea53d5500a",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 320,
        "height": 224,
        "content": "### Gather parameters needed to add to data table"
      },
      "typeVersion": 1
    },
    {
      "id": "aae84a07-c67a-446a-9a6c-84e06432a4e9",
      "name": "Sticky Note14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        816,
        816
      ],
      "parameters": {
        "color": 7,
        "width": 198,
        "height": 224,
        "content": "### Insert into data table for parent workflow"
      },
      "typeVersion": 1
    },
    {
      "id": "b9c97657-07cd-4166-9b8c-6c5dd2cc78b1",
      "name": "Sticky Note15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        464
      ],
      "parameters": {
        "color": 5,
        "width": 1312,
        "height": 592,
        "content": "## Sub-Workflow: HTTPs Requests for RIverflow 2.0 through Replicate"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "970aa2b8-fa89-46fa-a823-1d202592cfda",
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Get how many processes done",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Start": {
      "main": [
        [
          {
            "node": "POST request to Replicate API",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait1": {
      "main": [
        [
          {
            "node": "GET Request for Riverflow Predictions",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Output Filtering": {
      "main": [
        [
          {
            "node": "Get image/s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Code in JavaScript": {
      "main": [
        [
          {
            "node": "Insert row",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "On form submission": {
      "main": [
        [
          {
            "node": "Parse inputs given from form",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Isolate 1 process id": {
      "main": [
        [
          {
            "node": "Insert empty process id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Isolate 1 process id1": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert empty process id": {
      "main": [
        [
          {
            "node": "Isolate 1 process id1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Return output image url": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Check if output is present": {
      "main": [
        [
          {
            "node": "Wait1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Return output image url",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get how many processes done": {
      "main": [
        [
          {
            "node": "If number of processes is correct",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse inputs given from form": {
      "main": [
        [
          {
            "node": "Call 'POST + GET requests sub-workflow'",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "POST request to Replicate API": {
      "main": [
        [
          {
            "node": "Wait1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If number of processes is correct": {
      "main": [
        [
          {
            "node": "Isolate 1 process id1",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Output Filtering",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GET Request for Riverflow Predictions": {
      "main": [
        [
          {
            "node": "Check if output is present",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Call 'POST + GET requests sub-workflow'": {
      "main": [
        [
          {
            "node": "Isolate 1 process id",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}