How to Generate AI Video with Google Veo 3 in n8n

This guide walks Awesomate members through connecting Google's Veo 3 AI video generation model to n8n, so you can automate the creation of high-quality video clips as part of your workflows.



What is Google Veo 3?

Veo 3 is Google's AI video generation model. You give it a text description (called a "prompt") and it creates a short, high-quality video clip — typically 8 seconds long — complete with audio, sound effects, and even dialogue.

Think of it like having a mini film studio that turns your written ideas into video content automatically.

Why Use It in n8n?

By connecting Veo 3 to your n8n workflows inside Awesomate, you can automate video creation as part of a larger process. For example:

  • Automatically generate a product promo video when a new item is added to your store
  • Create social media video content on a schedule
  • Generate video summaries from blog post content
  • Build a workflow where a client fills in a form and receives a custom video


What You'll Need Before You Start

Make sure you have these ready before beginning:

  1. A Google account (any Gmail account works)
  2. A credit card or debit card (for Google Cloud billing)
  3. Access to your Awesomate n8n instance
  4. About 30 minutes to set everything up

⚠️ Important — Costs: Veo 3 is a paid API. There is no free tier for video generation. Current pricing:

  • Veo 3.1 Fast: ~$0.15 per second = ~$1.20 per 8-second video
  • Veo 3.1 Standard: ~$0.40 per second = ~$3.20 per 8-second video
  • Veo 3.0 Full: ~$0.75 per second = ~$6.00 per 8-second video

New Google Cloud accounts may receive $300 in free credits (valid for 90 days). You are only charged for videos that are successfully generated.



Part 1: Get Your Google Gemini API Key

The Veo 3 video model is accessed through Google's Gemini API. You need an API key to use it.

Step-by-Step: Create Your API Key

  1. Go to Google AI Studio. Open your browser and navigate to aistudio.google.com.
  2. Sign in. Click "Sign in" and use your Google account.
  3. Find the API Key section. Look for "Get API key" in the left-hand sidebar or top navigation.
  4. Create a new key. Click "Create API key in new project". Google will create a new cloud project automatically.
  5. Copy your API key. Your key will appear on screen — it starts with AIza. Copy it immediately and save it somewhere safe, like a password manager. You'll need it later.

🔒 Security tip: Treat your API key like a password. Never share it publicly, post it in forums, or commit it to public code repositories. Anyone with your key can generate videos and you'll be charged.



Part 2: Enable Billing (Required for Video Generation)

Veo 3 is only available on the paid tier of the Gemini API. Even with an API key, video generation won't work until billing is enabled.

Step-by-Step: Set Up Billing

  1. Go to the Google Cloud Console. Visit console.cloud.google.com.
  2. Select your project. In the top dropdown, find and select the project created when you made your API key (it may be named something like "Generative Language Client").
  3. Navigate to Billing. In the left sidebar, click "Billing". If prompted, click "Link a billing account".
  4. Create a billing account. Follow the prompts to add your card details. New accounts may receive $300 in free credits.
  5. Confirm billing is linked. Once complete, your project should show as linked to a billing account, upgrading your API key to the paid tier.

ℹ️ Note: Google may require a small prepayment to activate the paid tier. This is applied as credit to your account — not a fee.



Part 3: Build the Video Generation Workflow in n8n

Now for the fun part. We're going to build an n8n workflow that sends a prompt to Veo 3, waits for the video to be generated, then downloads the finished video file.

The workflow uses 3 main stages because video generation is not instant — it typically takes 2–5 minutes. The process is:

  • Stage 1: Submit your video prompt to Google (you receive an "operation ID" in return)
  • Stage 2: Keep checking if the video is ready (called "polling")
  • Stage 3: Download the finished video file


Node 1: Trigger

You can start this workflow however suits your use case:

  • Manual Trigger — for testing, just click "Execute Workflow"
  • Webhook Trigger — so another system can call it with a prompt
  • Schedule Trigger — to generate videos on a timed schedule
  • Form Trigger — so someone can type a prompt via a web form

For testing, use the Manual Trigger node.



Node 2: Set Node — Define Your Prompt

Add a Set node after your trigger. Configure it with these two fields:

Field 1 — prompt (String)

Your video description. Be descriptive! Example:

A slow aerial drone shot over a tropical beach at sunset. Golden light reflects off gentle waves. A few palm trees sway in a light breeze. Calm ambient music plays softly.

Field 2 — model (String)

Set this to one of the following:

