{
  "id": "8Deu7DEmE7N3xZ3q",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "AI Logistics Quoting Platform with Carrier Intelligence",
  "tags": [],
  "nodes": [
    {
      "id": "52097498-3d4c-45ad-b9c4-b38913802994",
      "name": "\ud83d\udccb Overview",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        832,
        2384
      ],
      "parameters": {
        "color": 2,
        "width": 716,
        "height": 624,
        "content": "## \ud83d\udccb AI Freight Quote Comparator\n\nBrokers and freight teams waste hours building rate quotes manually from spreadsheets and carrier emails. This workflow eliminates that \u2014 a shipment request comes in and a ranked PDF quote goes out automatically, in minutes.\n\n### How it works\n1. A customer submits shipment details (origin, destination, weight, mode) via webhook\n2. The workflow simultaneously fetches rates from 3 carrier sheets in Google Sheets\n3. GPT-4o normalises the data and builds a ranked HTML comparison table\n4. PDFShift converts the HTML to a clean A4 PDF\n5. Gmail delivers the quote to the customer as an attachment\n\n### Setup steps\n1. Connect your **OpenAI** credential to the GPT-4o node\n2. Connect **Google Sheets OAuth2** \u2014 your sheet ID is already pre-filled\n3. Add your **PDFShift API key** to the Generate Quote PDF node header\n4. Connect **Gmail OAuth2** to the Send Quote Email node\n5. Click **Test Workflow** \u2014 demo shipment data is pinned on the webhook"
      },
      "typeVersion": 1
    },
    {
      "id": "b814dcf6-ea94-4957-983c-1dfba5e66c03",
      "name": "Section \u2013 Trigger & Extraction",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1696,
        2928
      ],
      "parameters": {
        "color": 7,
        "width": 548,
        "height": 484,
        "content": "## \ud83d\udce5 Trigger & Field Extraction\nWebhook receives the customer's shipment request. The Set node unpacks body fields into clean named variables used downstream.\n\nDemo data is pinned \u2014 hit **Test Workflow** to run without a live HTTP call."
      },
      "typeVersion": 1
    },
    {
      "id": "6514ddbc-9876-43ea-9268-56e580567f79",
      "name": "Section \u2013 Carrier Lookup",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2288,
        2736
      ],
      "parameters": {
        "color": 7,
        "width": 796,
        "height": 860,
        "content": "## \ud83d\udd0d Carrier Rate Lookup\nThree Google Sheets reads run in parallel \u2014 one per carrier tab. The Merge node waits for all three before passing data forward.\n\nEach tab shares the same spreadsheet; only the sheet name differs per carrier."
      },
      "typeVersion": 1
    },
    {
      "id": "2d25d9c6-6c9a-4418-a502-7cb6c35384b6",
      "name": "Section \u2013 AI & PDF",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3136,
        2912
      ],
      "parameters": {
        "color": 7,
        "width": 840,
        "height": 612,
        "content": "## \ud83e\udd16 AI Quote Generation & PDF\nThe Code node structures shipment and carrier data into a clean JSON payload. GPT-4o receives this and returns a complete HTML quote page.\n\nPDFShift converts that HTML to an A4 PDF binary, which is passed directly to Gmail."
      },
      "typeVersion": 1
    },
    {
      "id": "70efbfa6-642a-4826-921e-f1da77f598b3",
      "name": "Section \u2013 Email Delivery",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4048,
        2912
      ],
      "parameters": {
        "color": 7,
        "width": 340,
        "height": 500,
        "content": "## \ud83d\udce7 Customer Delivery\nGmail sends the ranked PDF quote to the customer's email address. Subject and body auto-fill from the shipment data.\n\nThe quote is valid for 7 days \u2014 update the footer prompt in the GPT-4o node if needed."
      },
      "typeVersion": 1
    },
    {
      "id": "ae57aa1f-d52f-4ecf-8c4c-1f23ed6d7e97",
      "name": "\ud83d\udd10 Credentials & Security",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4160,
        3552
      ],
      "parameters": {
        "color": 3,
        "width": 340,
        "height": 296,
        "content": "## \ud83d\udd10 Credentials & Security\nRequires: OpenAI API key, Google Sheets OAuth2, PDFShift API key, Gmail OAuth2.\n\nDo not hardcode API keys. Use n8n credential store. Remove personal emails before sharing this template."
      },
      "typeVersion": 1
    },
    {
      "id": "1b48bae4-b1df-4cb2-93c6-f0a10b2b625c",
      "name": "Shipment Request Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        1792,
        3200
      ],
      "parameters": {
        "path": "freight-quote-request",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "lastNode"
      },
      "typeVersion": 2
    },
    {
      "id": "f7630b0b-16d7-4823-b270-fa6574da95a4",
      "name": "Extract Shipment Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        2064,
        3200
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "a1",
              "name": "customer_name",
              "type": "string",
              "value": "={{ $json.body.customer_name }}"
            },
            {
              "id": "a2",
              "name": "customer_email",
              "type": "string",
              "value": "={{ $json.body.customer_email }}"
            },
            {
              "id": "a3",
              "name": "origin",
              "type": "string",
              "value": "={{ $json.body.origin }}"
            },
            {
              "id": "a4",
              "name": "destination",
              "type": "string",
              "value": "={{ $json.body.destination }}"
            },
            {
              "id": "a5",
              "name": "weight_kg",
              "type": "number",
              "value": "={{ $json.body.weight_kg }}"
            },
            {
              "id": "a6",
              "name": "mode",
              "type": "string",
              "value": "={{ $json.body.mode }}"
            },
            {
              "id": "a7",
              "name": "shipment_date",
              "type": "string",
              "value": "={{ $json.body.shipment_date }}"
            },
            {
              "id": "a8",
              "name": "cargo_type",
              "type": "string",
              "value": "={{ $json.body.cargo_type }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bc97cf95-54c0-4860-a7df-ae8259ffba29",
      "name": "Fetch BlueDart Rates",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2464,
        2976
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 2100629485,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg/edit#gid=21+1234567890",
          "cachedResultName": "BlueDart_Rates"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg/edit?usp=drivesdk",
          "cachedResultName": "Carrier Rate Sheets"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "02c2c378-1a0c-4691-88bf-38686108d2c5",
      "name": "Fetch DTDC Rates",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2480,
        3216
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 1842667957,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg/edit#gid=1842667957",
          "cachedResultName": "DTDC_Rates"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg/edit?usp=drivesdk",
          "cachedResultName": "Carrier Rate Sheets"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "ca1aecdf-50c1-4153-be6f-2ae078303b2f",
      "name": "Fetch Delhivery Rates",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        2480,
        3424
      ],
      "parameters": {
        "options": {},
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": 323178608,
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg/edit#gid=323178608",
          "cachedResultName": "Delhivery_Rates"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1qqsY3yqAMeZm13wrmJwcx08jzWm8zwCJrrWU-Q0KtIg/edit#gid=323178608",
          "cachedResultName": "Carrier Rate Sheets"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "107ab114-c7e5-44a1-ad3c-3df885c9819a",
      "name": "Merge Carrier Rates",
      "type": "n8n-nodes-base.merge",
      "position": [
        2768,
        3200
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3
    },
    {
      "id": "5a35b084-f2a2-4ae9-b188-fe1ea4206c76",
      "name": "Normalize & Structure Rate Data",
      "type": "n8n-nodes-base.code",
      "position": [
        2960,
        3200
      ],
      "parameters": {
        "jsCode": "const shipment = {\n  customer_name: $('Extract Shipment Fields').first().json.customer_name,\n  customer_email: $('Extract Shipment Fields').first().json.customer_email,\n  origin: $('Extract Shipment Fields').first().json.origin,\n  destination: $('Extract Shipment Fields').first().json.destination,\n  weight_kg: Number($('Extract Shipment Fields').first().json.weight_kg),\n  mode: $('Extract Shipment Fields').first().json.mode,\n  shipment_date: $('Extract Shipment Fields').first().json.shipment_date,\n  cargo_type: $('Extract Shipment Fields').first().json.cargo_type\n};\n\nconst carriers = [\n  {\n    carrier: 'BlueDart',\n    rate_per_kg: Number($('Fetch BlueDart Rates').first().json['Rate_Per_Kg']) || 0,\n    transit_days: $('Fetch BlueDart Rates').first().json['Transit_Days'] || 'N/A',\n    reliability_score: $('Fetch BlueDart Rates').first().json['Reliability_Score'] || 'N/A',\n    tracking: $('Fetch BlueDart Rates').first().json['Tracking'] || 'Yes',\n    insurance: $('Fetch BlueDart Rates').first().json['Insurance'] || 'Optional'\n  },\n  {\n    carrier: 'DTDC',\n    rate_per_kg: Number($('Fetch DTDC Rates').first().json['Rate_Per_Kg']) || 0,\n    transit_days: $('Fetch DTDC Rates').first().json['Transit_Days'] || 'N/A',\n    reliability_score: $('Fetch DTDC Rates').first().json['Reliability_Score'] || 'N/A',\n    tracking: $('Fetch DTDC Rates').first().json['Tracking'] || 'Yes',\n    insurance: $('Fetch DTDC Rates').first().json['Insurance'] || 'Optional'\n  },\n  {\n    carrier: 'Delhivery',\n    rate_per_kg: Number($('Fetch Delhivery Rates').first().json['Rate_Per_Kg']) || 0,\n    transit_days: $('Fetch Delhivery Rates').first().json['Transit_Days'] || 'N/A',\n    reliability_score: $('Fetch Delhivery Rates').first().json['Reliability_Score'] || 'N/A',\n    tracking: $('Fetch Delhivery Rates').first().json['Tracking'] || 'Yes',\n    insurance: $('Fetch Delhivery Rates').first().json['Insurance'] || 'Optional'\n  }\n];\n\nconst enrichedCarriers = carriers.map(c => ({\n  ...c,\n  total_cost: Math.round(c.rate_per_kg * shipment.weight_kg)\n}));\n\nreturn [{ json: { shipment, carriers: enrichedCarriers } }];\n"
      },
      "typeVersion": 2
    },
    {
      "id": "2e6651b9-1b10-4c2c-96a2-b081f31b7f60",
      "name": "GPT-4o Generate Quote HTML",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        3280,
        3200
      ],
      "parameters": {
        "resource": "chat"
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.8
    },
    {
      "id": "ae5fc641-92a0-4a25-a442-9379b4b7297b",
      "name": "Prepare Quote Fields",
      "type": "n8n-nodes-base.set",
      "position": [
        3584,
        3200
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "b1",
              "name": "html_quote",
              "type": "string",
              "value": "={{ $json.message.content }}"
            },
            {
              "id": "b2",
              "name": "customer_name",
              "type": "string",
              "value": "={{ $('Normalize & Structure Rate Data').item.json.shipment.customer_name }}"
            },
            {
              "id": "b3",
              "name": "customer_email",
              "type": "string",
              "value": "={{ $('Normalize & Structure Rate Data').item.json.shipment.customer_email }}"
            },
            {
              "id": "b4",
              "name": "origin",
              "type": "string",
              "value": "={{ $('Normalize & Structure Rate Data').item.json.shipment.origin }}"
            },
            {
              "id": "b5",
              "name": "destination",
              "type": "string",
              "value": "={{ $('Normalize & Structure Rate Data').item.json.shipment.destination }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "06c19b70-50ed-4a3f-bc1e-cbb65c2a157b",
      "name": "Generate Quote PDF",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3792,
        3200
      ],
      "parameters": {
        "url": "https://api.pdfshift.io/v3/convert/pdf",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "responseFormat": "file"
            }
          }
        },
        "jsonBody": "={\n  \"source\": {{ JSON.stringify($json.html_quote) }},\n  \"sandbox\": true,\n  \"landscape\": false,\n  \"format\": \"A4\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "X-API-Key",
              "value": "YOUR_PDFSHIFT_API_KEY_HERE"
            }
          ]
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "2b749950-2f7c-4e51-a4c3-420fde850a79",
      "name": "Send Quote Email to Customer",
      "type": "n8n-nodes-base.gmail",
      "position": [
        4160,
        3200
      ],
      "parameters": {
        "sendTo": "={{ $('Prepare Quote Fields').item.json.customer_email }}",
        "message": "=<p>Dear {{ $('Prepare Quote Fields').item.json.customer_name }},</p><p>Please find your freight quote attached for your shipment from <strong>{{ $('Prepare Quote Fields').item.json.origin }}</strong> to <strong>{{ $('Prepare Quote Fields').item.json.destination }}</strong>.</p><p>The PDF contains a ranked comparison from BlueDart, DTDC, and Delhivery \u2014 best-value option highlighted in green.</p><p>This quote is valid for <strong>7 days</strong>. Reply to this email to confirm your booking.</p><p>Best regards,<br/><strong>FreightPro Quotation Team</strong><br/>support@freightpro-demo.com | +91-98765-43210</p>",
        "options": {
          "attachmentsUi": {
            "attachmentsBinary": [
              {}
            ]
          }
        },
        "subject": "=Your Freight Quote \u2013 {{ $('Prepare Quote Fields').item.json.origin }} to {{ $('Prepare Quote Fields').item.json.destination }}"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "b536e1e8-5c8f-40ed-9f2a-a95ff565e30a",
      "name": "Slack \u2014 Send Workflow Error Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2000,
        3872
      ],
      "parameters": {
        "text": "=error in the workflow please check ",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0AN1UGL0RM",
          "cachedResultName": "all-n8n-automations"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "513c3eb4-8dfa-4636-b526-cf93d7409975",
      "name": "On Workflow Error",
      "type": "n8n-nodes-base.errorTrigger",
      "position": [
        1744,
        3872
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "90e3d541-5979-4999-bafc-4fb1083fcc27",
      "name": "Section: Error Handler",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1648,
        3696
      ],
      "parameters": {
        "color": 7,
        "width": 588,
        "height": 384,
        "content": "## \u26a0\ufe0f Error Handler\nCatches any failure in the workflow and posts a Slack alert. Wire the error output of critical nodes here to prevent silent failures going unnoticed."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "cd4365f6-0974-423a-8e19-03d10275f018",
  "nodeGroups": [],
  "connections": {
    "Fetch DTDC Rates": {
      "main": [
        [
          {
            "node": "Merge Carrier Rates",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "On Workflow Error": {
      "main": [
        [
          {
            "node": "Slack \u2014 Send Workflow Error Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Generate Quote PDF": {
      "main": [
        [
          {
            "node": "Send Quote Email to Customer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Carrier Rates": {
      "main": [
        [
          {
            "node": "Normalize & Structure Rate Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch BlueDart Rates": {
      "main": [
        [
          {
            "node": "Merge Carrier Rates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Quote Fields": {
      "main": [
        [
          {
            "node": "Generate Quote PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Delhivery Rates": {
      "main": [
        [
          {
            "node": "Merge Carrier Rates",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Extract Shipment Fields": {
      "main": [
        [
          {
            "node": "Fetch BlueDart Rates",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch DTDC Rates",
            "type": "main",
            "index": 0
          },
          {
            "node": "Fetch Delhivery Rates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Shipment Request Webhook": {
      "main": [
        [
          {
            "node": "Extract Shipment Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GPT-4o Generate Quote HTML": {
      "main": [
        [
          {
            "node": "Prepare Quote Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Normalize & Structure Rate Data": {
      "main": [
        [
          {
            "node": "GPT-4o Generate Quote HTML",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}