AutomationFlowsMarketing & Ads › Generate Product and Marketing Images Using Riverflow 2.0 on Replicate

Generate Product and Marketing Images Using Riverflow 2.0 on Replicate

ByJoel Sage @joelsagesourceful on n8n.io

This workflow is designed to take user inputs in order to generate an image using the Riverflow 2.0 model through the Replicate API. It can handle both image generation as well as image editing. Additionally, for specific text modifications, the source text and font can be…

Event trigger★★★★★ complexity36 nodesForm TriggerData TableHTTP RequestExecute Workflow Trigger
Marketing & Ads Trigger: Event Nodes: 36 Complexity: ★★★★★ Added:

This workflow corresponds to n8n.io template #13303 — we link there as the canonical source.

This workflow follows the Datatable → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "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
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow is designed to take user inputs in order to generate an image using the Riverflow 2.0 model through the Replicate API. It can handle both image generation as well as image editing. Additionally, for specific text modifications, the source text and font can be…

Source: https://n8n.io/workflows/13303/ — original creator credit. Request a take-down →

More Marketing & Ads workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Marketing & Ads

Sales teams looking to build targeted company lead lists

Form Trigger, HTTP Request, Data Table
Marketing & Ads

The Recap AI - Insurance Lawyer Lead Gen. Uses executeWorkflowTrigger, formTrigger, @mendable/n8n-nodes-firecrawl, googleSheets. Event-driven trigger; 33 nodes.

Execute Workflow Trigger, Form Trigger, @Mendable/N8N Nodes Firecrawl +4
Marketing & Ads

Paste your webinar recording URL into a simple form — and this workflow does the rest automatically. WayinVideo AI scans the full recording and extracts the most engaging clip segments, ready for your

HTTP Request, Google Drive, Form Trigger
Marketing & Ads

Edit Image. Uses executeWorkflowTrigger, httpRequest, convertToFile, googleSheets. Event-driven trigger; 12 nodes.

Execute Workflow Trigger, HTTP Request, Google Sheets +2
Marketing & Ads

This workflow utilizes the Defapi API with Sora 2 AI model to generate stunning viral videos with creative AI-generated motion, effects, and storytelling. Simply provide a creative prompt describing y

HTTP Request, Form Trigger