This workflow corresponds to n8n.io template #13541 — we link there as the canonical source.
This workflow follows the HTTP Request → OpenAI 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 →
{
"nodes": [
{
"id": "ae0639dc-3064-4489-99ce-34c7ae49c1ed",
"name": "\ud83d\udccb Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-128,
-656
],
"parameters": {
"width": 620,
"height": 588,
"content": "\ud83d\udecd\ufe0f AI Product Catalog Architect\nThe Problem: Manual product entry\u2014uploading, resizing, and writing descriptions\u2014is a bottleneck for e-commerce growth.\nThe Solution: A mobile-to-store pipeline that hosts images via UploadToURL, generates SEO content via Vision AI, and creates listings on Shopify or WooCommerce.\n\n\u2699\ufe0f How it Works\nWebhook: Receives image (Binary or URL) + SKU/Price metadata.\n\nUploadToURL: Instantly hosts the image and returns a CDN link.\n\nGPT-4o Vision: Analyzes the photo to write titles, descriptions, and tags.\n\nStore Integration: Creates the product listing directly in your store.\n\n\ud83d\udd10 Credentials & Setup\nNode: Install n8n-nodes-uploadtourl (Community Node).\n\nAPIs: UploadToURL, OpenAI (GPT-4o), and Shopify/WooCommerce.\n\nVariable: Set DEFAULT_PLATFORM to shopify or woocommerce."
},
"typeVersion": 1
},
{
"id": "e1482d72-5e54-4f41-ad4a-776593008d19",
"name": "Entry & Validation",
"type": "n8n-nodes-base.stickyNote",
"position": [
640,
-80
],
"parameters": {
"color": 7,
"width": 576,
"height": 578,
"content": "## \ud83d\udeaa Entry & Validation\n**Nodes:** Webhook \u2192 Validate & Enrich \u2192 Has Remote URL?\n\n- Accepts `POST` with product metadata + either a `fileUrl` (remote) or binary file attachment\n- Validates required fields: needs at least `filename` or `fileUrl` plus a valid `platform` value\n- Sanitises SKU (uppercased, stripped of special chars), coerces price to float, defaults inventory to 1\n- Detects image MIME type from extension for correct Content-Type downstream\n- IF branch routes to the right upload path without duplicating logic"
},
"typeVersion": 1
},
{
"id": "5d68e82d-7573-4d9c-9338-64f7d1371876",
"name": "Upload + Vision AI",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
-144
],
"parameters": {
"color": 7,
"width": 896,
"height": 722,
"content": "## \u2601\ufe0f Upload to URL \u2192 Vision AI\n**Nodes:** Upload to URL (\u00d72) \u2192 Extract URL \u2192 GPT-4o Vision \u2192 Parse AI Response\n\n- Native **Upload to URL** community node handles both URL-fetch and binary-upload paths \u2014 no custom HTTP node needed\n- `Extract URL` normalises the response shape across both paths\n- GPT-4o Vision receives the **actual image URL** and generates: product title, SEO meta description, 5 bullet features, suggested category, tags array, and a short marketing blurb\n- `Parse AI Response` validates and flattens the JSON, merges with original metadata, and computes `handle` (URL slug) from the AI title"
},
"typeVersion": 1
},
{
"id": "114fad13-8471-41da-9db2-8af369336a5d",
"name": "Platform Routing",
"type": "n8n-nodes-base.stickyNote",
"position": [
2160,
-224
],
"parameters": {
"color": 7,
"width": 592,
"height": 770,
"content": "## \ud83c\udfea Platform Routing & Product Creation\n**Nodes:** Route by Platform \u2192 Shopify Create \u2192 WooCommerce Create\n\n- Switch node reads `platform` field (`shopify` or `woocommerce`) \u2014 extend with more outputs for other platforms\n- **Shopify branch:** creates product via GraphQL-compatible REST body with `images` array pre-set to the UploadToURL CDN link, sets `status: active` or `draft` based on `publishImmediately`\n- **WooCommerce branch:** creates product with `images[0].src` set to the CDN link, maps all AI-generated fields to WC schema including `short_description` and `tags`\n- Both branches pass `compare_at_price` / `regular_price` for sale display"
},
"typeVersion": 1
},
{
"id": "b44b85fd-fe8f-4b18-b947-78d38570875c",
"name": "Notification & Response",
"type": "n8n-nodes-base.stickyNote",
"position": [
2768,
-208
],
"parameters": {
"color": 7,
"width": 480,
"height": 654,
"content": "## \ud83d\udce3 Notification & Response\n**Nodes:** Build Response \u2192 Slack Notifier \u2192 Respond to Webhook\n\n- `Build Response` merges platform API reply with product metadata into a clean summary object\n- **Slack Notifier** posts a formatted message with product name, image thumbnail link, store URL, SKU, and price \u2014 easy to disable if not needed\n- Final webhook response returns `productId`, `productUrl`, `imageUrl`, `title`, `sku`, `platform` \u2014 ready to consume by a mobile app or Zapier downstream"
},
"typeVersion": 1
},
{
"id": "016d11e3-a873-4796-806f-5d6f9b036420",
"name": "Webhook - Receive Product",
"type": "n8n-nodes-base.webhook",
"notes": "Accepts POST with product metadata + fileUrl or binary image. Supports both mobile uploads and remote URL ingestion.",
"position": [
672,
224
],
"parameters": {
"path": "product-catalog-upload",
"options": {
"allowedOrigins": "*"
},
"httpMethod": "POST",
"responseMode": "responseNode"
},
"typeVersion": 2
},
{
"id": "14fe3281-67a8-4ce6-84c3-6fea8102a6e8",
"name": "Validate & Enrich Payload",
"type": "n8n-nodes-base.code",
"position": [
880,
224
],
"parameters": {
"jsCode": "const body = $input.first().json.body || $input.first().json;\n\n// --- Platform validation ---\nconst allowedPlatforms = ['shopify', 'woocommerce'];\nconst platform = (body.platform || $vars.DEFAULT_PLATFORM || 'shopify').toLowerCase();\nif (!allowedPlatforms.includes(platform)) {\n throw new Error(`Invalid platform \"${platform}\". Must be: ${allowedPlatforms.join(' | ')}`);\n}\n\n// --- File source validation ---\nif (!body.fileUrl && !body.filename) {\n throw new Error('Provide either fileUrl (remote image) or filename (for binary upload).');\n}\n\n// --- Filename & MIME detection ---\nconst filename = body.filename || body.fileUrl?.split('?')[0].split('/').pop() || 'product.jpg';\nconst ext = filename.split('.').pop()?.toLowerCase() || 'jpg';\nconst mimeMap = { jpg: 'image/jpeg', jpeg: 'image/jpeg', png: 'image/png', webp: 'image/webp', gif: 'image/gif', avif: 'image/avif' };\nconst mimeType = mimeMap[ext] || 'image/jpeg';\n\n// --- SKU sanitisation ---\nconst rawSku = body.sku || '';\nconst sku = rawSku.toUpperCase().replace(/[^A-Z0-9\\-_]/g, '').trim() || `SKU-${Date.now()}`;\n\n// --- Price coercion ---\nconst price = parseFloat(body.price) || 0;\nconst compareAtPrice = parseFloat(body.compareAtPrice) || null;\nif (price < 0) throw new Error('Price cannot be negative.');\n\n// --- Inventory ---\nconst inventory = parseInt(body.inventory, 10);\nconst safeInventory = isNaN(inventory) ? 1 : Math.max(0, inventory);\n\n// --- Tags ---\nconst tagsRaw = body.tags || '';\nconst tagsArray = tagsRaw.split(',').map(t => t.trim()).filter(Boolean);\n\nreturn [{\n json: {\n // Source\n filename,\n fileUrl: body.fileUrl || null,\n mimeType,\n // Platform\n platform,\n publishImmediately: body.publishImmediately !== false,\n // Product fields\n sku,\n price,\n compareAtPrice,\n vendor: body.vendor || '',\n productType: body.productType || '',\n inventory: safeInventory,\n weight: parseFloat(body.weight) || null,\n tags: tagsArray,\n // Pass-through for AI context\n userTitle: body.title || '',\n userDescription: body.description || '',\n // Meta\n receivedAt: new Date().toISOString()\n }\n}];"
},
"typeVersion": 2
},
{
"id": "7a2b2887-718f-4d76-820a-c5b452e706c5",
"name": "Has Remote URL?",
"type": "n8n-nodes-base.if",
"position": [
1104,
224
],
"parameters": {
"options": {},
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "cond-fileurl",
"operator": {
"type": "string",
"operation": "notEmpty"
},
"leftValue": "={{ $json.fileUrl }}",
"rightValue": ""
}
]
}
},
"typeVersion": 2
},
{
"id": "a760c1eb-3636-4acf-854f-fd995a00c5b7",
"name": "Upload to URL - Remote",
"type": "n8n-nodes-uploadtourl.uploadToUrl",
"position": [
1328,
112
],
"parameters": {
"operation": "uploadFile"
},
"credentials": {
"uploadToUrlApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "1e27bcd3-29cb-41a6-acfb-ee74a10b6ef6",
"name": "Upload to URL - Binary",
"type": "n8n-nodes-uploadtourl.uploadToUrl",
"position": [
1328,
352
],
"parameters": {
"operation": "uploadFile"
},
"credentials": {
"uploadToUrlApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "4117a58c-304e-4ac7-b5e2-3b0fbcbfbe6c",
"name": "Extract Image URL",
"type": "n8n-nodes-base.code",
"position": [
1552,
224
],
"parameters": {
"jsCode": "const uploadResp = $input.first().json;\nconst meta = $('Validate & Enrich Payload').first().json;\n\nconst imageUrl =\n uploadResp.url ||\n uploadResp.link ||\n uploadResp.data?.url ||\n uploadResp.file?.url ||\n uploadResp.shortUrl;\n\nif (!imageUrl) {\n throw new Error('Upload to URL returned no public URL. Raw response: ' + JSON.stringify(uploadResp));\n}\n\n// Ensure URL is HTTPS (some CDNs return HTTP)\nconst secureUrl = imageUrl.replace(/^http:\\/\\//, 'https://');\n\nreturn [{\n json: {\n ...meta,\n imageUrl: secureUrl,\n uploadId: uploadResp.id || uploadResp.data?.id || null,\n fileSizeBytes: uploadResp.size || uploadResp.data?.size || null\n }\n}];"
},
"typeVersion": 2
},
{
"id": "f0f9f546-2e0a-4ee1-a846-778aa59b4bc8",
"name": "GPT-4o Vision - Analyse Product",
"type": "@n8n/n8n-nodes-langchain.openAi",
"notes": "Sends the uploaded image URL to GPT-4o Vision. Returns structured product content: title, SEO description, features, tags, category, and a URL handle.",
"position": [
1760,
224
],
"parameters": {
"modelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"options": {
"maxTokens": 1200,
"temperature": 0.6
},
"messages": {
"values": [
{
"role": "system",
"content": "You are a professional e-commerce copywriter and product categorisation expert. Analyse the product image provided and return ONLY a valid JSON object \u2014 no markdown, no preamble, no trailing text."
},
{
"content": "=Analyse this product image and generate all required e-commerce content.\n\nImage URL: {{ $json.imageUrl }}\nUser-provided title (may be empty): {{ $json.userTitle }}\nUser-provided description (may be empty): {{ $json.userDescription }}\nVendor: {{ $json.vendor || 'Unknown' }}\nProduct Type hint: {{ $json.productType || 'Not specified' }}\nExisting tags: {{ $json.tags.join(', ') || 'None' }}\nPrice: {{ $json.price }}\n\nReturn ONLY this JSON structure:\n{\n \"title\": \"Short compelling product title (max 70 chars)\",\n \"seoTitle\": \"SEO-optimised title with keywords (max 70 chars)\",\n \"description\": \"Rich HTML product description (2-3 paragraphs, can use <p> <strong> <ul> <li> tags)\",\n \"shortDescription\": \"One-sentence plain text summary for WooCommerce short_description\",\n \"bulletFeatures\": [\"Feature 1\", \"Feature 2\", \"Feature 3\", \"Feature 4\", \"Feature 5\"],\n \"suggestedCategory\": \"Most specific applicable product category\",\n \"suggestedTags\": [\"tag1\", \"tag2\", \"tag3\", \"tag4\", \"tag5\"],\n \"metaDescription\": \"SEO meta description (max 155 chars)\",\n \"handle\": \"url-slug-from-title-lowercase-hyphenated\",\n \"marketingBlurb\": \"One punchy sentence for social media or email marketing\",\n \"confidenceScore\": 0.95\n}"
}
]
}
},
"typeVersion": 1.5
},
{
"id": "14f53b63-c22a-4030-989b-46b51475926f",
"name": "Parse & Merge AI Product Data",
"type": "n8n-nodes-base.code",
"position": [
2048,
224
],
"parameters": {
"jsCode": "const aiRaw = $input.first().json;\nconst productData = $('Extract Image URL').first().json;\n\n// --- Parse AI response ---\nlet ai;\ntry {\n const raw = aiRaw.message?.content || aiRaw.choices?.[0]?.message?.content || aiRaw.content || aiRaw.text;\n ai = typeof raw === 'string' ? JSON.parse(raw) : raw;\n} catch (e) {\n throw new Error('Failed to parse GPT-4o JSON response: ' + e.message);\n}\n\n// --- Validate essentials ---\nif (!ai.title) throw new Error('GPT-4o did not return a product title.');\n\n// --- Merge user-provided tags with AI tags (deduplicated) ---\nconst allTags = [...new Set([\n ...productData.tags,\n ...(ai.suggestedTags || [])\n])].slice(0, 15); // Most platforms cap at 15 tags\n\n// --- Build clean URL handle ---\nconst handle = (ai.handle || ai.title)\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .trim();\n\n// --- Shopify status ---\nconst shopifyStatus = productData.publishImmediately ? 'active' : 'draft';\n\n// --- WooCommerce status ---\nconst wcStatus = productData.publishImmediately ? 'publish' : 'draft';\n\nreturn [{\n json: {\n // Pass-through\n platform: productData.platform,\n imageUrl: productData.imageUrl,\n sku: productData.sku,\n price: productData.price,\n compareAtPrice: productData.compareAtPrice,\n vendor: productData.vendor,\n productType: productData.productType || ai.suggestedCategory,\n inventory: productData.inventory,\n weight: productData.weight,\n uploadId: productData.uploadId,\n\n // AI-generated\n title: productData.userTitle || ai.title,\n seoTitle: ai.seoTitle,\n description: ai.description,\n shortDescription: ai.shortDescription,\n bulletFeatures: ai.bulletFeatures || [],\n category: ai.suggestedCategory,\n tags: allTags,\n metaDescription: ai.metaDescription,\n handle,\n marketingBlurb: ai.marketingBlurb,\n confidenceScore: ai.confidenceScore || null,\n\n // Platform-specific computed\n shopifyStatus,\n wcStatus,\n\n generatedAt: new Date().toISOString()\n }\n}];"
},
"typeVersion": 2
},
{
"id": "2d70dfc8-89e8-4ef2-ba5e-d603d1131d33",
"name": "Route by Platform",
"type": "n8n-nodes-base.switch",
"position": [
2208,
224
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "Shopify",
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.platform }}",
"rightValue": "shopify"
}
]
},
"renameOutput": true
},
{
"outputKey": "WooCommerce",
"conditions": {
"options": {
"caseSensitive": false,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.platform }}",
"rightValue": "woocommerce"
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "extra"
}
},
"typeVersion": 3
},
{
"id": "14303dea-d4f1-49ac-8278-97d285f669b2",
"name": "Shopify - Create Product",
"type": "n8n-nodes-base.shopify",
"notes": "Creates product with image URL pre-attached. Sets SEO metafields, variant pricing, and inventory. Status: active or draft based on publishImmediately.",
"position": [
2432,
112
],
"parameters": {
"title": "={{ $json.title }}",
"resource": "product",
"authentication": "oAuth2",
"additionalFields": {}
},
"typeVersion": 1
},
{
"id": "866f00db-805f-4884-b5ec-541651235f0a",
"name": "WooCommerce - Create Product",
"type": "n8n-nodes-base.httpRequest",
"notes": "Creates WooCommerce product via REST API. Sets image src to UploadToURL CDN link. Writes Yoast SEO meta fields and marketing blurb to post meta.",
"position": [
2432,
352
],
"parameters": {
"url": "={{ $credentials.url }}/wp-json/wc/v3/products",
"method": "POST",
"options": {
"response": {
"response": {
"responseFormat": "json"
}
}
},
"jsonBody": "={\n \"name\": {{ JSON.stringify($json.title) }},\n \"slug\": {{ JSON.stringify($json.handle) }},\n \"type\": \"simple\",\n \"status\": {{ JSON.stringify($json.wcStatus) }},\n \"description\": {{ JSON.stringify($json.description) }},\n \"short_description\": {{ JSON.stringify($json.shortDescription) }},\n \"sku\": {{ JSON.stringify($json.sku) }},\n \"regular_price\": {{ JSON.stringify(String($json.price)) }},\n \"sale_price\": {{ $json.compareAtPrice ? JSON.stringify(String($json.price)) : '\"\"' }},\n \"manage_stock\": true,\n \"stock_quantity\": {{ $json.inventory }},\n \"weight\": {{ JSON.stringify($json.weight ? String($json.weight) : '') }},\n \"categories\": [{ \"name\": {{ JSON.stringify($json.category) }} }],\n \"tags\": {{ JSON.stringify($json.tags.map(t => ({ name: t }))) }},\n \"images\": [{ \"src\": {{ JSON.stringify($json.imageUrl) }}, \"alt\": {{ JSON.stringify($json.title) }}, \"position\": 1 }],\n \"meta_data\": [\n { \"key\": \"_yoast_wpseo_title\", \"value\": {{ JSON.stringify($json.seoTitle) }} },\n { \"key\": \"_yoast_wpseo_metadesc\", \"value\": {{ JSON.stringify($json.metaDescription) }} },\n { \"key\": \"marketing_blurb\", \"value\": {{ JSON.stringify($json.marketingBlurb) }} }\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "genericCredentialType",
"genericAuthType": "httpBasicAuth"
},
"credentials": {
"httpBasicAuth": {
"name": "<your credential>"
}
},
"typeVersion": 4.2
},
{
"id": "16ff0092-fdda-4675-aae9-594a12578d9d",
"name": "Build Product Response",
"type": "n8n-nodes-base.code",
"position": [
2640,
224
],
"parameters": {
"jsCode": "const platformResp = $input.first().json;\nconst productData = $('Parse & Merge AI Product Data').first().json;\n\n// Normalise Shopify vs WooCommerce response shapes\nconst isShopify = productData.platform === 'shopify';\n\nconst productId = isShopify\n ? (platformResp.product?.id || platformResp.id)\n : (platformResp.id);\n\nconst productUrl = isShopify\n ? `https://${platformResp.product?.handle || productData.handle}.myshopify.com/products/${platformResp.product?.handle || productData.handle}`\n : (platformResp.permalink || `${platformResp.link || ''}`);\n\nconst imageUrl = isShopify\n ? (platformResp.product?.images?.[0]?.src || productData.imageUrl)\n : (platformResp.images?.[0]?.src || productData.imageUrl);\n\nif (!productId) {\n throw new Error(`${productData.platform} did not return a product ID. Response: ${JSON.stringify(platformResp).slice(0, 300)}`);\n}\n\nreturn [{\n json: {\n success: true,\n platform: productData.platform,\n productId: String(productId),\n productUrl,\n imageUrl,\n title: productData.title,\n sku: productData.sku,\n price: productData.price,\n compareAtPrice: productData.compareAtPrice,\n category: productData.category,\n tags: productData.tags,\n handle: productData.handle,\n inventory: productData.inventory,\n marketingBlurb: productData.marketingBlurb,\n confidenceScore: productData.confidenceScore,\n publishStatus: productData.shopifyStatus || productData.wcStatus,\n generatedAt: productData.generatedAt,\n createdAt: new Date().toISOString()\n }\n}];"
},
"typeVersion": 2
},
{
"id": "b247362f-8b43-4487-9055-714a9f21f04c",
"name": "Slack - Notify Team",
"type": "n8n-nodes-base.slack",
"notes": "Optional: posts a formatted Slack notification to #product-updates with image link, product URL, SKU, price, and AI confidence score. Disable this node if Slack is not used.",
"position": [
2864,
112
],
"parameters": {
"text": "=:new: *New product created!*\n\n*{{ $json.title }}*\nSKU: `{{ $json.sku }}` | Price: ${{ $json.price }}{{ $json.compareAtPrice ? ' ~~$' + $json.compareAtPrice + '~~' : '' }}\nPlatform: {{ $json.platform | upcase }}\nCategory: {{ $json.category }}\nTags: {{ $json.tags.join(', ') }}\n\n:frame_with_picture: <{{ $json.imageUrl }}|View image>\n:link: <{{ $json.productUrl }}|View product>\n\n_AI confidence: {{ Math.round(($json.confidenceScore || 0) * 100) }}%_\n_{{ $json.marketingBlurb }}_",
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.2
},
{
"id": "2cbafe11-18db-4f5d-a02a-5c2b7c16376e",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2864,
320
],
"parameters": {
"options": {
"responseCode": 201,
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"respondWith": "json",
"responseBody": "={{ $('Build Product Response').first().json }}"
},
"typeVersion": 1.1
}
],
"connections": {
"Has Remote URL?": {
"main": [
[
{
"node": "Upload to URL - Remote",
"type": "main",
"index": 0
}
],
[
{
"node": "Upload to URL - Binary",
"type": "main",
"index": 0
}
]
]
},
"Extract Image URL": {
"main": [
[
{
"node": "GPT-4o Vision - Analyse Product",
"type": "main",
"index": 0
}
]
]
},
"Route by Platform": {
"main": [
[
{
"node": "Shopify - Create Product",
"type": "main",
"index": 0
}
],
[
{
"node": "WooCommerce - Create Product",
"type": "main",
"index": 0
}
]
]
},
"Slack - Notify Team": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Build Product Response": {
"main": [
[
{
"node": "Slack - Notify Team",
"type": "main",
"index": 0
}
]
]
},
"Upload to URL - Binary": {
"main": [
[
{
"node": "Extract Image URL",
"type": "main",
"index": 0
}
]
]
},
"Upload to URL - Remote": {
"main": [
[
{
"node": "Extract Image URL",
"type": "main",
"index": 0
}
]
]
},
"Shopify - Create Product": {
"main": [
[
{
"node": "Build Product Response",
"type": "main",
"index": 0
}
]
]
},
"Validate & Enrich Payload": {
"main": [
[
{
"node": "Has Remote URL?",
"type": "main",
"index": 0
}
]
]
},
"Webhook - Receive Product": {
"main": [
[
{
"node": "Validate & Enrich Payload",
"type": "main",
"index": 0
}
]
]
},
"WooCommerce - Create Product": {
"main": [
[
{
"node": "Build Product Response",
"type": "main",
"index": 0
}
]
]
},
"Parse & Merge AI Product Data": {
"main": [
[
{
"node": "Route by Platform",
"type": "main",
"index": 0
}
]
]
},
"GPT-4o Vision - Analyse Product": {
"main": [
[
{
"node": "Parse & Merge AI Product Data",
"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.
httpBasicAuthslackOAuth2ApiuploadToUrlApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
Transform raw product images into fully-optimized e-commerce listings in seconds. This workflow automates the bridge between a photo upload and a live product page by combining UploadToURL for hosting, GPT-4o Vision for content generation, and native integrations for Shopify and…
Source: https://n8n.io/workflows/13541/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
This workflow captures new leads via webhook, enriches and scores them with Apollo and Google Gemini, logs everything in Google Sheets, and automates outreach, reply handling, follow-ups, meeting prep
Venafi Presentation - Watch Video
Automatically detects missed Zoom demos booked via Calendly and triggers AI-powered follow-up sequences.
This workflow accepts invoice documents via webhook, validates and de-duplicates them, extracts invoice data from PDFs with OpenAI, and either posts approved invoices to an ERP via HTTP or routes exce
AI-Powered Fake Review Detection Workflow Using n8n & Airtable. Uses httpRequest, airtable, openAi, slack. Webhook trigger; 27 nodes.