{
  "id": "6HuVv5w13YcvIEzu",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "Compare shipping rates with FedEx, DHL, BlueDart, Delhivery and Claude AI",
  "tags": [],
  "nodes": [
    {
      "id": "48452fd5-01e3-4211-86d6-cdaf40ab0c6a",
      "name": "Receive shipment request",
      "type": "n8n-nodes-base.webhook",
      "position": [
        3424,
        5872
      ],
      "parameters": {
        "path": "shipment-quote",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2
    },
    {
      "id": "dc940eba-a7fd-48f6-aeaa-39de558d8490",
      "name": "Validate input and calculate weights",
      "type": "n8n-nodes-base.code",
      "position": [
        3648,
        5872
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Extract shipment data from request body\nconst shipment = $input.item.json.body || $input.item.json;\n\n// Define required fields\nconst required = ['origin', 'destination', 'weight', 'length', 'width', 'height'];\n\n// Check for missing fields\nconst missing = required.filter(field => !shipment[field]);\nif (missing.length > 0) {\n  throw new Error(`Missing required fields: ${missing.join(', ')}`);\n}\n\n// Validate numeric values\nconst numericFields = ['weight', 'length', 'width', 'height'];\nfor (const field of numericFields) {\n  const value = parseFloat(shipment[field]);\n  if (isNaN(value) || value <= 0) {\n    throw new Error(`Invalid ${field}: must be a positive number`);\n  }\n}\n\n// Structure the data\nconst structured = {\n  origin: {\n    postalCode: shipment.origin.postalCode || shipment.origin,\n    country: shipment.origin.country || 'IN'\n  },\n  destination: {\n    postalCode: shipment.destination.postalCode || shipment.destination,\n    country: shipment.destination.country || 'IN'\n  },\n  package: {\n    weight: parseFloat(shipment.weight),\n    length: parseFloat(shipment.length),\n    width: parseFloat(shipment.width),\n    height: parseFloat(shipment.height)\n  },\n  preferences: {\n    deliverySpeed: shipment.deliverySpeed || 'standard',\n    insurance: Boolean(shipment.insurance),\n    cod: Boolean(shipment.cod),\n    autoBook: Boolean(shipment.autoBook)\n  },\n  metadata: {\n    requestId: `REQ-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n    requestedAt: new Date().toISOString()\n  }\n};\n\n// Calculate volumetric weight (standard divisor: 5000 for cm\u00b3 to kg)\nstructured.package.volumetricWeight = \n  (structured.package.length * structured.package.width * structured.package.height) / 5000;\n\n// Calculate chargeable weight (higher of actual or volumetric)\nstructured.package.chargeableWeight = Math.max(\n  structured.package.weight,\n  structured.package.volumetricWeight\n);\n\nreturn { json: structured };"
      },
      "typeVersion": 2
    },
    {
      "id": "49ff4abf-ce3b-4033-88a7-3e542f31f4fd",
      "name": "Get FedEx rates",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3872,
        5584
      ],
      "parameters": {
        "url": "https://api.fedex.com/rate/v1/rates/quotes",
        "options": {
          "timeout": 10000
        },
        "jsonBody": "={\n  \"accountNumber\": {\n    \"value\": \"{{$credentials.accountNumber}}\"\n  },\n  \"requestedShipment\": {\n    \"shipper\": {\n      \"address\": {\n        \"postalCode\": \"{{$json.origin.postalCode}}\",\n        \"countryCode\": \"{{$json.origin.country}}\"\n      }\n    },\n    \"recipient\": {\n      \"address\": {\n        \"postalCode\": \"{{$json.destination.postalCode}}\",\n        \"countryCode\": \"{{$json.destination.country}}\"\n      }\n    },\n    \"pickupType\": \"DROPOFF_AT_FEDEX_LOCATION\",\n    \"serviceType\": \"FEDEX_GROUND\",\n    \"rateRequestType\": [\"ACCOUNT\"],\n    \"requestedPackageLineItems\": [\n      {\n        \"weight\": {\n          \"value\": {{$json.package.chargeableWeight}},\n          \"units\": \"KG\"\n        },\n        \"dimensions\": {\n          \"length\": {{$json.package.length}},\n          \"width\": {{$json.package.width}},\n          \"height\": {{$json.package.height}},\n          \"units\": \"CM\"\n        }\n      }\n    ]\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "fedExApi"
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "25831822-8f70-4818-b9cd-e75dc86d0f5f",
      "name": "Get DHL rates",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3872,
        5776
      ],
      "parameters": {
        "url": "https://api-eu.dhl.com/mydhlapi/v1/rates",
        "options": {
          "timeout": 10000
        },
        "jsonBody": "={\n  \"customerDetails\": {\n    \"shipperDetails\": {\n      \"postalCode\": \"{{$json.origin.postalCode}}\",\n      \"countryCode\": \"{{$json.origin.country}}\"\n    },\n    \"receiverDetails\": {\n      \"postalCode\": \"{{$json.destination.postalCode}}\",\n      \"countryCode\": \"{{$json.destination.country}}\"\n    }\n  },\n  \"accounts\": [\n    {\n      \"typeCode\": \"shipper\",\n      \"number\": \"{{$credentials.accountNumber}}\"\n    }\n  ],\n  \"plannedShippingDateAndTime\": \"{{new Date().toISOString()}}\",\n  \"unitOfMeasurement\": \"metric\",\n  \"isCustomsDeclarable\": false,\n  \"monetaryAmount\": [\n    {\n      \"typeCode\": \"declaredValue\",\n      \"value\": 100,\n      \"currency\": \"INR\"\n    }\n  ],\n  \"packages\": [\n    {\n      \"weight\": {{$json.package.chargeableWeight}},\n      \"dimensions\": {\n        \"length\": {{$json.package.length}},\n        \"width\": {{$json.package.width}},\n        \"height\": {{$json.package.height}}\n      }\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "dhlApi"
      },
      "credentials": {
        "dhlApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "1722bca0-bbc4-48a6-98cd-2599907fa4a5",
      "name": "Get BlueDart rates",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3872,
        5968
      ],
      "parameters": {
        "url": "https://api.bluedart.com/servlet/RoutingServlet",
        "options": {
          "timeout": 10000
        },
        "jsonBody": "={\n  \"Request\": {\n    \"ServiceType\": \"{{$json.preferences.deliverySpeed === 'express' ? 'P' : 'S'}}\",\n    \"OriginPincode\": \"{{$json.origin.postalCode}}\",\n    \"DestinationPincode\": \"{{$json.destination.postalCode}}\",\n    \"Weight\": \"{{$json.package.chargeableWeight}}\",\n    \"Dimensions\": {\n      \"Length\": {{$json.package.length}},\n      \"Width\": {{$json.package.width}},\n      \"Height\": {{$json.package.height}}\n    },\n    \"IsCOD\": \"{{$json.preferences.cod ? 'Y' : 'N'}}\",\n    \"CustomerCode\": \"{{$credentials.customerCode}}\",\n    \"LoginID\": \"{{$credentials.loginId}}\"\n  }\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        },
        "nodeCredentialType": "blueDartApi"
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "58beb078-f224-4077-b4c9-24ff36ca46d7",
      "name": "Get Delhivery rates",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3872,
        6160
      ],
      "parameters": {
        "url": "https://track.delhivery.com/api/kinko/v1/invoice/charges/.json",
        "options": {
          "timeout": 10000
        },
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "ss",
              "value": "Delivered"
            },
            {
              "name": "md",
              "value": "={{ $json.preferences.deliverySpeed === 'express' ? 'E' : 'S' }}"
            },
            {
              "name": "cgm",
              "value": "={{ $json.package.chargeableWeight }}"
            },
            {
              "name": "o_pin",
              "value": "={{ $json.origin.postalCode }}"
            },
            {
              "name": "d_pin",
              "value": "={{ $json.destination.postalCode }}"
            }
          ]
        },
        "nodeCredentialType": "delhiveryApi"
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "67140ee6-bba6-4482-a3b0-38eb6d10af27",
      "name": "Combine all carrier responses",
      "type": "n8n-nodes-base.merge",
      "position": [
        4096,
        5872
      ],
      "parameters": {
        "mode": "mergeByPosition"
      },
      "typeVersion": 3
    },
    {
      "id": "4971d1ba-2f6e-4f67-8c90-d4443917cb83",
      "name": "Parse and normalize carrier rates",
      "type": "n8n-nodes-base.code",
      "position": [
        4320,
        5872
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Get shipment details and carrier responses\nconst shipment = $('Validate input and calculate weights').item.json;\nconst fedex = $('Get FedEx rates').item.json;\nconst dhl = $('Get DHL rates').item.json;\nconst bluedart = $('Get BlueDart rates').item.json;\nconst delhivery = $('Get Delhivery rates').item.json;\n\nconst rates = [];\n\n// Parse FedEx response\ntry {\n  if (fedex && !fedex.error && fedex.output?.rateReplyDetails) {\n    const fedexRate = fedex.output.rateReplyDetails[0];\n    rates.push({\n      carrier: 'FedEx',\n      cost: parseFloat(fedexRate.ratedShipmentDetails?.[0]?.totalNetCharge || 0),\n      currency: fedexRate.ratedShipmentDetails?.[0]?.currency || 'INR',\n      transitDays: parseInt(fedexRate.commit?.transitTime || 999),\n      service: fedexRate.serviceName || 'Standard',\n      available: true\n    });\n  }\n} catch (error) {\n  console.log('FedEx parsing error:', error.message);\n}\n\n// Parse DHL response\ntry {\n  if (dhl && !dhl.error && dhl.products && dhl.products.length > 0) {\n    const dhlRate = dhl.products[0];\n    rates.push({\n      carrier: 'DHL',\n      cost: parseFloat(dhlRate.totalPrice?.[0]?.price || 0),\n      currency: dhlRate.totalPrice?.[0]?.priceCurrency || 'INR',\n      transitDays: parseInt(dhlRate.deliveryCapabilities?.estimatedDeliveryDateAndTime ? \n        Math.ceil((new Date(dhlRate.deliveryCapabilities.estimatedDeliveryDateAndTime) - new Date()) / (1000 * 60 * 60 * 24)) : 999),\n      service: dhlRate.productName || 'Standard',\n      available: true\n    });\n  }\n} catch (error) {\n  console.log('DHL parsing error:', error.message);\n}\n\n// Parse BlueDart response\ntry {\n  if (bluedart && !bluedart.error && bluedart.Response) {\n    rates.push({\n      carrier: 'BlueDart',\n      cost: parseFloat(bluedart.Response.Charges?.TotalAmount || 0),\n      currency: 'INR',\n      transitDays: parseInt(bluedart.Response.TransitDays || 999),\n      service: bluedart.Response.ServiceType || 'Standard',\n      available: bluedart.Response.Status === 'Success'\n    });\n  }\n} catch (error) {\n  console.log('BlueDart parsing error:', error.message);\n}\n\n// Parse Delhivery response\ntry {\n  if (delhivery && !delhivery.error && Array.isArray(delhivery) && delhivery.length > 0) {\n    const delhiveryRate = delhivery[0];\n    rates.push({\n      carrier: 'Delhivery',\n      cost: parseFloat(delhiveryRate.total_amount || 0),\n      currency: 'INR',\n      transitDays: parseInt(delhiveryRate.transit_time || 999),\n      service: delhiveryRate.mode || 'Standard',\n      available: true\n    });\n  }\n} catch (error) {\n  console.log('Delhivery parsing error:', error.message);\n}\n\n// Filter out invalid rates and sort by cost\nconst validRates = rates.filter(r => r.cost > 0 && r.available);\n\nif (validRates.length === 0) {\n  throw new Error('No valid rates received from any carrier. Please check API credentials and service availability.');\n}\n\n// Sort rates by cost (lowest first)\nvalidRates.sort((a, b) => a.cost - b.cost);\n\nreturn {\n  json: {\n    shipmentDetails: shipment,\n    rates: validRates,\n    ratesCount: validRates.length,\n    carriersQueried: 4,\n    carriersResponded: validRates.length\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "3353c46c-c50f-4cee-a8bd-d3628f105ea5",
      "name": "Analyze with Claude AI",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        4544,
        5872
      ],
      "parameters": {
        "text": "=You are a shipping logistics expert. Analyze these shipping rates and recommend the best carrier based on the customer's preferences.\n\n**Available Rates:**\n{{ JSON.stringify($json.rates, null, 2) }}\n\n**Customer Preferences:**\n- Delivery Speed: {{ $json.shipmentDetails.preferences.deliverySpeed }}\n- Insurance Required: {{ $json.shipmentDetails.preferences.insurance }}\n- Cash on Delivery (COD): {{ $json.shipmentDetails.preferences.cod }}\n\n**Analysis Guidelines:**\n1. If deliverySpeed is \"express\", prioritize carriers with fewer transit days\n2. If deliverySpeed is \"standard\", balance cost and transit time\n3. Consider insurance and COD requirements\n4. Provide a value score from 1-100 based on overall value\n\n**Response Format (JSON only):**\n{\n  \"recommendedCarrier\": \"carrier name\",\n  \"reasoning\": \"brief explanation of why this carrier is best\",\n  \"valueScore\": 85\n}",
        "options": {
          "systemMessage": "You are a shipping logistics expert that provides carrier recommendations in JSON format only. Never include markdown code blocks or additional text."
        },
        "promptType": "define"
      },
      "typeVersion": 1.6
    },
    {
      "id": "cd07d172-2e69-48d5-9701-8283e895dd26",
      "name": "Claude AI model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        4616,
        6096
      ],
      "parameters": {
        "model": "claude-sonnet-4-20250514",
        "options": {
          "temperature": 0.3
        }
      },
      "credentials": {
        "anthropicApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "6d8c057a-efd9-4c53-b5b8-4d343da94a7d",
      "name": "Build final response",
      "type": "n8n-nodes-base.code",
      "position": [
        4896,
        5872
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Extract AI response\nconst aiResponse = $input.item.json;\nlet aiText = aiResponse.response || aiResponse.output || aiResponse.text || '';\n\n// Handle content array format\nif (aiResponse.content && Array.isArray(aiResponse.content)) {\n  aiText = aiResponse.content[0]?.text || '';\n}\n\n// Clean JSON from markdown code blocks\nconst cleanText = aiText\n  .replace(/```json\\s*/g, '')\n  .replace(/```\\s*/g, '')\n  .trim();\n\nlet aiRecommendation;\ntry {\n  aiRecommendation = JSON.parse(cleanText);\n} catch (error) {\n  throw new Error(`Failed to parse AI response: ${error.message}. Response was: ${cleanText}`);\n}\n\n// Get normalized rates data\nconst ratesData = $('Parse and normalize carrier rates').item.json;\n\n// Find the recommended carrier in rates\nconst recommended = ratesData.rates.find(\n  r => r.carrier.toLowerCase() === aiRecommendation.recommendedCarrier.toLowerCase()\n);\n\nif (!recommended) {\n  throw new Error(`Recommended carrier \"${aiRecommendation.recommendedCarrier}\" not found in available rates`);\n}\n\n// Calculate comparison metrics\nconst sorted = [...ratesData.rates].sort((a, b) => a.cost - b.cost);\nconst cheapest = sorted[0];\nconst fastest = [...ratesData.rates].sort((a, b) => a.transitDays - b.transitDays)[0];\nconst mostExpensive = sorted[sorted.length - 1];\n\nconst savingsVsMostExpensive = mostExpensive.cost - recommended.cost;\nconst extraCostVsCheapest = recommended.cost - cheapest.cost;\n\nreturn {\n  json: {\n    requestId: ratesData.shipmentDetails.metadata.requestId,\n    recommended: {\n      ...recommended,\n      reasoning: aiRecommendation.reasoning,\n      valueScore: aiRecommendation.valueScore\n    },\n    comparison: {\n      cheapestCarrier: cheapest.carrier,\n      cheapestCost: cheapest.cost.toFixed(2),\n      fastestCarrier: fastest.carrier,\n      fastestTransitDays: fastest.transitDays,\n      savingsVsMostExpensive: savingsVsMostExpensive.toFixed(2),\n      extraCostVsCheapest: extraCostVsCheapest.toFixed(2),\n      totalOptionsCompared: ratesData.rates.length\n    },\n    allRates: sorted,\n    shipmentDetails: ratesData.shipmentDetails\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "86b26897-d45d-4305-bf3e-0b51bfba2090",
      "name": "Check if auto-booking enabled",
      "type": "n8n-nodes-base.if",
      "position": [
        5120,
        5872
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "boolean",
                "operation": "true"
              },
              "leftValue": "={{ $json.shipmentDetails.preferences.autoBook }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "ce8a11a8-6b61-4a78-8397-e8988835f20d",
      "name": "Prepare booking request",
      "type": "n8n-nodes-base.code",
      "position": [
        5344,
        5776
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const response = $input.item.json;\nconst carrier = response.recommended.carrier;\n\n// Map carriers to their booking endpoints\nconst carrierEndpoints = {\n  'FedEx': 'https://api.fedex.com/ship/v1/shipments',\n  'DHL': 'https://api-eu.dhl.com/mydhlapi/v1/shipments',\n  'BlueDart': 'https://api.bluedart.com/servlet/RoutingServlet',\n  'Delhivery': 'https://track.delhivery.com/api/cmu/create.json'\n};\n\nconst endpoint = carrierEndpoints[carrier];\n\nif (!endpoint) {\n  throw new Error(`No booking endpoint configured for carrier: ${carrier}`);\n}\n\n// Generate unique booking reference\nconst bookingRef = `BK-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n\nreturn {\n  json: {\n    carrier,\n    endpoint,\n    shipmentData: response.shipmentDetails,\n    recommendedService: response.recommended.service,\n    estimatedCost: response.recommended.cost,\n    bookingRef\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "b9272e4f-0012-4475-9260-03c051c5896c",
      "name": "Book shipment with carrier",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        5568,
        5776
      ],
      "parameters": {
        "url": "={{ $json.endpoint }}",
        "options": {
          "timeout": 15000
        },
        "jsonBody": "={\n  \"shipment\": {{ JSON.stringify($json.shipmentData) }},\n  \"service\": \"{{ $json.recommendedService }}\",\n  \"reference\": \"{{ $json.bookingRef }}\"\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "06218eee-b8f1-4a42-a153-fa0d96f50884",
      "name": "Format booking confirmation",
      "type": "n8n-nodes-base.code",
      "position": [
        5792,
        5776
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const bookingResponse = $input.item.json;\nconst preparedData = $('Prepare booking request').item.json;\nconst recommendation = $('Build final response').item.json;\n\n// Extract tracking number from various carrier response formats\nlet trackingNumber = 'PENDING';\n\nif (bookingResponse.tracking_number) {\n  trackingNumber = bookingResponse.tracking_number;\n} else if (bookingResponse.trackingNumber) {\n  trackingNumber = bookingResponse.trackingNumber;\n} else if (bookingResponse.trackingId) {\n  trackingNumber = bookingResponse.trackingId;\n} else if (bookingResponse.shipmentIdentificationNumber) {\n  trackingNumber = bookingResponse.shipmentIdentificationNumber;\n}\n\nreturn {\n  json: {\n    success: true,\n    booked: true,\n    status: 'Shipment booked successfully',\n    carrier: recommendation.recommended.carrier,\n    trackingNumber,\n    estimatedCost: recommendation.recommended.cost,\n    currency: recommendation.recommended.currency,\n    estimatedTransitDays: recommendation.recommended.transitDays,\n    service: recommendation.recommended.service,\n    savings: recommendation.comparison.savingsVsMostExpensive,\n    bookingRef: preparedData.bookingRef,\n    requestId: recommendation.requestId\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "1c155c2d-46e2-4926-a1b5-3eb1715f2635",
      "name": "Format quote response",
      "type": "n8n-nodes-base.code",
      "position": [
        5792,
        5968
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const response = $input.item.json;\n\nreturn {\n  json: {\n    success: true,\n    booked: false,\n    status: 'Quote generated - manual booking required',\n    message: 'Rate comparison completed. Enable autoBook in request to book automatically.',\n    recommended: {\n      carrier: response.recommended.carrier,\n      cost: response.recommended.cost,\n      currency: response.recommended.currency,\n      transitDays: response.recommended.transitDays,\n      service: response.recommended.service,\n      reasoning: response.recommended.reasoning,\n      valueScore: response.recommended.valueScore\n    },\n    comparison: response.comparison,\n    allRates: response.allRates.map(rate => ({\n      carrier: rate.carrier,\n      cost: rate.cost,\n      currency: rate.currency,\n      transitDays: rate.transitDays,\n      service: rate.service\n    })),\n    requestId: response.requestId\n  }\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "75d57ff1-41b6-4f26-959e-9745cbec5e55",
      "name": "Send response to client",
      "type": "n8n-nodes-base.respondToWebhook",
      "position": [
        6016,
        5872
      ],
      "parameters": {
        "options": {
          "responseHeaders": {
            "entries": [
              {
                "name": "Content-Type",
                "value": "application/json"
              }
            ]
          }
        },
        "respondWith": "json",
        "responseBody": "={{ JSON.stringify($json, null, 2) }}"
      },
      "typeVersion": 1
    },
    {
      "id": "67db4ae5-ac95-4285-b69c-9cf11b29d36d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2432,
        5200
      ],
      "parameters": {
        "width": 760,
        "height": 1084,
        "content": "## Compare shipping rates with FedEx, DHL, BlueDart, Delhivery and Claude AI\n\nThis AI-powered workflow automatically compares shipping rates across four major carriers, uses Claude AI to recommend the best option based on cost and delivery time, and optionally books shipments instantly.\n\n### How it works\n\n1. **Receive request** - Webhook accepts shipment details (origin, destination, weight, dimensions)\n2. **Validate data** - Checks required fields and calculates volumetric weight\n3. **Query carriers** - Simultaneously fetches rates from FedEx, DHL, BlueDart, and Delhivery\n4. **Normalize responses** - Parses different carrier formats into standardized structure\n5. **AI analysis** - Claude AI evaluates options considering cost, speed, and preferences\n6. **Return results** - Provides recommendation with savings analysis, or books shipment if enabled\n\n### Setup steps\n\n1. Import this workflow into your n8n instance\n2. Configure carrier API credentials:\n   - **FedEx API** - Get credentials from FedEx Developer Portal\n   - **DHL API** - Register at DHL Developer Portal\n   - **BlueDart API** - Contact BlueDart for API access\n   - **Delhivery API** - Get token from Delhivery partner portal\n3. Add **Anthropic API** credentials for Claude AI\n4. Activate workflow to generate webhook URL\n5. Test with sample request:\n   ```json\n   {\n     \"origin\": \"400001\",\n     \"destination\": \"110001\",\n     \"weight\": 2,\n     \"length\": 30,\n     \"width\": 20,\n     \"height\": 15,\n     \"deliverySpeed\": \"standard\",\n     \"autoBook\": false\n   }\n   ```\n\n### Features\n\n- **Real-time rates** from 4 carriers\n- **AI-powered recommendations** considering cost, speed, and preferences  \n- **Automatic booking** when enabled\n- **Comprehensive error handling**\n- **Detailed cost comparison** and savings analysis"
      },
      "typeVersion": 1
    },
    {
      "id": "52fd0104-1bbc-46ac-9d41-1783efe02dff",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3340,
        5704
      ],
      "parameters": {
        "color": 4,
        "width": 424,
        "height": 328,
        "content": "## 1. Input validation"
      },
      "typeVersion": 1
    },
    {
      "id": "8dc75b93-73ba-4e3a-aebd-f37f276ea69c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3788,
        5444
      ],
      "parameters": {
        "color": 4,
        "width": 456,
        "height": 684,
        "content": "## 2. Fetch carrier rates"
      },
      "typeVersion": 1
    },
    {
      "id": "1ea2ac82-f318-40d6-a862-9926a8ea0f10",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        4292,
        5748
      ],
      "parameters": {
        "color": 4,
        "width": 712,
        "height": 284,
        "content": "## 3. AI recommendation"
      },
      "typeVersion": 1
    },
    {
      "id": "b99daf49-429a-4c56-a660-23d11a0d982d",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        5052,
        5636
      ],
      "parameters": {
        "color": 4,
        "width": 1176,
        "height": 492,
        "content": "## 4. Book or quote"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "21367db6-abe9-433d-acaf-c68d2cbbdef3",
  "connections": {
    "Get DHL rates": {
      "main": [
        [
          {
            "node": "Combine all carrier responses",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Claude AI model": {
      "ai_languageModel": [
        [
          {
            "node": "Analyze with Claude AI",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Get FedEx rates": {
      "main": [
        [
          {
            "node": "Combine all carrier responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get BlueDart rates": {
      "main": [
        [
          {
            "node": "Combine all carrier responses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Delhivery rates": {
      "main": [
        [
          {
            "node": "Combine all carrier responses",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Build final response": {
      "main": [
        [
          {
            "node": "Check if auto-booking enabled",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format quote response": {
      "main": [
        [
          {
            "node": "Send response to client",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Analyze with Claude AI": {
      "main": [
        [
          {
            "node": "Build final response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare booking request": {
      "main": [
        [
          {
            "node": "Book shipment with carrier",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Receive shipment request": {
      "main": [
        [
          {
            "node": "Validate input and calculate weights",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Book shipment with carrier": {
      "main": [
        [
          {
            "node": "Format booking confirmation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Format booking confirmation": {
      "main": [
        [
          {
            "node": "Send response to client",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if auto-booking enabled": {
      "main": [
        [
          {
            "node": "Prepare booking request",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Format quote response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Combine all carrier responses": {
      "main": [
        [
          {
            "node": "Parse and normalize carrier rates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse and normalize carrier rates": {
      "main": [
        [
          {
            "node": "Analyze with Claude AI",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Validate input and calculate weights": {
      "main": [
        [
          {
            "node": "Get FedEx rates",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get DHL rates",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get BlueDart rates",
            "type": "main",
            "index": 0
          },
          {
            "node": "Get Delhivery rates",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}