Model Name
Speed / Cost
Best For
veo-3.1-fast-generate-preview
Fastest / ~$1.20 per video
Testing, social media, quick drafts
veo-3.1-generate-preview
Moderate / ~$3.20 per video
Professional content, marketing

💡 Recommendation: Start with veo-3.1-fast-generate-preview while testing. Switch to the standard model once you're happy with your prompts.



Node 3: HTTP Request — Submit Video Generation

Add an HTTP Request node to send your prompt to Google and start generating the video.

Configuration:

  • Method: POST
  • URL:
https://generativelanguage.googleapis.com/v1beta/models/{{ $json.model }}:predictLongRunning

(This expression pulls in the model name from your Set node.)

  • Send Query Parameters: ON

    • Name: key | Value: your Gemini API key
  • Send Headers: ON

    • Name: Content-Type | Value: application/json
  • Send Body: ON | Body Content Type: JSON

JSON Body:

{
  "instances": [
    {
      "prompt": "{{ $json.prompt }}"
    }
  ]
}

ℹ️ What this does: This sends your prompt to Google and returns an "operation name" — a ticket number Google uses to track your video. The video is not ready yet at this point.



Node 4: Wait Node

Add a Wait node after the HTTP Request.

  • Wait Amount: 30
  • Wait Unit: Seconds

This gives Google time to start processing before you check on it.



Node 5: HTTP Request — Check if Video is Ready

Add another HTTP Request node to poll the status of your video.

Configuration:

  • Method: GET
  • URL:
https://generativelanguage.googleapis.com/v1beta/{{ $('Submit Video Generation').first().json.name }}

⚠️ Important: Replace the node name in the expression with the actual name of your first HTTP Request node if you renamed it.

  • Send Query Parameters: ON
    • Name: key | Value: your Gemini API key

The response includes a field called done. If it's true, the video is ready. If it's false or missing, the video is still being generated.



Node 6: IF Node — Is the Video Ready?

Add an IF node after the polling request.

Condition:

  • Value 1: {{ $json.done }}
  • Operation: is equal to
  • Value 2: true

This creates two branches:

  • TRUE → The video is ready. Continue to download.
  • FALSE → The video isn't ready yet. Loop back and wait again.

Connect the FALSE output back to the Wait node (Node 4). This creates a polling loop:

Wait 30s → Check status → Not ready? → Wait again → Check again...

This loop runs until the video is ready — typically 4–10 loops (2–5 minutes).

💡 Tip: To prevent infinite loops, you can add a loop counter in the Set node and stop after 20 attempts (10 minutes). For most cases, Google finishes well within that window.



Node 7: HTTP Request — Download the Video (TRUE Branch)

Connect this node to the TRUE output of the IF node.

Configuration:

  • Method: GET
  • URL:
{{ $json.response.generateVideoResponse.generatedSamples[0].video.uri }}

  • Send Query Parameters: ON

    • Name: key | Value: your Gemini API key
  • Options → Response:

    • Response Format: File
    • Output File Name: generated-video.mp4

This downloads the finished video as an MP4 file, ready to use in the rest of your workflow.



Complete Workflow Summary

[Trigger]
    ↓
[Set Node] — Define prompt + model name
    ↓
[HTTP Request] — POST to submit video generation
    ↓
[Wait] — 30 seconds
    ↓
[HTTP Request] — GET to check status
    ↓
[IF] — Is done = true?
    ↓ TRUE                    ↓ FALSE
[HTTP Request]           [Loop back to Wait]
Download video
    ↓
[Next steps: Save, email, upload, etc.]



Import the Starter Workflow (Copy & Paste)

Instead of building this from scratch, you can import a ready-made starter workflow directly into your n8n instance.

Preview


How to import:

  1. Copy the entire JSON block below
  2. Open your n8n instance
  3. Create a new workflow
  4. Press Ctrl+V (or Cmd+V on Mac) to paste it onto the canvas
  5. All the nodes and connections will appear automatically
  6. Replace YOUR_GEMINI_API_KEY_HERE in the three HTTP Request nodes with your actual API key (see Part 1 above)

⚠️ Important: You MUST replace the placeholder API key YOUR_GEMINI_API_KEY_HERE in three places before running the workflow. Use Ctrl+F / Cmd+F to find and replace all instances.

