{
  "id": "R92VazF8o6NMCa9L",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true
  },
  "name": "Translate YouTube video titles and descriptions to multiple languages with OpenAI",
  "tags": [],
  "nodes": [
    {
      "id": "7e9a50bb-1332-4e5c-aa2e-683098a32300",
      "name": "Run workflow",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        0,
        0
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "707433a7-de32-45b3-8a7e-ba436fd2d554",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        224,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "cfg-video-id",
              "name": "video_id",
              "type": "string",
              "value": "REPLACEME"
            },
            {
              "id": "cfg-default-lang",
              "name": "default_language",
              "type": "string",
              "value": "en"
            },
            {
              "id": "cfg-openai-model",
              "name": "openai_model",
              "type": "string",
              "value": "gpt-4.1-mini"
            },
            {
              "id": "cfg-target-langs",
              "name": "target_languages",
              "type": "object",
              "value": {
                "english": "en",
                "spanish": "es-419",
                "japanese": "ja"
              }
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "498a0de9-2340-4305-8eb4-67241dfbc68f",
      "name": "Fetch video information",
      "type": "n8n-nodes-base.youTube",
      "position": [
        464,
        0
      ],
      "parameters": {
        "part": [
          "id",
          "snippet",
          "localizations",
          "status"
        ],
        "options": {},
        "videoId": "={{ $('Configuration').item.json.video_id }}",
        "resource": "video",
        "operation": "get"
      },
      "typeVersion": 1
    },
    {
      "id": "c139269e-af8f-4e0c-bec2-8b9b6d663f21",
      "name": "Prepare target languages",
      "type": "n8n-nodes-base.code",
      "position": [
        704,
        0
      ],
      "parameters": {
        "jsCode": "const video = $input.first().json;\nconst defaultLang = video?.snippet?.defaultLanguage || $('Configuration').first().json.default_language || 'en';\nconst nameToCode = $('Configuration').first().json.target_languages || {};\nconst entries = Object.entries(nameToCode).filter(([, code]) => code !== defaultLang);\nconst languages = entries.map(([name]) => name);\nconst keys = Object.fromEntries(entries);\nreturn [{ json: { defaultLang, languages, keys } }];"
      },
      "typeVersion": 2
    },
    {
      "id": "314554cd-ab06-44da-b453-06b5c80cdf87",
      "name": "AI translator",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        992,
        0
      ],
      "parameters": {
        "text": "=Translate the YouTube video metadata whose default language is {{ $json.defaultLang }} into these languages: {{ $json.languages }}.\n\nUse exactly these language keys in the output JSON: {{ JSON.stringify($json.keys) }}\n\nTitle: {{ $('Fetch video information').item.json.snippet.title }}\n\nDescription: {{ $('Fetch video information').item.json.snippet.description }}\n\nReturn ONLY a JSON object. Each key is a language code, each value is an object with a translated \"title\" and \"description\". Do not translate the default language. Keep line breaks and meaning faithful.",
        "options": {
          "systemMessage": "You are a professional translator for YouTube metadata. You translate titles and descriptions faithfully, preserve formatting and line breaks, and you always return valid JSON only, with no extra commentary."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3.1
    },
    {
      "id": "58291421-7d3f-4d76-b15f-856fef376adc",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        992,
        240
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Configuration').first().json.openai_model }}"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "eaf5dd80-efb8-431a-a477-55279bcfd8c9",
      "name": "Translation output parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1168,
        240
      ],
      "parameters": {
        "schemaType": "manual",
        "inputSchema": "{\n  \"type\": \"object\",\n  \"additionalProperties\": {\n    \"type\": \"object\",\n    \"properties\": {\n      \"title\": { \"type\": \"string\" },\n      \"description\": { \"type\": \"string\" }\n    },\n    \"required\": [\"title\", \"description\"]\n  }\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "3f55cc34-ef8c-447f-b2d5-afccd08f78b6",
      "name": "Update video localization",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1376,
        0
      ],
      "parameters": {
        "url": "https://www.googleapis.com/youtube/v3/videos?part=snippet,localizations",
        "method": "PUT",
        "options": {},
        "jsonBody": "={{ {\n  id: $('Fetch video information').item.json.id,\n  snippet: {\n    defaultLanguage: $('Prepare target languages').item.json.defaultLang,\n    title: $('Fetch video information').item.json.snippet.title,\n    description: $('Fetch video information').item.json.snippet.description,\n    categoryId: $('Fetch video information').item.json.snippet.categoryId,\n    tags: $('Fetch video information').item.json.snippet.tags\n  },\n  localizations: $json.output\n} }}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "youTubeOAuth2Api"
      },
      "typeVersion": 4.4
    },
    {
      "id": "2d16a2c3-3910-4c5e-8770-2a0f03770a9f",
      "name": "Build localization URL",
      "type": "n8n-nodes-base.set",
      "position": [
        1616,
        0
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "url-out",
              "name": "localization_url",
              "type": "string",
              "value": "=https://studio.youtube.com/video/{{ $('Fetch video information').item.json.id }}/translations"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "1a183173-99e7-4848-a186-482ad988497e",
      "name": "Sticky Note 8e113d45",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -912,
        -208
      ],
      "parameters": {
        "width": 852,
        "height": 2060,
        "content": "# Translate YouTube video titles and descriptions to multiple languages with OpenAI\n\n# \ud83d\udce5  [Open full documentation on Notion](https://automatisation.notion.site/Translate-YouTube-video-titles-and-descriptions-to-multiple-languages-with-OpenAI-Course-support-EN-3993d6550fd981c997cfc26dbe14d58a)\n\nIf you want to reach a wider audience, having your video titles and descriptions in multiple languages helps you connect with more viewers. This template generates the translations with OpenAI and writes them straight back to YouTube as native localizations.\n\n## How it works\n- **Configuration** groups every value you may want to change (video ID, default language, target languages, OpenAI model) in one place.\n- **Fetch video information** retrieves the current title, description, category and tags from YouTube, whether the video is public or not.\n- **Prepare target languages** removes the default language from the target list so you only translate what you actually need.\n- **AI translator** translates the title and description into every target language and returns clean JSON.\n- **Update video localization** sends the original default language plus all translations back to YouTube in a single API call.\n- **Build localization URL** returns the YouTube Studio URL where you can review the result.\n\n\u26a0 A translation overwrites any existing translation for the same language.\n\n## Setup\n1. (First time only) Connect the two credentials: YouTube OAuth2 and OpenAI.\n2. Open **Configuration** and set `video_id` to your video ID (the part of the URL between \"/\" and \"?si=\").\n3. Adjust `target_languages` and `default_language` if needed.\n4. Click **Execute workflow** and review the translations in YouTube Studio.\n\n## Requirements\n- A YouTube account with a **YouTube OAuth2** credential (free tier is enough).\n- An **OpenAI** credential.\n- n8n Cloud or self-hosted. No paid plan required; mind the API rate limits if you extend this to many videos at once.\n\n## Customization\n- Change `openai_model` in **Configuration** to trade quality for cost.\n- Add or remove languages in `target_languages` (name \u2192 language code).\n- Refine the translator prompt to match your tone, but keep the JSON output structure unchanged.\n\n## Need help customizing?\nContact me for consulting and support : [Linkedin](https://www.linkedin.com/in/doctor-firass/)\n\n# MY NEW YOUTUBE CHANNEL\n\ud83d\udc49 [Subscribe to my new YouTube channel](https://www.youtube.com/@DrFiras_AI). Here I'll share videos and Shorts with practical tutorials and FREE templates for n8n.\n\n[![The AI Doctor](https://www.dr-firas.com/the-ai-doctor.png)](https://www.youtube.com/@DrFiras_AI)"
      },
      "typeVersion": 1
    },
    {
      "id": "a285f9df-07e2-4d12-984e-7980d9312b6f",
      "name": "Sticky Note 85b8b34d",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -16,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 166,
        "content": "## 1. Set your video and languages\nEdit **Configuration** only: your video ID, the default language and the target languages (name \u2192 code). Nothing else is hardcoded downstream."
      },
      "typeVersion": 1
    },
    {
      "id": "8729d568-c2ad-42e1-a33d-8710eb3220ea",
      "name": "Sticky Note d3373b2b",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        464,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 460,
        "height": 166,
        "content": "## 2. Fetch and prepare\nGet the video metadata from YouTube, then drop the default language from the list to translate."
      },
      "typeVersion": 1
    },
    {
      "id": "3189ad00-dd18-42d9-b8e2-73ea3fd8bb55",
      "name": "Sticky Note 8c46a79b",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        928,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 388,
        "height": 620,
        "content": "## 3. Translate with AI\nThe AI translator (OpenAI) returns one JSON object with a title and description per target language."
      },
      "typeVersion": 1
    },
    {
      "id": "3ede7fff-7b18-47c8-b755-2481c6c4f304",
      "name": "Sticky Note c14ea32e",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1328,
        -208
      ],
      "parameters": {
        "color": 7,
        "width": 520,
        "height": 150,
        "content": "## 4. Write back to YouTube\nPush the default language + translations back to the video, then output the YouTube Studio URL to review them."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "bcb1f526-9b1f-4d2a-827a-e3f12f278fc9",
  "nodeGroups": [],
  "connections": {
    "Run workflow": {
      "main": [
        [
          {
            "node": "Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI translator": {
      "main": [
        [
          {
            "node": "Update video localization",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configuration": {
      "main": [
        [
          {
            "node": "Fetch video information",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI translator",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Fetch video information": {
      "main": [
        [
          {
            "node": "Prepare target languages",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare target languages": {
      "main": [
        [
          {
            "node": "AI translator",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Translation output parser": {
      "ai_outputParser": [
        [
          {
            "node": "AI translator",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Update video localization": {
      "main": [
        [
          {
            "node": "Build localization URL",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}