AutomationFlowsData & Sheets › Bulk AI Video Generation with Freepik Minimax Hailuo

Bulk AI Video Generation with Freepik Minimax Hailuo

Original n8n title: Bulk AI Video Generation with Freepik Minimax Hailuo & Google Suite Integration

ByRobert Breen @rbreen on n8n.io

This n8n workflow automates bulk AI video generation using Freepik's Image-to-Video API powered by Minimax Hailuo-02-768p. It reads video prompts from a Google Sheet, generates multiple variations of each video using Freepik's AI, handles asynchronous video processing with…

Manual trigger★★★★☆ complexity13 nodesHTTP RequestGoogle DriveGoogle Sheets
Data & Sheets Trigger: Manual Nodes: 13 Complexity: ★★★★☆ Added:

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

This workflow follows the Google Drive → Google Sheets 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
{
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "39cea19d-02e6-4431-9d8e-0dc76646d6cd",
      "name": "Download Video as Base64",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        128,
        1904
      ],
      "parameters": {
        "url": "={{ $json.data.generated[0] }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "78fa05c7-f18f-4d91-a425-d3760106016e",
      "name": "Upload to Google Drive1",
      "type": "n8n-nodes-base.googleDrive",
      "position": [
        256,
        2048
      ],
      "parameters": {
        "name": "=video - {{ $('Get prompt from google sheet').item.json.Name }} - {{ $('Duplicate Rows2').item.json.run }}",
        "driveId": {
          "__rl": true,
          "mode": "list",
          "value": "My Drive",
          "cachedResultUrl": "https://drive.google.com/drive/my-drive",
          "cachedResultName": "My Drive"
        },
        "options": {},
        "folderId": {
          "__rl": true,
          "mode": "list",
          "value": "1TnDibwPPPUm3VbmETiqWDVhtaUTLJ6mn",
          "cachedResultUrl": "https://drive.google.com/drive/folders/1TnDibwPPPUm3VbmETiqWDVhtaUTLJ6mn",
          "cachedResultName": "n8n workflows"
        }
      },
      "credentials": {
        "googleDriveOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 3
    },
    {
      "id": "ed922804-f614-4dc4-be98-263c803e8382",
      "name": "Create Video",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -720,
        1952
      ],
      "parameters": {
        "url": "https://api.freepik.com/v1/ai/image-to-video/minimax-hailuo-02-768p",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "prompt",
              "value": "={{ $json.Prompt }}   "
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "4a77b1d7-8e1f-49c0-899c-182ab2866d6f",
      "name": "Get Video URL",
      "type": "n8n-nodes-base.httpRequest",
      "notes": "If the previous node isn't SUCCEEDED yet, re-run \"Get Task Status\" after a short wait.",
      "position": [
        -496,
        1936
      ],
      "parameters": {
        "url": "=\nhttps://api.freepik.com/v1/ai/image-to-video/minimax-hailuo-02-768p/{{ $json.data.task_id }}\n\n",
        "options": {
          "timeout": 120000
        },
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "notesInFlow": true,
      "typeVersion": 4.2
    },
    {
      "id": "1a4468a7-753e-4caf-956d-6d07121e0da5",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        -208,
        1968
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Completed",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "43a3872d-1597-4265-92df-cb055a049d10",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.status }}",
                    "rightValue": "COMPLETED"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Failed",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "d54580f5-e892-475d-b2eb-19dcf216e1e2",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.status }}",
                    "rightValue": "FAILED"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Created",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "089f70ab-b693-44c4-bca7-dfee87bd6fee",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.status }}",
                    "rightValue": "CREATED"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "In Progress",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "d3086f63-8dd7-421d-a880-877f318c5366",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.data.status }}",
                    "rightValue": "IN_PROGRESS"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "25e5774c-ea6d-47bd-bb32-93136982ee16",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        32,
        2032
      ],
      "parameters": {
        "amount": 30
      },
      "typeVersion": 1.1
    },
    {
      "id": "714ea29e-4834-4da7-aab2-68e2dae8e0a1",
      "name": "Duplicate Rows2",
      "type": "n8n-nodes-base.code",
      "position": [
        -1296,
        2080
      ],
      "parameters": {
        "jsCode": "const original = items[0].json;\n\nreturn [\n  { json: { ...original, run: 1 } },\n  { json: { ...original, run: 2 } },\n];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "4c240d7f-5497-4165-b485-3fcb8c0a0baa",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -944,
        1952
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "34f8f236-4efb-44c8-aead-4dc19d7e2381",
      "name": "Get prompt from google sheet",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        -1504,
        2016
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1_u9IxEZINcwKQB15Rfx7C1hM71zeDST58Fz3nRHTCUY/edit#gid=0",
          "cachedResultName": "Sheet1"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1_u9IxEZINcwKQB15Rfx7C1hM71zeDST58Fz3nRHTCUY",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1_u9IxEZINcwKQB15Rfx7C1hM71zeDST58Fz3nRHTCUY/edit?usp=drivesdk",
          "cachedResultName": "freepik prompts"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "3d4d077f-4988-4b70-b3a5-358ecbab19f4",
      "name": "Sticky Note17",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1616,
        1200
      ],
      "parameters": {
        "width": 2032,
        "content": "## \ud83d\udcec Need Help or Want to Customize This?\n\ud83d\udce7 [robert@ynteractive.com](mailto:robert@ynteractive.com)  \n\ud83d\udd17 [LinkedIn](https://www.linkedin.com/in/robert-breen-29429625/)"
      },
      "typeVersion": 1
    },
    {
      "id": "a310dde0-0eb9-4a18-8e0a-cb9519fd2b9f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1616,
        1376
      ],
      "parameters": {
        "color": 5,
        "width": 600,
        "height": 860,
        "content": "\n#### Node Configuration Details:\n\n##### Get prompt from google sheet (Google Sheets)\n- **Document ID**: Your Google Sheet ID (from Step 3)\n- **Sheet Name**: `Sheet1` (or your sheet name)\n- **Operation**: Read\n- **Credentials**: Select your \"Google Sheets account\"\n\n##### Duplicate Rows2 (Code Node)\n- **Purpose**: Creates multiple variations of each prompt\n- **JavaScript Code**:\n```javascript\nconst original = items[0].json;\n\nreturn [\n  { json: { ...original, run: 1 } },\n  { json: { ...original, run: 2 } },\n];\n```\nGoogle sheet to copy: \nhttps://docs.google.com/spreadsheets/d/1_u9IxEZINcwKQB15Rfx7C1hM71zeDST58Fz3nRHTCUY/edit?usp=sharing"
      },
      "typeVersion": 1
    },
    {
      "id": "c7610191-4c24-4701-9c3f-bce9feb9e167",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -992,
        1376
      ],
      "parameters": {
        "color": 6,
        "width": 712,
        "height": 860,
        "content": "\n##### Loop Over Items (Split in Batches)\n- Processes items in batches to manage API rate limits\n- **Options**: Keep default settings\n- **Reset**: `false`\n\n##### Create Video (HTTP Request)\n- **Method**: `POST`\n- **URL**: `https://api.freepik.com/v1/ai/image-to-video/minimax-hailuo-02-768p`\n- **Authentication**: Generic \u2192 HTTP Header Auth\n- **Credentials**: Select your \"Header Auth account\"\n- **Send Body**: `true`\n- **Body Parameters**:\n  - **Name**: `prompt`\n  - **Value**: `={{ $json.Prompt }}`\n\n##### Get Video URL (HTTP Request)\n- **Method**: `GET`\n- **URL**: `https://api.freepik.com/v1/ai/image-to-video/minimax-hailuo-02-768p/{{ $json.data.task_id }}`\n- **Authentication**: Generic \u2192 HTTP Header Auth\n- **Credentials**: Select your \"Header Auth account\"\n- **Timeout**: `120000` (2 minutes)\n- **Purpose**: Polls the API for video completion status\n"
      },
      "typeVersion": 1
    },
    {
      "id": "6b1c2572-5143-402b-9bdd-8225b187ee4e",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -256,
        1376
      ],
      "parameters": {
        "color": 3,
        "width": 664,
        "height": 860,
        "content": "\n##### Switch (Switch Node)\n- **Purpose**: Routes workflow based on video generation status\n- **Conditions**:\n  - **Completed**: `{{ $json.data.status }}` equals `COMPLETED`\n  - **Failed**: `{{ $json.data.status }}` equals `FAILED`\n  - **Created**: `{{ $json.data.status }}` equals `CREATED`\n  - **In Progress**: `{{ $json.data.status }}` equals `IN_PROGRESS`\n\n##### Wait (Wait Node)\n- **Amount**: `30` seconds\n- **Purpose**: Waits before re-checking video status\n- **Webhook ID**: Auto-generated for resume functionality\n\n##### Download Video as Base64 (HTTP Request)\n- **Method**: `GET`\n- **URL**: `={{ $json.data.generated[0] }}`\n- **Purpose**: Downloads completed video file\n\n##### Upload to Google Drive1 (Google Drive)\n- **Operation**: Upload\n- **Name**: `=video - {{ $('Get prompt from google sheet').item.json.Name }} - {{ $('Duplicate Rows2').item.json.run }}`\n- **Drive ID**: `My Drive`\n- **Folder ID**: Your Google Drive folder ID (from Step 4)\n- **Credentials**: Select your \"Google Drive account\"\n"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Get Video URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Download Video as Base64",
            "type": "main",
            "index": 0
          }
        ],
        [],
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Video": {
      "main": [
        [
          {
            "node": "Get Video URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Video URL": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Duplicate Rows2": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Create Video",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Upload to Google Drive1": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Download Video as Base64": {
      "main": [
        [
          {
            "node": "Upload to Google Drive1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get prompt from google sheet": {
      "main": [
        [
          {
            "node": "Duplicate Rows2",
            "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 n8n workflow automates bulk AI video generation using Freepik's Image-to-Video API powered by Minimax Hailuo-02-768p. It reads video prompts from a Google Sheet, generates multiple variations of each video using Freepik's AI, handles asynchronous video processing with…

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

More Data & Sheets workflows → · Browse all categories →

Related workflows

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

Data & Sheets

This workflow monitors Google Calendar for events indicating that a customer will visit the company today or the next day, retrieves the required details, and sends reminder notifications to the relev

Google Calendar, Google Sheets, HTTP Request +1
Data & Sheets

PCN. Uses googleSheets, httpRequest, @n-octo-n/n8n-nodes-json-database, itemLists. Event-driven trigger; 60 nodes.

Google Sheets, HTTP Request, @N Octo N/N8N Nodes Json Database +3
Data & Sheets

The workflow automates the process of gathering extensive keyword data for a "Main Keyword." It starts by reading initial parameters from a Google Sheets template, creates a new dedicated Google Sheet

Google Sheets, Google Drive, HTTP Request
Data & Sheets

🔥 March Sale – n8n Community Members Get ideoGener8r for Just $27! (Reg. $47) Use Coupon Code: (Valid until 3/31/2025 for n8n community members)

HTTP Request, Google Drive, Google Sheets
Data & Sheets

📄 Documentation: Notion Guide

Google Sheets, Google Drive, HTTP Request +2