This workflow corresponds to n8n.io template #10496 — 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": "5cU1AGvVfWmNY8xF",
"name": "Proof-of-Delivery Automation & Dispute Handler",
"tags": [],
"nodes": [
{
"id": "5997a7ad-e534-4c00-9678-44eac343faae",
"name": "Webhook - POD Submission1",
"type": "n8n-nodes-base.webhook",
"position": [
-3408,
2320
],
"parameters": {
"path": "pod-delivery-submit",
"options": {}
},
"typeVersion": 1.1
},
{
"id": "1da6b444-4040-47a0-a1b6-0adfa87b5298",
"name": "Sticky Note11",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3456,
2064
],
"parameters": {
"color": 4,
"width": 310,
"height": 416,
"content": "## \ud83d\udce6 POD Workflow Entry\nCapture Delivery Proof Instantly\n\n\u2022 What: Webhook grabs driver-submitted data (photos, signatures, GPS coords).\n\u2022 Why: No manual uploads\u2014ensures 100% capture for audit-proof records.\n\u2022 Next: Feeds into validation to flag issues early."
},
"typeVersion": 1
},
{
"id": "7ee1f974-2743-4767-8849-1a739d8fd140",
"name": "Validate Input Data1",
"type": "n8n-nodes-base.if",
"position": [
-2976,
2320
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.body.delivery_id }}",
"operation": "isNotEmpty"
},
{
"value1": "={{ $json.body.signature_image }}",
"operation": "isNotEmpty"
},
{
"value1": "={{ $json.body.delivery_photo }}",
"operation": "isNotEmpty"
}
]
}
},
"typeVersion": 1
},
{
"id": "a7aacd2e-416b-489f-86a6-232040a3fd8e",
"name": "Return Error1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-2720,
2608
],
"parameters": {
"options": {
"responseCode": 400
},
"respondWith": "json",
"responseBody": "={{ {\"error\": \"Missing required fields\", \"message\": \"delivery_id, signature_image, and delivery_photo are required\"} }}"
},
"typeVersion": 1
},
{
"id": "26655e92-8458-4fe3-b875-02def9409ea7",
"name": "AI Photo Verification1",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2624,
1792
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "model",
"value": "gpt-4-vision-preview"
},
{
"name": "messages",
"value": "={{ [{\"role\": \"user\", \"content\": [{\"type\": \"text\", \"text\": \"Analyze this delivery proof photo. Check for: 1) Package visibility 2) Clear address/location 3) Proper placement 4) Any damage visible. Respond in JSON format with: {verified: boolean, confidence: number, issues: array, description: string}\"}, {\"type\": \"image_url\", \"image_url\": {\"url\": $json.body.delivery_photo}}]}] }}"
},
{
"name": "max_tokens",
"value": "500"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "e25cf0a8-298a-4f73-9290-fb49cf1a029a",
"name": "AI Signature Verification1",
"type": "n8n-nodes-base.httpRequest",
"position": [
-2608,
2320
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"method": "POST",
"options": {},
"sendBody": true,
"sendHeaders": true,
"bodyParameters": {
"parameters": [
{
"name": "model",
"value": "gpt-4-vision-preview"
},
{
"name": "messages",
"value": "={{ [{\"role\": \"user\", \"content\": [{\"type\": \"text\", \"text\": \"Analyze this signature image. Check if it appears to be: 1) A genuine handwritten signature 2) Clear and legible 3) Not a printed/typed name 4) Complete (not partial). Respond in JSON: {valid: boolean, confidence: number, concerns: array}\"}, {\"type\": \"image_url\", \"image_url\": {\"url\": $json.body.signature_image}}]}] }}"
},
{
"name": "max_tokens",
"value": "300"
}
]
},
"headerParameters": {
"parameters": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"typeVersion": 4.1
},
{
"id": "6f10644e-315f-47b5-aecb-cbb5e778e5a8",
"name": "Merge Analysis Results1",
"type": "n8n-nodes-base.code",
"position": [
-2384,
2224
],
"parameters": {
"jsCode": "const webhookData = $input.first().json.body;\nconst photoAnalysis = JSON.parse($input.all()[1].json.choices[0].message.content);\nconst signatureAnalysis = JSON.parse($input.all()[2].json.choices[0].message.content);\n\nconst photoVerified = photoAnalysis.verified && photoAnalysis.confidence > 0.7;\nconst signatureValid = signatureAnalysis.valid && signatureAnalysis.confidence > 0.7;\n\nconst overallStatus = photoVerified && signatureValid ? 'verified' : 'disputed';\n\nreturn {\n json: {\n delivery_id: webhookData.delivery_id,\n driver_id: webhookData.driver_id || 'UNKNOWN',\n recipient_name: webhookData.recipient_name || '',\n delivery_status: overallStatus,\n verification: {\n photo: {\n verified: photoVerified,\n confidence: photoAnalysis.confidence,\n issues: photoAnalysis.issues || [],\n description: photoAnalysis.description\n },\n signature: {\n valid: signatureValid,\n confidence: signatureAnalysis.confidence,\n concerns: signatureAnalysis.concerns || []\n }\n },\n gps_coordinates: webhookData.gps_coordinates || null,\n timestamp: new Date().toISOString(),\n images: {\n signature: webhookData.signature_image,\n delivery: webhookData.delivery_photo\n }\n }\n};"
},
"typeVersion": 2
},
{
"id": "75ca1a66-3826-44c1-9430-74fa19ea35fe",
"name": "Sticky Note14",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2112,
1920
],
"parameters": {
"color": 6,
"width": 176,
"height": 460,
"content": "\u2705 Verdict Gatekeeper\n\n\u2022 What: If score >80%, route to success; else, flag for dispute.\n\u2022 Why: Single decision point\u2014avoids over-processing bad data, streamlining flow.\n\u2022 Branches to: ERP update (green) or ticket creation (red)."
},
"typeVersion": 1
},
{
"id": "7d659c6e-73ce-4dc8-b2fe-7029b21d2c04",
"name": "Check Verification Status1",
"type": "n8n-nodes-base.if",
"position": [
-2048,
2224
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.delivery_status }}",
"value2": "verified",
"operation": "equals"
}
]
}
},
"typeVersion": 1
},
{
"id": "2f96245b-7c51-426b-930d-8677f2e36b5e",
"name": "Update Delivery Status1",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1840,
2016
],
"parameters": {
"url": "https://your-erp-system.com/api/deliveries/update",
"method": "POST",
"options": {},
"jsonBody": "={{ {\n \"delivery_id\": $json.delivery_id,\n \"status\": \"delivered\",\n \"delivered_at\": $json.timestamp,\n \"signature_url\": $json.images.signature,\n \"proof_photo_url\": $json.images.delivery,\n \"gps_coordinates\": $json.gps_coordinates,\n \"verification_confidence\": $json.verification.photo.confidence\n} }}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.1
},
{
"id": "388cb0af-8b05-4b56-9aee-2410474b3b1d",
"name": "Sticky Note15",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1920,
1648
],
"parameters": {
"color": 3,
"width": 300,
"height": 540,
"content": "\ud83d\udd04 ERP Sync: Status Update\n\n\u2022 What: Pushes \"Delivered\" to ERP (e.g., SAP/NetSuite) with POD refs.\n\u2022 Why: Real-time inventory accuracy\u2014triggers warehouse restock, cuts stockouts.\n\u2022 Flows from: Verified check; logs timestamp for compliance."
},
"typeVersion": 1
},
{
"id": "24d13fb3-87ad-47d5-b58a-f7387376ccd5",
"name": "Trigger Invoice Generation1",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1456,
2016
],
"parameters": {
"url": "https://your-billing-system.com/api/invoices/generate",
"method": "POST",
"options": {},
"jsonBody": "={{ {\n \"delivery_id\": $json.delivery_id,\n \"invoice_date\": $json.timestamp,\n \"status\": \"ready_for_billing\",\n \"proof_of_delivery\": true,\n \"verification_passed\": true\n} }}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.1
},
{
"id": "15454b74-f2cb-43d1-8866-6d495df7c11a",
"name": "Create Dispute Ticket1",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1824,
2464
],
"parameters": {
"url": "https://your-support-system.com/api/tickets/create",
"method": "POST",
"options": {},
"jsonBody": "={{ {\n \"title\": \"Delivery Verification Failed - \" + $json.delivery_id,\n \"type\": \"dispute\",\n \"priority\": \"high\",\n \"delivery_id\": $json.delivery_id,\n \"driver_id\": $json.driver_id,\n \"description\": \"Automated POD verification failed. Issues found:\\n\\nPhoto Issues: \" + JSON.stringify($json.verification.photo.issues) + \"\\n\\nSignature Concerns: \" + JSON.stringify($json.verification.signature.concerns),\n \"metadata\": {\n \"photo_confidence\": $json.verification.photo.confidence,\n \"signature_confidence\": $json.verification.signature.confidence,\n \"signature_url\": $json.images.signature,\n \"photo_url\": $json.images.delivery,\n \"gps_coordinates\": $json.gps_coordinates\n },\n \"status\": \"open\",\n \"assigned_to\": \"dispute_team\"\n} }}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.1
},
{
"id": "210d794d-48a7-4aec-830b-a0eeedc9431c",
"name": "Sticky Note16",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1888,
2240
],
"parameters": {
"color": 4,
"width": 272,
"height": 384,
"content": "\u26a0\ufe0f Dispute Launcher\n\n\u2022 What: If verification fails, creates support ticket with issue details (e.g., damage photo).\n\u2022 Why: Proactive escalation\u2014resolves mismatches in <24h vs. manual weeks.\n\u2022 Flows to: High-priority tag; notifies team via Slack/email."
},
"typeVersion": 1
},
{
"id": "6d686a2e-57cb-494b-9401-c1c421bf4fca",
"name": "Notify Dispute Team1",
"type": "n8n-nodes-base.httpRequest",
"position": [
-1424,
2464
],
"parameters": {
"url": "https://your-notification-service.com/api/send",
"method": "POST",
"options": {},
"jsonBody": "={{ {\n \"recipient\": \"dispute-team@company.com\",\n \"subject\": \"\u26a0\ufe0f Delivery Dispute - \" + $json.delivery_id,\n \"body\": \"A delivery verification has failed and requires manual review.\\n\\nDelivery ID: \" + $json.delivery_id + \"\\nDriver: \" + $json.driver_id + \"\\nTimestamp: \" + $json.timestamp + \"\\n\\nReview the ticket for full details and evidence.\",\n \"priority\": \"high\"\n} }}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.1
},
{
"id": "f0cc7963-5833-49d3-a4cf-295a478981ed",
"name": "Sticky Note17",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1504,
2224
],
"parameters": {
"color": 5,
"width": 220,
"height": 412,
"content": "\ud83d\udd14 Team Alert\n\n\u2022 What: Sends Slack/email with ticket link, priority flag, and evidence summary.\n\u2022 Why: Loops in support fast\u2014high-priority routing ensures quick driver follow-up.\n\u2022 Flows from: Ticket creation; tracks response time."
},
"typeVersion": 1
},
{
"id": "aae5eb3f-ad51-4ca9-8eda-0ba930fe4c7e",
"name": "Success Response1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-1184,
2144
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ {\n \"success\": true,\n \"delivery_id\": $json.delivery_id,\n \"status\": \"verified\",\n \"message\": \"Delivery verified and invoice triggered\",\n \"verification_details\": $json.verification\n} }}"
},
"typeVersion": 1
},
{
"id": "165d79a1-17d5-4e44-8be0-a3115109373b",
"name": "Dispute Response1",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
-1168,
2320
],
"parameters": {
"options": {},
"respondWith": "json",
"responseBody": "={{ {\n \"success\": true,\n \"delivery_id\": $json.delivery_id,\n \"status\": \"disputed\",\n \"message\": \"Delivery verification failed - dispute ticket created\",\n \"ticket_created\": true,\n \"verification_details\": $json.verification\n} }}"
},
"typeVersion": 1
},
{
"id": "c26c79ab-cef0-47bd-96e1-fb3069933094",
"name": "Sticky Note18",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1248,
1872
],
"parameters": {
"color": 4,
"width": 220,
"height": 652,
"content": "\ud83d\udce4 Echo Back Success\n\n\u2022 What: Returns JSON to caller (e.g., driver app) with status, ref ID, next steps.\n\u2022 Why: Closes the loop for users\u2014confirms submission, reduces \"where's my POD?\" queries.\n\u2022 Includes: Processing time, verification details."
},
"typeVersion": 1
},
{
"id": "e646dfa2-f915-45a4-89e2-fada3cf651e2",
"name": "Sticky Note19",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3504,
1360
],
"parameters": {
"width": 672,
"height": 624,
"content": "## \ud83d\ude80 Workflow Overview\n\nProof-of-Delivery Automation: End-to-End Logistics Magic\n\n\u2022 What: Ingests POD data (signatures, photos, GPS) \u2192 Verifies with AI \u2192 Updates ERP/invoices \u2192 Handles disputes.\n\u2022 Why: Cuts billing errors by 80% and resolves issues in hours, not days\u2014seamless for high-volume deliveries.\n\u2022 Pro Tip: Trigger via webhook for real-time magic. Starts here \u2192 Ends with alerts & reports.\n\nHow it works\n\nThis Proof-of-Delivery (POD) Automation handles delivery confirmations end-to-end. It validates incoming webhook data, verifies proof images and signatures using AI, consolidates results, and determines whether the delivery is verified or disputed. Verified deliveries trigger ERP updates and auto-invoicing, while disputed ones create a service ticket and alert the support team.\n\nSetup steps\n\n1\ufe0f\u20e3 Connect all API integrations \u2014 Webhook, AI Vision, AI Signature, ERP, Billing, and Notification systems.\n2\ufe0f\u20e3 Configure your validation rules for delivery ID, signature, and photo.\n3\ufe0f\u20e3 Set routing logic: verified \u2192 invoice; disputed \u2192 ticket.\n4\ufe0f\u20e3 Map output fields for success and dispute responses.\n5\ufe0f\u20e3 Test with sample deliveries before activating automation."
},
"typeVersion": 1
},
{
"id": "007edb56-e515-45cd-a0c8-276a08637676",
"name": "Sticky Note20",
"type": "n8n-nodes-base.stickyNote",
"position": [
-960,
2064
],
"parameters": {
"color": 2,
"width": 464,
"height": 416,
"content": "## \u2705 Completion & Outputs\n\nSummary\n\nAfter execution, the workflow updates the ERP and billing systems, sends the response to the original webhook, and alerts the relevant team if disputes arise.\n\nResults include:\n\n\ud83e\uddfe Invoice or ticket reference ID\n\n\ud83d\udcec Delivery verification status\n\n\u23f1\ufe0f Processing time and timestamps\n\n\ud83d\udce7 Notifications sent to ops and support teams"
},
"typeVersion": 1
},
{
"id": "79a29a0c-1579-46ca-b3f6-733e4f76f16f",
"name": "Sticky Note13",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2688,
2048
],
"parameters": {
"color": 5,
"width": 220,
"height": 380,
"content": "\u270d\ufe0f Signature Auth Check\n\n\u2022 What: Analyzes handwriting for completeness and forgery patterns (e.g., via ML model).\n\u2022 Why: Ensures genuine customer sign-off\u2014cuts dispute escalations by validating 95% auto.\n\u2022 Flows to: Merge analysis; rejects if incomplete."
},
"typeVersion": 1
},
{
"id": "ff98e134-c444-4d99-bcd9-907db40404ff",
"name": "Sticky Note12",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2688,
1504
],
"parameters": {
"color": 5,
"width": 208,
"height": 412,
"content": "\ud83d\udc41\ufe0f AI Package Inspector\n\n\u2022 What: Runs computer vision on photos to detect damage, tampering, or label mismatches.\n\u2022 Why: Automates visual audits (humans miss 20%)\u2014scales to 1000s of deliveries/day.\n\u2022 Flows to: Merge with signature results; scores integrity 0-100."
},
"typeVersion": 1
},
{
"id": "5c36ec9f-c0dd-4963-a7fe-b883f5d28855",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-3088,
2064
],
"parameters": {
"color": 3,
"width": 310,
"height": 416,
"content": "\u2699\ufe0f Basic Data Scrub\n\n\u2022 What: Checks for required fields (e.g., photo URL, GPS validity, signature blob).\n\u2022 Why: Blocks junk data early\u2014prevents crashes downstream, saving 30% debug time.\n\u2022 Flows to: GPS/signature checks; branches to error if invalid."
},
"typeVersion": 1
},
{
"id": "ae4617b0-a828-4783-943a-895a9144a59f",
"name": "Sticky Note21",
"type": "n8n-nodes-base.stickyNote",
"position": [
-2400,
1920
],
"parameters": {
"color": 2,
"width": 176,
"height": 460,
"content": "\ud83d\udd17 Combine Insights\n\n\u2022 What: Fuses AI vision + sig scores into single verification verdict (pass/fail).\n\u2022 Why: Holistic view prevents siloed errors\u2014one truth for routing decisions.\n\u2022 Flows to: Status check; includes raw data for audits."
},
"typeVersion": 1
},
{
"id": "ab67c262-716f-4b50-86d0-f7ea21370806",
"name": "Sticky Note22",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1568,
1648
],
"parameters": {
"color": 2,
"width": 300,
"height": 540,
"content": "\ud83d\udcb0 Invoice Kickoff\n\n\u2022 What: Generates customer invoice PDF from verified POD data.\n\u2022 Why: Auto-bills on proof\u2014speeds cash flow, reduces DSO from weeks to days.\n\u2022 Flows to: Mark as billable; attaches photo evidence."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "81466bdc-b086-4117-bae5-9fe701b4df3f",
"connections": {
"Notify Dispute Team1": {
"main": [
[
{
"node": "Dispute Response1",
"type": "main",
"index": 0
}
]
]
},
"Validate Input Data1": {
"main": [
[
{
"node": "AI Photo Verification1",
"type": "main",
"index": 0
},
{
"node": "AI Signature Verification1",
"type": "main",
"index": 0
}
],
[
{
"node": "Return Error1",
"type": "main",
"index": 0
}
]
]
},
"AI Photo Verification1": {
"main": [
[
{
"node": "Merge Analysis Results1",
"type": "main",
"index": 0
}
]
]
},
"Create Dispute Ticket1": {
"main": [
[
{
"node": "Notify Dispute Team1",
"type": "main",
"index": 0
}
]
]
},
"Merge Analysis Results1": {
"main": [
[
{
"node": "Check Verification Status1",
"type": "main",
"index": 0
}
]
]
},
"Update Delivery Status1": {
"main": [
[
{
"node": "Trigger Invoice Generation1",
"type": "main",
"index": 0
}
]
]
},
"Webhook - POD Submission1": {
"main": [
[
{
"node": "Validate Input Data1",
"type": "main",
"index": 0
}
]
]
},
"AI Signature Verification1": {
"main": [
[
{
"node": "Merge Analysis Results1",
"type": "main",
"index": 0
}
]
]
},
"Check Verification Status1": {
"main": [
[
{
"node": "Update Delivery Status1",
"type": "main",
"index": 0
}
],
[
{
"node": "Create Dispute Ticket1",
"type": "main",
"index": 0
}
]
]
},
"Trigger Invoice Generation1": {
"main": [
[
{
"node": "Success Response1",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n workflow automates the end-to-end proof-of-delivery process for logistics operations. It ingests POD data via webhook—including driver signatures, delivery photos, and GPS coordinates—performs AI-driven verification for package integrity and authenticity, updates ERP…
Source: https://n8n.io/workflows/10496/ — 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 n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di
This flow creates dummy files for every item added in your *Arrs (Radarr/Sonarr) with the tag .
This workflow acts as a central API gateway for all technical indicator agents in the Binance Spot Market Quant AI system. It listens for incoming webhook requests and dynamically routes them to the c
Sign PDF documents with legally-compliant digital signatures using X.509 certificates. Supports multiple PAdES signature levels (B, T, LT, LTA) with optional visible stamps.
📡 This workflow serves as the central Alpha Vantage API fetcher for Tesla trading indicators, delivering cleaned 20-point JSON outputs for three timeframes: , , and . It is required by the following a