{
  "name": "Turn customer reviews into Videotok UGC ads",
  "nodes": [
    {
      "parameters": {
        "content": "## Review to UGC testimonial ads\n\nFor DTC brands and agencies that want new UGC angles from real customer language.\n\nReplace the sample review with Shopify, Gorgias, Typeform, Airtable, or Google Sheets. Keep review claims compliant and truthful.\n\nRequired variables: VIDEOTOK_API_KEY, OPENAI_API_KEY, VIDEOTOK_BRAND_KIT_ID, VIDEOTOK_AVATAR_ID.",
        "height": 320,
        "width": 500,
        "color": 7
      },
      "id": "note-overview",
      "name": "Overview and compliance",
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [-700, -280]
    },
    {
      "parameters": {},
      "id": "manual",
      "name": "Manual review test",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [-620, 120]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "review",
              "name": "review_text",
              "type": "string",
              "value": "I bought this before a work trip and my skin looked better in three days. It is the first serum I actually finished."
            },
            {
              "id": "product",
              "name": "product_name",
              "type": "string",
              "value": "Vitamin C serum"
            },
            {
              "id": "image",
              "name": "product_image_url",
              "type": "string",
              "value": "https://example.com/product.png"
            }
          ]
        }
      },
      "id": "review-source",
      "name": "Replace with review source",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [-360, 120]
    },
    {
      "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\":\"Convert this customer review into compliant UGC ad JSON. Include title, hook, script, generation_prompt, caption. Preserve truthful customer language and avoid unsupported claims. Input: \" + JSON.stringify($json)}"
      },
      "id": "openai-ugc",
      "name": "OpenAI writes UGC script",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [-80, 120]
    },
    {
      "parameters": {
        "jsCode": "const review = $('Replace with review source').first().json;\nconst raw = $input.first().json.output_text || '{}';\nlet brief;\ntry { brief = JSON.parse(raw); } catch { brief = { title: 'UGC testimonial ad', hook: raw.slice(0, 120), script: raw, generation_prompt: raw, caption: raw.slice(0, 220) }; }\nreturn [{ json: { ...brief, product_image_url: review.product_image_url, idempotency_key: `review-ugc-${$execution.id}` } }];"
      },
      "id": "prepare",
      "name": "Prepare UGC payload",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [200, 120]
    },
    {
      "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": "={\"type\":\"ugc_ad\",\"template_slug\":\"ugc-product-video\",\"prompt\":$json.generation_prompt,\"aspect_ratio\":\"9:16\",\"duration\":8,\"quality_tier\":\"high\",\"avatar_id\":$vars.VIDEOTOK_AVATAR_ID,\"brand_kit_id\":$vars.VIDEOTOK_BRAND_KIT_ID,\"reference_image_urls\":[$json.product_image_url],\"idempotency_key\":$json.idempotency_key}"
      },
      "id": "generate",
      "name": "Create Videotok UGC ad",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [500, 120]
    },
    {
      "parameters": {
        "amount": 90,
        "unit": "seconds"
      },
      "id": "wait",
      "name": "Wait before polling",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [760, 120]
    },
    {
      "parameters": {
        "url": "=https://videotok.app/api/v1/generations/{{$json.id || $json.generation_id}}",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "Authorization",
              "value": "=Bearer {{$vars.VIDEOTOK_API_KEY}}"
            }
          ]
        }
      },
      "id": "poll",
      "name": "Poll UGC status",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [1020, 120]
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "approval",
              "name": "approval_note",
              "type": "string",
              "value": "={{'Review claim compliance before publishing. Caption: ' + $('Prepare UGC payload').first().json.caption}}"
            },
            {
              "id": "url",
              "name": "videotok_url",
              "type": "string",
              "value": "={{$json.url}}"
            }
          ]
        }
      },
      "id": "approval",
      "name": "Prepare approval handoff",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [1280, 120]
    }
  ],
  "connections": {
    "Manual review test": {
      "main": [
        [{ "node": "Replace with review source", "type": "main", "index": 0 }]
      ]
    },
    "Replace with review source": {
      "main": [
        [{ "node": "OpenAI writes UGC script", "type": "main", "index": 0 }]
      ]
    },
    "OpenAI writes UGC script": {
      "main": [[{ "node": "Prepare UGC payload", "type": "main", "index": 0 }]]
    },
    "Prepare UGC payload": {
      "main": [
        [{ "node": "Create Videotok UGC ad", "type": "main", "index": 0 }]
      ]
    },
    "Create Videotok UGC ad": {
      "main": [[{ "node": "Wait before polling", "type": "main", "index": 0 }]]
    },
    "Wait before polling": {
      "main": [[{ "node": "Poll UGC status", "type": "main", "index": 0 }]]
    },
    "Poll UGC status": {
      "main": [
        [{ "node": "Prepare approval handoff", "type": "main", "index": 0 }]
      ]
    }
  },
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "tags": ["videotok", "openai", "ugc", "reviews"],
  "active": false,
  "versionId": "videotok-review-to-ugc-ads-1"
}
