This workflow corresponds to n8n.io template #17324 — we link there as the canonical source.
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 →
{
"id": "JeFVMY0AmBGhogu1",
"name": "Backfill studio product photos for single-image Shopify products with Dreem.ai",
"tags": [],
"nodes": [
{
"id": "bac338f2-fca8-483d-b686-012dc1095cc7",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
0,
0
],
"parameters": {
"width": 480,
"height": 896,
"content": "## Backfill studio product photos for single-image Shopify products with Dreem.ai\n\n### How it works\n\nThis workflow manually backfills studio-style product photos for Shopify products that currently have only a single image. It fetches products, filters for missing shots, loops through each item, generates front and back renders with Dreem.ai, asks for Slack approval on the front shot, and publishes approved/completed images back to Shopify. Slack is also used to notify when items are skipped and when the full run is complete.\n\n### Setup steps\n\n- Configure Shopify credentials and confirm the product query returns the catalog segment you want to backfill.\n- Configure Dreem.ai credentials and set the front/back render prompts or product-image inputs in the Dreem nodes.\n- Configure Slack credentials, the review channel, approval interaction settings, and completion/skipped notification destinations.\n- Review the filter logic in \u201cMissing Product Shots?\u201d so it matches your definition of single-image or missing-photo products.\n- Adjust wait durations and completion checks to match typical Dreem.ai render times and response fields.\n\n### Customization\n\nYou can change the product filter, batch size, Slack approval wording, Dreem.ai render prompts, and whether back shots require a separate approval step before publishing."
},
"typeVersion": 1
},
{
"id": "68178e17-d00b-434b-a72d-25b8e4ae2b35",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
560,
224
],
"parameters": {
"color": 7,
"width": 912,
"height": 352,
"content": "## Select products to process\n\nStarts the manual backfill, retrieves Shopify products, filters for items missing additional product shots, and batches them one product at a time for downstream processing."
},
"typeVersion": 1
},
{
"id": "b1744bc4-315d-42fe-ace0-e1a1e8090a0e",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1520,
320
],
"parameters": {
"color": 7,
"width": 416,
"height": 368,
"content": "## Generate front shots\n\nRequests a front-facing studio render from Dreem.ai for the current product and pauses to allow the render job to complete."
},
"typeVersion": 1
},
{
"id": "358f8430-2e49-48ed-a9e4-e792807e9339",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
2160,
96
],
"parameters": {
"color": 7,
"width": 656,
"height": 688,
"content": "## Review rendered shots\n\nChecks whether the front render completed, posts completed shots to Slack for review, captures approval, and sends skipped notifications when rendering is incomplete or later rejected paths need to move on."
},
"typeVersion": 1
},
{
"id": "12b73dd0-36ee-4e27-98f4-f941f6647a3b",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2976,
96
],
"parameters": {
"color": 7,
"height": 368,
"content": "## Publish approved front\n\nUploads the approved front product shot back to Shopify before starting the secondary back-shot generation path."
},
"typeVersion": 1
},
{
"id": "29301fdd-994c-4a32-8e88-12e0120a63e5",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1520,
800
],
"parameters": {
"color": 7,
"width": 864,
"height": 336,
"content": "## Generate back shots\n\nRuns the back-view Dreem.ai render, waits for completion, verifies the result, and publishes completed back shots to Shopify before returning to the product loop."
},
"typeVersion": 1
},
{
"id": "70007855-1e77-4eb8-9e54-be340b3fad0e",
"name": "Sticky Note6",
"type": "n8n-nodes-base.stickyNote",
"position": [
1520,
-128
],
"parameters": {
"color": 7,
"height": 368,
"content": "## Send completion notice\n\nPosts a Slack notification when the product batch loop has no more matching products to process."
},
"typeVersion": 1
},
{
"id": "995011f5-13e0-4c5e-b7d3-fe473beea3ba",
"name": "Start Workflow Manually",
"type": "n8n-nodes-base.manualTrigger",
"position": [
608,
400
],
"parameters": {},
"typeVersion": 1
},
{
"id": "76a2d1a2-b10b-4dd7-8388-e7f058f491eb",
"name": "Fetch Shopify Products",
"type": "n8n-nodes-base.shopify",
"position": [
848,
400
],
"parameters": {
"resource": "product",
"operation": "getAll",
"returnAll": true,
"authentication": "accessToken",
"additionalFields": {}
},
"credentials": {
"shopifyAccessTokenApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "dab6ea68-0cc0-49d6-b615-f96707e8d21e",
"name": "Filter Missing Photos",
"type": "n8n-nodes-base.filter",
"position": [
1088,
400
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7ef567b8-e6d4-47f6-836f-0a20ce0f4c8a",
"operator": {
"type": "string",
"operation": "notContains"
},
"leftValue": "={{ $json.tags }}",
"rightValue": "dreem-shots-added"
},
{
"id": "c4a90d12-58be-4f21-9a3e-7d2f6b1e8a01",
"operator": {
"type": "number",
"operation": "equals"
},
"leftValue": "={{ ($json.images ?? []).length }}",
"rightValue": 1
}
]
}
},
"typeVersion": 2.2
},
{
"id": "287efcdc-c8ec-4bc4-bee5-c4cea2eedc03",
"name": "Post Completion on Slack",
"type": "n8n-nodes-base.slack",
"position": [
1568,
80
],
"parameters": {
"text": "=Dreem product shots run complete. Every product missing shots has been processed.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.5
},
{
"id": "3ac8d016-566e-42a7-a451-947415043476",
"name": "Create Front View Images",
"type": "n8n-nodes-dreem.dreem",
"position": [
1568,
528
],
"parameters": {
"operation": "generateProductShots",
"shotCodes": [
"flat_lay_front",
"invisible_mannequin_front"
],
"callbackUrl": "={{ $execution.resumeUrl }}",
"backImageUrl": "={{ $json.images?.[1]?.src ?? '' }}",
"outputFormat": "jpeg",
"frontImageUrl": "={{ $json.images[0].src }}",
"authentication": "apiKey",
"outputAspectRatio": 5
},
"typeVersion": 1
},
{
"id": "943f4567-26d6-42b1-ab0f-56f2a0ff9f3f",
"name": "Wait for Image Render",
"type": "n8n-nodes-base.wait",
"position": [
1792,
528
],
"parameters": {
"resume": "webhook",
"options": {},
"httpMethod": "POST",
"resumeUnit": "minutes",
"resumeAmount": 20,
"limitWaitTime": true
},
"typeVersion": 1.1
},
{
"id": "95cac5a4-fa11-4a30-b553-6ca437da89a3",
"name": "Check Render Completion",
"type": "n8n-nodes-base.if",
"position": [
2240,
528
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body?.status ?? $json.status }}",
"rightValue": "completed"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "72f0eedf-41cd-416b-bf40-a715bf0f4af3",
"name": "Request Approval on Slack",
"type": "n8n-nodes-base.slack",
"disabled": true,
"position": [
2448,
448
],
"parameters": {
"select": "channel",
"message": "=Approve the product shots above for *{{ $('Loop Through Product Batches').item.json.title }}*? *Approve & publish* adds them to the product; *Skip* leaves it untouched (and untagged, so it's retried next run).",
"options": {
"limitWaitTime": {
"values": {
"resumeAmount": 24
}
}
},
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"operation": "sendAndWait",
"authentication": "oAuth2",
"approvalOptions": {
"values": {
"approvalType": "double",
"approveLabel": "Approve & publish",
"disapproveLabel": "Skip"
}
}
},
"typeVersion": 2.5
},
{
"id": "ed937219-7705-4719-ab4f-43050a3390c6",
"name": "Check Approval Status",
"type": "n8n-nodes-base.if",
"disabled": true,
"position": [
2672,
448
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "boolean",
"operation": "equals"
},
"leftValue": "={{ $json.data.approved }}",
"rightValue": true
}
]
}
},
"typeVersion": 2.2
},
{
"id": "80dbd52c-8475-43a8-b32e-21ad9d3d73c9",
"name": "Loop Through Product Batches",
"type": "n8n-nodes-base.splitInBatches",
"position": [
1328,
400
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "8ba71729-4dfc-4381-b630-6b6b2a89bf78",
"name": "Notify Skipped Photos",
"type": "n8n-nodes-base.slack",
"position": [
2448,
640
],
"parameters": {
"text": "=Skipped *{{ $('Loop Through Product Batches').item.json.title }}* - the render did not finish in time. If its shots weren't added yet, it will be picked up again on the next run.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.5
},
{
"id": "535b2597-4a58-4fe3-8ccf-27b1a7995e2b",
"name": "Update Front Photos",
"type": "n8n-nodes-base.shopify",
"position": [
3056,
352
],
"parameters": {
"resource": "product",
"operation": "update",
"productId": "={{ $('Loop Through Product Batches').item.json.id }}",
"updateFields": {
"tags": "={{ [$('Loop Through Product Batches').item.json.tags, 'dreem-shots-added'].filter(Boolean).join(', ') }}",
"images": "={{ ($('Loop Through Product Batches').item.json.images || []).map(i => ({ id: i.id })).concat(($('Wait for Image Render').item.json.body.outputs || []).map(o => ({ src: o.files[0].url }))) }}"
},
"authentication": "accessToken"
},
"typeVersion": 1
},
{
"id": "78c1bcdd-b5d2-4e9c-a689-28bce720f0eb",
"name": "Create Back View Images",
"type": "n8n-nodes-dreem.dreem",
"disabled": true,
"position": [
1568,
960
],
"parameters": {
"operation": "generateProductShots",
"shotCodes": [
"flat_lay_back",
"invisible_mannequin_back"
],
"callbackUrl": "={{ $execution.resumeUrl }}",
"backImageUrl": "={{ $('Loop Through Product Batches').item.json.images?.[1]?.src ?? '' }}",
"outputFormat": "jpeg",
"frontImageUrl": "={{ $('Loop Through Product Batches').item.json.images[0].src }}",
"authentication": "apiKey",
"outputAspectRatio": 5
},
"typeVersion": 1
},
{
"id": "4109e2d1-d518-41e5-83f4-604803dbe71a",
"name": "Wait for Back Image Render",
"type": "n8n-nodes-base.wait",
"disabled": true,
"position": [
1792,
960
],
"parameters": {
"resume": "webhook",
"options": {},
"httpMethod": "POST",
"resumeUnit": "minutes",
"resumeAmount": 20,
"limitWaitTime": true
},
"typeVersion": 1.1
},
{
"id": "03331b66-f7b5-445f-8fe7-b7f8410c8300",
"name": "Check Back Render Completion",
"type": "n8n-nodes-base.if",
"disabled": true,
"position": [
2016,
960
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "loose"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.body?.status ?? $json.status }}",
"rightValue": "completed"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "e26f0301-b4f2-4e1d-87f7-62f848592e16",
"name": "Update Back Photos",
"type": "n8n-nodes-base.shopify",
"disabled": true,
"position": [
2240,
960
],
"parameters": {
"resource": "product",
"operation": "update",
"productId": "={{ $('Loop Through Product Batches').item.json.id }}",
"updateFields": {
"images": "={{ ($('Update Front Photos').item.json.images || []).map(i => ({ id: i.id })).concat(($('Wait for Back Image Render').item.json.body.outputs || []).map(o => ({ src: o.files[0].url }))) }}"
},
"authentication": "accessToken"
},
"typeVersion": 1
},
{
"id": "3fb7c2e0-96a2-4462-946b-df222b3c6517",
"name": "Send Images to Slack for Review",
"type": "n8n-nodes-base.slack",
"disabled": true,
"position": [
2208,
272
],
"parameters": {
"text": "=*Product shots ready for review* \u2014 {{ $('Loop Through Product Batches').item.json.title }}\n{{ ($('Wait for Image Render').item.json.body?.outputs ?? $('Wait for Image Render').item.json.outputs ?? []).map(o => o.files[0].url).join('\\n') }}",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": ""
},
"otherOptions": {},
"authentication": "oAuth2"
},
"typeVersion": 2.5
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "dd44d49b-90a7-41df-aafe-b0450b362389",
"nodeGroups": [],
"connections": {
"Update Back Photos": {
"main": [
[
{
"node": "Loop Through Product Batches",
"type": "main",
"index": 0
}
]
]
},
"Update Front Photos": {
"main": [
[
{
"node": "Create Back View Images",
"type": "main",
"index": 0
}
]
]
},
"Check Approval Status": {
"main": [
[
{
"node": "Update Front Photos",
"type": "main",
"index": 0
}
],
[
{
"node": "Loop Through Product Batches",
"type": "main",
"index": 0
}
]
]
},
"Filter Missing Photos": {
"main": [
[
{
"node": "Loop Through Product Batches",
"type": "main",
"index": 0
}
]
]
},
"Notify Skipped Photos": {
"main": [
[
{
"node": "Loop Through Product Batches",
"type": "main",
"index": 0
}
]
]
},
"Wait for Image Render": {
"main": [
[
{
"node": "Check Render Completion",
"type": "main",
"index": 0
}
]
]
},
"Fetch Shopify Products": {
"main": [
[
{
"node": "Filter Missing Photos",
"type": "main",
"index": 0
}
]
]
},
"Check Render Completion": {
"main": [
[
{
"node": "Send Images to Slack for Review",
"type": "main",
"index": 0
}
],
[
{
"node": "Notify Skipped Photos",
"type": "main",
"index": 0
}
]
]
},
"Create Back View Images": {
"main": [
[
{
"node": "Wait for Back Image Render",
"type": "main",
"index": 0
}
]
]
},
"Start Workflow Manually": {
"main": [
[
{
"node": "Fetch Shopify Products",
"type": "main",
"index": 0
}
]
]
},
"Create Front View Images": {
"main": [
[
{
"node": "Wait for Image Render",
"type": "main",
"index": 0
}
]
]
},
"Request Approval on Slack": {
"main": [
[
{
"node": "Check Approval Status",
"type": "main",
"index": 0
}
]
]
},
"Wait for Back Image Render": {
"main": [
[
{
"node": "Check Back Render Completion",
"type": "main",
"index": 0
}
]
]
},
"Check Back Render Completion": {
"main": [
[
{
"node": "Update Back Photos",
"type": "main",
"index": 0
}
],
[
{
"node": "Notify Skipped Photos",
"type": "main",
"index": 0
}
]
]
},
"Loop Through Product Batches": {
"main": [
[
{
"node": "Post Completion on Slack",
"type": "main",
"index": 0
}
],
[
{
"node": "Create Front View Images",
"type": "main",
"index": 0
}
]
]
},
"Send Images to Slack for Review": {
"main": [
[
{
"node": "Request Approval on Slack",
"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.
shopifyAccessTokenApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
New products get attention; the back catalog doesn't. This workflow sweeps your Shopify catalog, finds every product that still has just one photo, and generates the missing studio product shots with Dreem.ai - one product at a time, so a 300-product store fixes itself while you…
Source: https://n8n.io/workflows/17324/ — 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 turns every new Shopify product into a complete photo set with Dreem.ai: studio product shots plus an on-model render, generated from one photo and added straight back to the listing. Op
This workflow turns a product photo into a short product video with Dreem AI. Tag a product dreem-video in Shopify and the finished clip arrives in Slack for approval, then lands in the product's medi
This workflow triggers on new Shopify products, generates studio-style product shots from one product image using Dreem.ai and appends the rendered images back to the Shopify product listing, with opt
This workflow fires when a new Shopify product is created, renders it on a virtual model with Dreem.ai, and appends the shot back to the product - with optional Slack posting and approval. A Shopify w
This workflow is essential for dropshippers, e-commerce store owners, and anyone looking to quickly import product catalogs from specific websites into their Shopify store.