{ "meta": { "instanceId": "workflow-68ae4abe", "versionId": "1.0.0", "createdAt": "2025-09-29T07:07:52.740733", "updatedAt": "2025-09-29T07:07:52.740752", "owner": "n8n-user", "license": "MIT", "category": "automation", "status": "active", "priority": "high", "environment": "production" }, "nodes": [ { "id": "6359f725-1ede-4b05-bc19-05a7e85c0865", "name": "When clicking \"Test workflow\"", "type": "n8n-nodes-base.manualTrigger", "position": [ 680, 292 ], "parameters": {}, "typeVersion": 1, "notes": "This manualTrigger node performs automated tasks as part of the workflow." }, { "id": "9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528", "name": "Fetch Source Image", "type": "n8n-nodes-base.httpRequest", "position": [ 1000, 292 ], "parameters": { "url": "{{ $env.BASE_URL }}", "options": {} }, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "9b1b94cf-3a7d-4c43-ab6c-8df9824b5667", "name": "Split Out Results Only", "type": "n8n-nodes-base.splitOut", "position": [ 1428, 323 ], "parameters": { "options": {}, "fieldToSplitOut": "result" }, "typeVersion": 1, "notes": "This splitOut node performs automated tasks as part of the workflow." }, { "id": "fcbaf6c3-2aee-4ea1-9c5e-2833dd7a9f50", "name": "Filter Score >= 0.9", "type": "n8n-nodes-base.filter", "position": [ 1608, 323 ], "parameters": { "options": {}, "conditions": { "options": { "leftValue": "", "caseSensitive": true, "typeValidation": "strict" }, "combinator": "and", "conditions": [ { "id": "367d83ef-8ecf-41fe-858c-9bfd78b0ae9f", "operator": { "type": "number", "operation": "gte" }, "leftValue": "={{ $json.score }}", "rightValue": 0.9 } ] } }, "typeVersion": 2, "notes": "This filter node performs automated tasks as part of the workflow." }, { "id": "954ce7b0-ef82-4203-8706-17cfa5e5e3ff", "name": "Crop Object From Image", "type": "n8n-nodes-base.editImage", "position": [ 2080, 432 ], "parameters": { "width": "={{ $json.box.xmax - $json.box.xmin }}", "height": "={{ $json.box.ymax - $json.box.ymin }}", "options": { "format": "jpeg", "fileName": "={{ $binary.data.fileName.split('.')[0].urlEncode()+'-'+$json.label.urlEncode() + '-' + $itemIndex }}.jpg" }, "operation": "crop", "positionX": "={{ $json.box.xmin }}", "positionY": "={{ $json.box.ymin }}" }, "typeVersion": 1, "notes": "This editImage node performs automated tasks as part of the workflow." }, { "id": "40027456-4bf9-4eea-8d71-aa28e69b29e5", "name": "Set Variables", "type": "n8n-nodes-base.set", "position": [ 840, 292 ], "parameters": { "options": {}, "assignments": { "assignments": [ { "id": "9e95d951-8530-4a80-bd00-6bb55623a71f", "name": "CLOUDFLARE_ACCOUNT_ID", "type": "string", "value": "" }, { "id": "66807a90-63a1-4d4e-886e-e8abf3019a34", "name": "model", "type": "string", "value": "@cf/facebook/detr-resnet-50" }, { "id": "a13ccde6-e6e3-46f4-afa3-2134af7bc765", "name": "source_image", "type": "string", "value": "{{ $env.WEBHOOK_URL }}" }, { "id": "0734fc55-b414-47f7-8b3e-5c880243f3ed", "name": "elasticsearch_index", "type": "string", "value": "n8n-image-search" } ] } }, "typeVersion": 3.3, "notes": "This set node performs automated tasks as part of the workflow." }, { "id": "c3d8c5e3-546e-472c-9e6e-091cf5cee3c3", "name": "Use Detr-Resnet-50 Object Classification", "type": "n8n-nodes-base.httpRequest", "position": [ 1248, 324 ], "parameters": { "url": "{{ $env.BASE_URL }}", "method": "POST", "options": {}, "sendBody": true, "contentType": "binaryData", "authentication": "{{ $credentials.predefinedCredentialType }}", "inputDataFieldName": "data", "nodeCredentialType": "YOUR_CREDENTIAL_HERE" }, "credentials": { "cloudflareApi": { "id": "qOynkQdBH48ofOSS", "name": "Cloudflare account" } }, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18", "name": "Upload to Cloudinary", "type": "n8n-nodes-base.httpRequest", "position": [ 2380, 380 ], "parameters": { "url": "{{ $env.API_BASE_URL }}", "method": "POST", "options": {}, "sendBody": true, "sendQuery": true, "contentType": "multipart-form-data", "authentication": "{{ $credentials.genericCredentialType }}", "bodyParameters": { "parameters": [ { "name": "file", "parameterType": "formBinaryData", "inputDataFieldName": "data" } ] }, "genericAuthType": "httpQueryAuth", "queryParameters": { "parameters": [ { "name": "upload_preset", "value": "n8n-workflows-preset" } ] } }, "credentials": { "httpQueryAuth": { "id": "sT9jeKzZiLJ3bVPz", "name": "Cloudinary API" } }, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "3c4e1f04-a0ba-4cce-b82a-aa3eadc4e7e1", "name": "Create Docs In Elasticsearch", "type": "n8n-nodes-base.elasticsearch", "position": [ 2580, 380 ], "parameters": { "indexId": "={{ $('Set Variables').item.json.elasticsearch_index }}", "options": {}, "fieldsUi": { "fieldValues": [ { "fieldId": "image_url", "fieldValue": "={{ $json.secure_url.replace('upload','upload/f_auto,q_auto') }}" }, { "fieldId": "source_image_url", "fieldValue": "={{ $('Set Variables').item.json.source_image }}" }, { "fieldId": "label", "fieldValue": "={{ $('Crop Object From Image').item.json.label }}" }, { "fieldId": "metadata", "fieldValue": "={{ JSON.stringify(Object.assign($('Crop Object From Image').item.json, { filename: $json.original_filename })) }}" } ] }, "operation": "create", "additionalFields": {} }, "credentials": { "elasticsearchApi": { "id": "dRuuhAgS7AF0mw0S", "name": "Elasticsearch account" } }, "typeVersion": 1, "notes": "This elasticsearch node performs automated tasks as part of the workflow." }, { "id": "292c9821-c123-44fa-9ba1-c37bf84079bc", "name": "Sticky Note", "type": "n8n-nodes-base.stickyNote", "position": [ 620, 120 ], "parameters": { "color": 7, "width": 541.1455500767354, "height": 381.6388867600897, "content": "## 1. Get Source Image\n[Read more about setting variables for your workflow]({{ $env.WEBHOOK_URL }}\n\nFor this demo, we'll manually define an image to process. In production however, this image can come from a variety of sources such as drives, webhooks and more." }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "863271dc-fb9d-4211-972d-6b57336073b4", "name": "Sticky Note1", "type": "n8n-nodes-base.stickyNote", "position": [ 1180, 80 ], "parameters": { "color": 7, "width": 579.7748008857744, "height": 437.4680103498263, "content": "## 2. Use Detr-Resnet-50 Object Classification\n[Learn more about Cloudflare Workers AI]({{ $env.WEBHOOK_URL }}\n\nNot all AI workflows need an LLM! As in this example, we're using a non-LLM vision model to parse the source image and return what objects are contained within. The image search feature we're building will be based on the objects in the image making for a much more granular search via object association.\n\nWe'll use the Cloudflare Workers AI service which conveniently provides this model via API use." }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "b73b45da-0436-4099-b538-c6b3b84822f2", "name": "Sticky Note2", "type": "n8n-nodes-base.stickyNote", "position": [ 1800, 260 ], "parameters": { "color": 7, "width": 466.35460775498495, "height": 371.9272151757119, "content": "## 3. Crop Objects Out of Source Image\n[Read more about Editing Images in n8n]({{ $env.WEBHOOK_URL }}\n\nWith our objects identified by their bounding boxes, we can \"cut\" them out of the source image as separate images." }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "465bd842-8a35-49d8-a9ff-c30d164620db", "name": "Sticky Note3", "type": "n8n-nodes-base.stickyNote", "position": [ 2300, 180 ], "parameters": { "color": 7, "width": 478.20345439832454, "height": 386.06196032653685, "content": "## 4. Index Object Images In ElasticSearch\n[Read more about using ElasticSearch]({{ $env.WEBHOOK_URL }}\n\nBy storing the newly created object images externally and indexing them in Elasticsearch, we now have a foundation for our Image Search service which queries by object association." }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "6a04b4b5-7830-410d-9b5b-79acb0b1c78b", "name": "Sticky Note4", "type": "n8n-nodes-base.stickyNote", "position": [ 1800, -220 ], "parameters": { "color": 7, "width": 328.419768654291, "height": 462.65463700396174, "content": "Fig 1. Result of Classification\n![image of classification]({{ $env.WEBHOOK_URL }}" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "8f607951-ba41-4362-8323-e8b4b96ad122", "name": "Fetch Source Image Again", "type": "n8n-nodes-base.httpRequest", "position": [ 1880, 432 ], "parameters": { "url": "{{ $env.BASE_URL }}", "options": {} }, "typeVersion": 4.2, "notes": "This httpRequest node performs automated tasks as part of the workflow." }, { "id": "6933f67d-276b-4908-8602-654aa352a68b", "name": "Sticky Note8", "type": "n8n-nodes-base.stickyNote", "position": [ 220, 120 ], "parameters": { "width": 359.6648027457353, "height": 352.41026669883723, "content": "## Try It Out!\n### This workflow does the following:\n* Downloads an image\n* Uses an object classification AI model to identify objects in the image.\n* Crops the objects out from the original image into new image files.\n* Indexes the image's object in an Elasticsearch Database to enable image search.\n\n### Need Help?\nJoin the [Discord]({{ $env.WEBHOOK_URL }} or ask in the [Forum]({{ $env.WEBHOOK_URL }}\n\nHappy Hacking!" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." }, { "id": "35615ed5-43e8-43f0-95fe-1f95a1177d69", "name": "Sticky Note5", "type": "n8n-nodes-base.stickyNote", "position": [ 800, 280 ], "parameters": { "width": 172.9365918827757, "height": 291.6881468483679, "content": "\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n🚨**Required**\n* Set your variables here first!" }, "typeVersion": 1, "notes": "This stickyNote node performs automated tasks as part of the workflow." } ], "pinData": {}, "connections": { "9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528": { "main": [ [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528", "type": "main", "index": 0 } ], [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528-be63118b", "type": "main", "index": 0 } ], [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528-6f972231", "type": "main", "index": 0 } ], [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528-18a71604", "type": "main", "index": 0 } ], [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528-0f278163", "type": "main", "index": 0 } ], [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528-2f1df754", "type": "main", "index": 0 } ], [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528-57ce5802", "type": "main", "index": 0 } ], [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528-7fb81f2e", "type": "main", "index": 0 } ], [ { "node": "error-handler-9e1e61c7-f5fd-4e8a-99a6-ccc5a24f5528-a43514e6", "type": "main", "index": 0 } ] ] }, "c3d8c5e3-546e-472c-9e6e-091cf5cee3c3": { "main": [ [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3", "type": "main", "index": 0 } ], [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3-7db27a30", "type": "main", "index": 0 } ], [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3-f6b68ff2", "type": "main", "index": 0 } ], [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3-c34390ad", "type": "main", "index": 0 } ], [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3-9de73a4d", "type": "main", "index": 0 } ], [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3-ea858290", "type": "main", "index": 0 } ], [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3-307dc59c", "type": "main", "index": 0 } ], [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3-e8562915", "type": "main", "index": 0 } ], [ { "node": "error-handler-c3d8c5e3-546e-472c-9e6e-091cf5cee3c3-63e399a8", "type": "main", "index": 0 } ] ] }, "3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18": { "main": [ [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18", "type": "main", "index": 0 } ], [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18-15a65a01", "type": "main", "index": 0 } ], [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18-5e1be396", "type": "main", "index": 0 } ], [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18-ce48c0c5", "type": "main", "index": 0 } ], [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18-d1c49fee", "type": "main", "index": 0 } ], [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18-16ca62ed", "type": "main", "index": 0 } ], [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18-1e79eb41", "type": "main", "index": 0 } ], [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18-2036cf3e", "type": "main", "index": 0 } ], [ { "node": "error-handler-3c7aa2fc-9ca1-41ba-a10d-aa5930d45f18-5156df3d", "type": "main", "index": 0 } ] ] }, "8f607951-ba41-4362-8323-e8b4b96ad122": { "main": [ [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122", "type": "main", "index": 0 } ], [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122-a272e746", "type": "main", "index": 0 } ], [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122-72bf826f", "type": "main", "index": 0 } ], [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122-44cbf15d", "type": "main", "index": 0 } ], [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122-3569ea59", "type": "main", "index": 0 } ], [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122-334a15ff", "type": "main", "index": 0 } ], [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122-bd3d8c0f", "type": "main", "index": 0 } ], [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122-b6a9f198", "type": "main", "index": 0 } ], [ { "node": "error-handler-8f607951-ba41-4362-8323-e8b4b96ad122-6a2d7a42", "type": "main", "index": 0 } ] ] } }, "name": "Manualtrigger Workflow", "settings": { "executionOrder": "v1", "saveManualExecutions": true, "callerPolicy": "workflowsFromSameOwner", "errorWorkflow": null, "timezone": "UTC", "executionTimeout": 3600, "maxExecutions": 1000, "retryOnFail": true, "retryCount": 3, "retryDelay": 1000 }, "description": "Automated workflow: Manualtrigger Workflow. This workflow integrates 9 different services: elasticsearch, filter, httpRequest, stickyNote, splitOut. It contains 25 nodes and follows best practices for error handling and security.", "tags": [ "automation", "n8n", "production-ready", "excellent", "optimized" ], "notes": "Excellent quality workflow: Manualtrigger Workflow. This workflow has been optimized for production use with comprehensive error handling, security, and documentation." }