{
  "name": "Generate brand ad campaign variants with Videotok",
  "nodes": [
    {
      "parameters": {
        "content": "## Generate brand ad campaign variants with Videotok\n\n### How it works\n\n1. The workflow is triggered manually. \n2. Campaign details including brand name and brief are set. \n3. Campaign brief data is sent to OpenAI to generate variants. \n4. The generated variants are prepared for Videotok. \n5. Prepared variants are sent to Videotok API to create the final ad content.\n\n### Setup steps\n\n- [ ] Ensure access to the OpenAI API and get the API key.\n- [ ] Ensure access to the Videotok API and get the API key.\n\n### Customization\n\nUser can customize the campaign details to generate different ad variants. Before activating the workflow, test it with one item, review the generated creative in Videotok, and confirm the brand, platform, and publishing requirements.",
        "width": 480,
        "height": 640
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-1232, 0],
      "id": "5f20badb-2342-4b3d-ad44-741d2014fac2",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## Trigger and set details\n\nManually triggers the workflow and sets initial campaign details like brand name and campaign brief.",
        "width": 464,
        "height": 304,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-672, 0],
      "id": "090c0cd7-c000-42f8-9221-e3a34aec8277",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "## Generate and build variants\n\nSends data to OpenAI for variant generation and prepares these variants using custom code.",
        "width": 816,
        "height": 272,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-128, 16],
      "id": "ae23617f-8baf-476d-9324-6be3c23f2953",
      "name": "Sticky Note2"
    },
    {
      "parameters": {},
      "id": "manual",
      "name": "When Campaign Brief Ready",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [-624, 128]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "brand",
              "name": "brand_name",
              "type": "string",
              "value": "Northstar"
            },
            {
              "id": "brief",
              "name": "campaign_brief",
              "type": "string",
              "value": "Launch campaign for an AI tool that helps teams produce social ads faster"
            },
            {
              "id": "image",
              "name": "hero_image_url",
              "type": "string",
              "value": "https://example.com/brand-hero.png"
            }
          ]
        }
      },
      "id": "campaign-source",
      "name": "Set Campaign Parameters",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [-352, 128]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://api.openai.com/v1/responses",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{$vars.OPENAI_API_KEY}}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={\"model\":\"gpt-4.1-mini\",\"input\":\"Create paid social ad variant JSON for a brand campaign. Return an array called variants with angle, format, prompt, caption. Include 4 variants. Input: \" + JSON.stringify($json)}"
      },
      "id": "openai-variants",
      "name": "Submit to OpenAI for Variants",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [-80, 128]
    },
    {
      "parameters": {
        "jsCode": "const source = $('Set Campaign Parameters').first().json;\nconst raw = $input.first().json.output_text || '{}';\nlet parsed;\ntry { parsed = JSON.parse(raw); } catch { parsed = { variants: [{ angle: 'Launch', format: 'video', prompt: raw, caption: raw }] }; }\nconst variants = Array.isArray(parsed.variants) ? parsed.variants : [];\nreturn variants.map((variant, index) => ({ json: { type: variant.format === 'static' ? 'static_ad' : 'video_ad', template_slug: variant.format === 'static' ? 'product-shoot' : 'viral-video-ads', prompt: variant.prompt, aspect_ratio: '9:16', duration: 8, quality_tier: 'high', reference_image_urls: [source.hero_image_url], brand_kit_id: $vars.VIDEOTOK_BRAND_KIT_ID, idempotency_key: `brand-campaign-${index}-${$execution.id}` } }));"
      },
      "id": "prepare-variants",
      "name": "Create Videotok Variants",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [224, 128]
    },
    {
      "parameters": {
        "method": "POST",
        "url": "https://videotok.app/api/v1/generations",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{$vars.VIDEOTOK_API_KEY}}"
            },
            {
              "name": "Content-Type",
              "value": "application/json"
            },
            {
              "name": "Idempotency-Key",
              "value": "={{$json.idempotency_key}}"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{$json}}"
      },
      "id": "create-variants",
      "name": "Send Variants to Videotok API",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [544, 128]
    }
  ],
  "connections": {
    "When Campaign Brief Ready": {
      "main": [
        [
          {
            "node": "Set Campaign Parameters",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Campaign Parameters": {
      "main": [
        [
          {
            "node": "Submit to OpenAI for Variants",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Submit to OpenAI for Variants": {
      "main": [
        [
          {
            "node": "Create Videotok Variants",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Videotok Variants": {
      "main": [
        [
          {
            "node": "Send Variants to Videotok API",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "tags": ["videotok", "openai", "brand ads", "campaign variants"],
  "active": false,
  "versionId": "videotok-brand-ad-campaign-variant-factory-1"
}