{
  "name": "Veo 3 - Generate AI Video",
  "nodes": [
    {
      "parameters": {},
      "id": "a1b2c3d4-0001-4000-8000-000000000001",
      "name": "Manual Trigger",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [0, 0]
    },
    {
      "parameters": {
        "mode": "manual",
        "duplicateItem": false,
        "assignments": {
          "assignments": [
            {
              "id": "prompt-field",
              "name": "prompt",
              "value": "A cinematic slow-motion shot of a barista pouring latte art in a cosy coffee shop. Warm natural light streams through the window. The camera slowly pulls back to reveal the full café interior with exposed brick walls and hanging plants. Soft jazz music plays in the background. Professional food photography style, shallow depth of field.",
              "type": "string"
            },
            {
              "id": "model-field",
              "name": "model",
              "value": "veo-3.1-fast-generate-preview",
              "type": "string"
            }
          ]
        }
      },
      "id": "a1b2c3d4-0002-4000-8000-000000000002",
      "name": "Set Prompt & Model",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [220, 0],
      "notesInFlow": true,
      "notes": "Edit the prompt and model here. Use veo-3.1-fast-generate-preview for cheap/fast or veo-3.1-generate-preview for higher quality."
    },
    {
      "parameters": {
        "method": "POST",
        "url": "=https://generativelanguage.googleapis.com/v1beta/models/{{ $json.model }}:predictLongRunning",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "key",
              "value": "YOUR_GEMINI_API_KEY_HERE"
            }
          ]
        },
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\n  \"instances\": [\n    {\n      \"prompt\": \"{{ $json.prompt }}\"\n    }\n  ]\n}",
        "options": {}
      },
      "id": "a1b2c3d4-0003-4000-8000-000000000003",
      "name": "Submit Video Generation",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [440, 0],
      "notesInFlow": true,
      "notes": "Sends the prompt to Google. Returns an operation name (job ID)."
    },
    {
      "parameters": {
        "amount": 30,
        "unit": "seconds"
      },
      "id": "a1b2c3d4-0004-4000-8000-000000000004",
      "name": "Wait 30s",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [660, 0],
      "webhookId": "veo3-wait-webhook"
    },
    {
      "parameters": {
        "method": "GET",
        "url": "=https://generativelanguage.googleapis.com/v1beta/{{ $('Submit Video Generation').first().json.name }}",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "key",
              "value": "YOUR_GEMINI_API_KEY_HERE"
            }
          ]
        },
        "options": {}
      },
      "id": "a1b2c3d4-0005-4000-8000-000000000005",
      "name": "Check Video Status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [880, 0],
      "notesInFlow": true,
      "notes": "Polls Google to see if the video is finished generating."
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict"
          },
          "conditions": [
            {
              "id": "condition-done-check",
              "leftValue": "={{ $json.done }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "a1b2c3d4-0006-4000-8000-000000000006",
      "name": "Video Ready?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [1100, 0]
    },
    {
      "parameters": {
        "method": "GET",
        "url": "={{ $json.response.generateVideoResponse.generatedSamples[0].video.uri }}",
        "sendQuery": true,
        "queryParameters": {
          "parameters": [
            {
              "name": "key",
              "value": "YOUR_GEMINI_API_KEY_HERE"
            }
          ]
        },
        "options": {
          "response": {
            "response": {
              "responseFormat": "file",
              "outputPropertyName": "data"
            }
          }
        }
      },
      "id": "a1b2c3d4-0007-4000-8000-000000000007",
      "name": "Download Video",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1320, -100],
      "notesInFlow": true,
      "notes": "Downloads the finished MP4 video file. Connect your next steps after this node (e.g. Google Drive, Email, etc.)"
    }
  ],
  "connections": {
    "Manual Trigger": {
      "main": [
        [
          {
            "node": "Set Prompt & Model",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Prompt & Model": {
      "main": [
        [
          {
            "node": "Submit Video Generation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Submit Video Generation": {
      "main": [
        [
          {
            "node": "Wait 30s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 30s": {
      "main": [
        [
          {
            "node": "Check Video Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Video Status": {
      "main": [
        [
          {
            "node": "Video Ready?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Video Ready?": {
      "main": [
        [
          {
            "node": "Download Video",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Wait 30s",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  },
  "pinData": {}
}

💡 After importing: The workflow comes with a sample coffee shop prompt. Edit the "Set Prompt & Model" node to change the prompt to whatever you'd like. To switch to the higher-quality model, change the model value from veo-3.1-fast-generate-preview to veo-3.1-generate-preview.



Optional: Customise Your Video Settings

Aspect Ratio

Add a parameters block to the JSON body in Node 3:

{
  "instances": [
    {
      "prompt": "{{ $json.prompt }}"
    }
  ],
  "parameters": {
    "aspectRatio": "9:16"
  }
}

Use 16:9 for landscape (YouTube, website headers) or 9:16 for portrait (Instagram Reels, TikTok, YouTube Shorts).

Resolution

"parameters": {
  "aspectRatio": "16:9",
  "resolution": "1080p"
}

Higher resolution = higher cost and longer generation time. 720p is the default and is perfectly fine for social media.

Negative Prompts

Tell Veo what to avoid by adding a negativePrompt inside the instances block:

"instances": [
  {
    "prompt": "your video description here",
    "negativePrompt": "blurry, shaky camera, text overlays"
  }
]



Tips for Writing Great Video Prompts

  1. Be specific about the scene. Instead of "a beach", say "a quiet tropical beach with white sand and turquoise water at golden hour."
  2. Describe the camera movement. Use terms like "slow pan", "drone shot", "close-up", "tracking shot", "dolly forward".
  3. Include audio descriptions. Veo 3 generates audio too — say things like "calm piano music", "ocean waves crashing", "upbeat electronic music."
  4. Mention the mood or style. Words like "cinematic", "documentary style", "dreamlike", or "professional corporate" help guide the output.
  5. Include dialogue if needed. You can write dialogue directly in the prompt, e.g. "A woman says, 'Welcome to our store!'"
  6. Keep it under 200 words. Be concise but descriptive — longer prompts don't always mean better results.


Example prompt:
A cinematic slow-motion shot of a barista pouring latte art in a cosy coffee shop. Warm natural light streams through the window. The camera slowly pulls back to reveal the full café interior with exposed brick walls and hanging plants. Soft jazz music plays in the background. Professional food photography style, shallow depth of field.




Storing Your API Key Securely in n8n

Rather than pasting your API key into each HTTP Request node, store it as a reusable credential:

  1. In n8n, go to Credentials in the left sidebar and click Add Credential.
  2. Choose Header Auth as the credential type.
  3. Set the Name to x-goog-api-key and the Value to your Gemini API key.
  4. In each HTTP Request node, set Authentication to Generic Credential Type → Header Auth and select your saved credential.

If you use this method, remove the key query parameter from your HTTP Request nodes — the key will be sent as a header automatically.



Troubleshooting


403 Forbidden / Permission Denied
Billing is not set up correctly, or your API key doesn't have paid tier access. Return to Part 2 and confirm billing is linked to your project.



400 Bad Request
Check your JSON body for syntax errors. Make sure your prompt doesn't contain unescaped double quotes — use single quotes or escape them if needed.



429 Too Many Requests
You've hit a rate limit. Wait a minute and try again, or increase the Wait time between polls.



Video generation stuck (10+ minutes)
Cancel the workflow and try again. If it keeps happening, try a simpler prompt or switch to the Fast model.



Downloaded file is empty or corrupted
Make sure the Response Format in the download node is set to File (not JSON). Also verify the video URI expression is correct.



API key not valid
Make sure you copied the full key including the AIza prefix. Trailing spaces can also cause issues — try regenerating a new key in Google AI Studio.




Managing Costs

  • Use the Fast model for testing — ~$1.20 per video vs $3.20+ for standard
  • Perfect your prompts in Google AI Studio before automating them in n8n to avoid wasting money on bad outputs
  • Set up budget alerts in Google Cloud Console under Billing → Budgets & Alerts
  • Remember: you're only charged for successfully generated videos
  • 720p is usually sufficient for social media — higher resolution costs more
  • Portrait (9:16) and landscape (16:9) videos are the same price


What to Do Next

Once your basic workflow is running, here are some ideas for extending it:

  • Save to Google Drive — Add a Google Drive node to automatically save each video to a specific folder
  • Post to social media — Connect to YouTube, Instagram, or TikTok via their APIs
  • AI-powered prompts — Use a Gemini or OpenAI node to automatically write video prompts from blog posts or product descriptions
  • Email the video — Attach the downloaded video to an automated email
  • Build a video factory — Loop through multiple prompts to batch-generate several videos in one workflow run


Need Help?

  • Join the Awesomate weekly n8n webinar for live Q&A — recordings available at awesomate.helpdocsite.com/webinars
  • Reach out to the Awesomate support team via your member portal
  • Check the Google Gemini API documentation at ai.google.dev/gemini-api/docs/video for the latest API details

Happy automating! 🚀