AutomationFlowsAI & RAG › Clear Integration of Gpt-4 with Key Tools for Enhanced Functionality

Clear Integration of Gpt-4 with Key Tools for Enhanced Functionality

ByNitin Garg @nitin-animoautomation on n8n.io

Turn discovery call forms into polished, personalized proposals in seconds. This workflow captures prospect information via Typeform, uses GPT-4 to write compelling proposal content, and automatically creates professional PandaDoc documents with pricing tables.

Event trigger★★★★☆ complexityAI-powered25 nodesTypeform TriggerOpenAIHTTP Request
AI & RAG Trigger: Event Nodes: 25 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #12032 — we link there as the canonical source.

This workflow follows the HTTP Request → OpenAI recipe pattern — see all workflows that pair these two integrations.

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 →

Download .json
{
  "id": "yt4wWVKefnaLtsI5",
  "name": "AI Proposal Generator - Typeform to PandaDoc with GPT-4",
  "tags": [],
  "nodes": [
    {
      "id": "e9b4a85d-c140-4129-b54f-1d28658a63c1",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -272,
        -256
      ],
      "parameters": {
        "color": 5,
        "width": 376,
        "height": 824,
        "content": "## \ud83d\udcc4 AI Proposal Generator\n\nAutomatically generate professional, personalized proposals from discovery call intake forms.\n\n### How it works\n1. **Prospect submits** Typeform with project details\n2. **Workflow validates** required fields (email, company)\n3. **AI selects template** based on budget & complexity\n4. **GPT-4 writes** personalized proposal content\n5. **GPT-4 generates** realistic project milestones\n6. **PandaDoc creates** professional document with pricing\n7. **Slack notifies** you with direct link to review\n\n### Setup (15-20 minutes)\n\u2610 Add **OpenAI API** credential (select in GPT nodes)\n\u2610 Add **Typeform API** credential\n\u2610 Add **PandaDoc API** credential (HTTP Header Auth)\n\u2610 Create Typeform with discovery questions\n\u2610 Create 2 PandaDoc templates (Quick Quote + Standard)\n\u2610 Update **Config** node with your company info\n\u2610 Set your **Slack webhook URL** in Config\n\n### Customize\n- Adjust **quickQuoteThreshold** in Config (default: $2,500)\n- Edit GPT prompts to match your writing style\n- Add industry-specific case studies to Config"
      },
      "typeVersion": 1
    },
    {
      "id": "f2581930-af38-4470-a7ae-8123cd0bf1fd",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        144,
        -256
      ],
      "parameters": {
        "color": 5,
        "width": 628,
        "height": 832,
        "content": "## 1. Capture & Extract\n\nThis section handles the intake process:\n\n**Config** \u2192 Stores your company info, PandaDoc template IDs, Slack webhook, and case studies\n\n**Typeform Trigger** \u2192 Fires when prospect submits discovery form\n\n**Extract & Transform Data** \u2192 Parses all form fields, converts budget ranges to numbers, calculates deposit amounts, and determines which template to use"
      },
      "typeVersion": 1
    },
    {
      "id": "05e4268d-3563-433a-89c5-bec383eb66e0",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        816,
        -256
      ],
      "parameters": {
        "color": 5,
        "width": 856,
        "height": 832,
        "content": "## 2. Validate & Route to AI\n\nEnsures data quality before AI processing:\n\n**Check Required Fields** \u2192 Validates email and company name exist (routes to error if missing)\n\n**Route: Quick Quote or Standard?** \u2192 Budget < $2,500 AND not complex \u2192 Quick Quote. Otherwise \u2192 Standard Proposal\n\n**AI: Generate Quick Quote** \u2192 GPT-4 writes concise 1-page quote with benefits and pricing\n\n**AI: Generate Standard Proposal** \u2192 GPT-4 writes detailed multi-page proposal with deliverables and ROI"
      },
      "typeVersion": 1
    },
    {
      "id": "a680aedd-1386-4e66-81c2-37f49f532aab",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1712,
        -256
      ],
      "parameters": {
        "color": 5,
        "width": 824,
        "height": 832,
        "content": "## 3. Parse, Timeline & Merge\n\nProcesses AI output and adds project schedule:\n\n**Parse AI Proposal Response** \u2192 Extracts JSON from GPT response, handles markdown cleanup, merges with form data\n\n**AI: Generate Project Milestones** \u2192 GPT-4 creates 4-phase timeline based on solution complexity\n\n**Parse Milestone Response** \u2192 Extracts timeline JSON with fallback defaults if parsing fails\n\n**Combine Proposal + Milestones** \u2192 Merges proposal content with timeline for complete document data"
      },
      "typeVersion": 1
    },
    {
      "id": "c89b55bb-156c-4744-bc67-0780a426686a",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2560,
        -256
      ],
      "parameters": {
        "color": 5,
        "width": 700,
        "height": 752,
        "content": "## 4. Create PandaDoc\n\nAssembles the final proposal document:\n\n**Check: AI Parse Successful?** \u2192 Routes to error notification if GPT response couldn't be parsed\n\n**Create PandaDoc Document** \u2192 Sends all data to PandaDoc API, populates template tokens, builds pricing table\n\n**Check: Document Created?** \u2192 Verifies PandaDoc returned a document ID"
      },
      "typeVersion": 1
    },
    {
      "id": "0e979740-f949-4041-b675-8c95d239628c",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3280,
        -256
      ],
      "parameters": {
        "color": 5,
        "width": 380,
        "height": 752,
        "content": "## 5. Send Notifications\n\nKeeps you informed of every submission:\n\n**Notify: Proposal Ready** \u2192 Rich Slack message with client name, value, template type, expiry date, and direct PandaDoc link\n\n**Notify: PandaDoc Failed** \u2192 Error details so you can manually follow up with the prospect"
      },
      "typeVersion": 1
    },
    {
      "id": "6bffdc22-e3d6-46ca-bce4-731936108b81",
      "name": "\u2699\ufe0f Config",
      "type": "n8n-nodes-base.set",
      "position": [
        176,
        48
      ],
      "parameters": {
        "mode": "raw",
        "options": {},
        "jsonOutput": "{\n  \"senderEmail\": \"user@example.com\",\n  \"senderFirstName\": \"Your\",\n  \"senderLastName\": \"Name\",\n  \"senderCompany\": \"Your Company\",\n  \"senderTitle\": \"Your Title\",\n  \"senderPhone\": \"+1234567890\",\n  \"quickQuoteTemplateId\": \"YOUR_PANDADOC_QUICK_QUOTE_TEMPLATE_ID\",\n  \"standardProposalTemplateId\": \"YOUR_PANDADOC_STANDARD_TEMPLATE_ID\",\n  \"quickQuoteThreshold\": \"2500\",\n  \"slackWebhookUrl\": \"YOUR_SLACK_WEBHOOK_URL\",\n  \"caseStudies\": {\n    \"default\": {\n      \"company\": \"Example Client\",\n      \"industry\": \"Professional Services\",\n      \"results\": \"20+ hours/week saved\",\n      \"testimonial\": \"The ROI was immediate.\"\n    }\n  }\n}"
      },
      "typeVersion": 3.4
    },
    {
      "id": "62036532-bec5-47ab-8bb5-328e6b8ff47c",
      "name": "\ud83d\udce5 Typeform Trigger",
      "type": "n8n-nodes-base.typeformTrigger",
      "position": [
        384,
        48
      ],
      "parameters": {
        "formId": "YOUR_TYPEFORM_FORM_ID"
      },
      "typeVersion": 1
    },
    {
      "id": "c2a3b89a-aeb2-4aaa-82ff-9e0d8a009959",
      "name": "\ud83d\udd04 Extract & Transform Data",
      "type": "n8n-nodes-base.code",
      "position": [
        592,
        48
      ],
      "parameters": {
        "jsCode": "const config = $('\u2699\ufe0f Config').first().json;\nconst formData = $input.first().json;\n\nconst extractedData = {\n  companyName: formData[\"What's your company name?\"] || '',\n  websiteUrl: formData[\"What's your company website?\"] || '',\n  businessDescription: formData[\"Tell us about your business\"] || '',\n  industry: formData[\"What industry are you in?\"] || '',\n  currentProblem: formData[\"What's your biggest operational challenge?\"] || '',\n  desiredSolution: formData[\"What would the ideal solution look like?\"] || '',\n  platformsToUse: formData[\"What tools/platforms do you currently use?\"] || '',\n  projectComplexity: formData[\"How complex is this project?\"] || '',\n  clientFirstName: formData[\"First name\"] || '',\n  clientLastName: formData[\"Last name\"] || '',\n  clientEmail: formData[\"Email address\"] || '',\n  additionalNotes: formData[\"Anything else we should know?\"] || ''\n};\n\n// Parse budget range to number\nfunction parseBudget(label) {\n  const l = (label || '').toLowerCase();\n  if (l.includes('under') && l.includes('1,500')) return 1250;\n  if (l.includes('1,500') && l.includes('2,500')) return 2000;\n  if (l.includes('2,500') && l.includes('5,000')) return 3750;\n  if (l.includes('5,000') && l.includes('10,000')) return 7500;\n  if (l.includes('10,000+')) return 12500;\n  return 3000;\n}\n\nextractedData.budgetLabel = formData[\"What's your estimated budget?\"] || '';\nextractedData.estimatedValue = parseBudget(extractedData.budgetLabel);\n\n// Template selection logic\nconst threshold = Number(config.quickQuoteThreshold) || 2500;\nconst isComplex = (extractedData.projectComplexity || '').toLowerCase().includes('complex');\n\nextractedData.selectedTemplate = (extractedData.estimatedValue < threshold && !isComplex) ? 'quick_quote' : 'standard';\nextractedData.templateReason = extractedData.selectedTemplate === 'quick_quote' \n  ? `Budget $${extractedData.estimatedValue} < $${threshold}` \n  : `Budget $${extractedData.estimatedValue} >= $${threshold} or complex project`;\nextractedData.pandaDocTemplateId = extractedData.selectedTemplate === 'quick_quote' \n  ? config.quickQuoteTemplateId \n  : config.standardProposalTemplateId;\n\n// Calculate amounts\nextractedData.depositAmount = Math.round(extractedData.estimatedValue * 0.5);\nextractedData.balanceAmount = extractedData.estimatedValue - extractedData.depositAmount;\n\n// Add dates\nconst today = new Date();\nconst validityDays = extractedData.selectedTemplate === 'quick_quote' ? 7 : 14;\nconst expiryDate = new Date(today.getTime() + validityDays * 24 * 60 * 60 * 1000);\nextractedData.documentDate = today.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });\nextractedData.proposalExpiryDate = expiryDate.toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });\n\nextractedData.config = config;\nextractedData.caseStudy = config.caseStudies?.default || {};\n\nreturn [{ json: extractedData }];"
      },
      "typeVersion": 2
    },
    {
      "id": "584e5d2e-f38e-479b-853f-49cedfccf7ca",
      "name": "\u2705 Check Required Fields",
      "type": "n8n-nodes-base.if",
      "position": [
        896,
        48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "check-email",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.clientEmail }}",
              "rightValue": ""
            },
            {
              "id": "check-company",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.companyName }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "adc5b18f-b488-45d6-beca-39e2cee0b7b1",
      "name": "\ud83d\udd00 Route: Quick Quote or Standard?",
      "type": "n8n-nodes-base.if",
      "position": [
        1104,
        32
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "check-template",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.selectedTemplate }}",
              "rightValue": "quick_quote"
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "cfb596d7-b361-4034-b4dd-a8c35d062037",
      "name": "\ud83e\udd16 AI: Generate Quick Quote",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1328,
        16
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "options": {
          "temperature": 0.7
        },
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a professional proposal writer for an automation agency. Write concise, benefit-focused proposals that emphasize ROI and time savings."
            },
            {
              "content": "=Generate a Quick Quote proposal for this prospective client:\n\n**Company:** {{ $json.companyName }}\n**Industry:** {{ $json.industry }}\n**Their Challenge:** {{ $json.currentProblem }}\n**Desired Outcome:** {{ $json.desiredSolution }}\n**Current Tools:** {{ $json.platformsToUse }}\n**Budget:** ${{ $json.estimatedValue }}\n\nWrite a concise, compelling quick quote. Return ONLY valid JSON (no markdown backticks):\n{\n  \"title\": \"Quick Quote: [specific solution name that addresses their challenge]\",\n  \"challengeSummary\": \"1-2 sentence summary of their pain point in your words\",\n  \"solutionType\": \"Short solution name (e.g., CRM Automation, Lead Follow-up System)\",\n  \"scopeDescription\": \"2-3 sentence description of what you'll build for them\",\n  \"impactBullet1\": \"Specific benefit with metric (e.g., Save 10+ hours/week on manual data entry)\",\n  \"impactBullet2\": \"Second key benefit with metric\",\n  \"impactBullet3\": \"Third key benefit with metric\",\n  \"timeSavings\": \"X hours/week\",\n  \"costSavings\": \"$X/month\"\n}"
            }
          ]
        },
        "jsonOutput": true
      },
      "typeVersion": 1.6
    },
    {
      "id": "06292822-f5ab-4535-b51d-d679e2ceb70b",
      "name": "\ud83e\udd16 AI: Generate Standard Proposal",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1328,
        224
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "options": {
          "temperature": 0.7
        },
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a professional proposal writer for an automation agency. Write detailed, compelling proposals that demonstrate deep understanding of the client's business and clearly articulate ROI."
            },
            {
              "content": "=Generate a detailed Standard Proposal for this prospective client:\n\n**Company:** {{ $json.companyName }}\n**Industry:** {{ $json.industry }}\n**About Their Business:** {{ $json.businessDescription }}\n**Their Challenge:** {{ $json.currentProblem }}\n**Desired Outcome:** {{ $json.desiredSolution }}\n**Current Tools:** {{ $json.platformsToUse }}\n**Project Complexity:** {{ $json.projectComplexity }}\n**Budget:** ${{ $json.estimatedValue }}\n**Additional Context:** {{ $json.additionalNotes }}\n\nWrite a comprehensive, persuasive proposal. Return ONLY valid JSON (no markdown backticks):\n{\n  \"title\": \"Proposal: [specific solution name that addresses their challenge]\",\n  \"challengeSummary\": \"Detailed 2-3 sentence summary demonstrating you understand their pain points\",\n  \"solutionType\": \"Solution name (e.g., End-to-End Sales Automation Platform)\",\n  \"scopeDescription\": \"Detailed 3-4 sentence scope of work explaining exactly what you'll deliver\",\n  \"impactBullet1\": \"Specific benefit with metric (e.g., Reduce lead response time from 24 hours to under 5 minutes)\",\n  \"impactBullet2\": \"Second key benefit with specific metric\",\n  \"impactBullet3\": \"Third key benefit with specific metric\",\n  \"outcomeProcess1\": \"Concrete deliverable 1 (e.g., Automated lead capture and CRM sync)\",\n  \"outcomeProcess2\": \"Concrete deliverable 2\",\n  \"outcomeProcess3\": \"Concrete deliverable 3\",\n  \"timeSavings\": \"X hours/week\",\n  \"costSavings\": \"$X/month\"\n}"
            }
          ]
        },
        "jsonOutput": true
      },
      "typeVersion": 1.6
    },
    {
      "id": "dce6e920-f7e8-4e3b-9771-20df29e58ccb",
      "name": "\ud83d\udccb Parse AI Proposal Response",
      "type": "n8n-nodes-base.code",
      "position": [
        1744,
        128
      ],
      "parameters": {
        "jsCode": "// Parse GPT response and merge with extracted data\nconst raw = $input.first().json;\nconst extractedData = $('\ud83d\udd04 Extract & Transform Data').first().json;\n\nlet content = raw.message?.content ?? raw.content ?? raw;\n\ntry {\n  if (typeof content === 'string') {\n    // Remove markdown code blocks if present\n    content = content.replace(/```json\\s*/g, '').replace(/```\\s*/g, '').trim();\n    content = JSON.parse(content);\n  }\n  \n  // Merge GPT response with extracted form data\n  return [{ \n    json: { \n      ...extractedData,\n      ...content, \n      proposalParseOk: true \n    } \n  }];\n} catch (e) {\n  return [{ \n    json: { \n      ...extractedData,\n      proposalParseOk: false, \n      proposalParseError: e.message \n    } \n  }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "c02eb059-c2a6-4c32-b6c8-717d14b92fa1",
      "name": "\ud83e\udd16 AI: Generate Project Milestones",
      "type": "@n8n/n8n-nodes-langchain.openAi",
      "position": [
        1936,
        0
      ],
      "parameters": {
        "modelId": {
          "__rl": true,
          "mode": "list",
          "value": ""
        },
        "options": {
          "temperature": 0.5
        },
        "messages": {
          "values": [
            {
              "role": "system",
              "content": "You are a project manager who creates realistic, client-friendly project timelines for automation projects."
            },
            {
              "content": "=Generate a 4-phase project timeline for this automation project:\n\n**Solution Being Built:** {{ $json.solutionType }}\n**Scope of Work:** {{ $json.scopeDescription }}\n**Project Complexity:** {{ $('\ud83d\udd04 Extract & Transform Data').first().json.projectComplexity }}\n\nCreate realistic milestones that set proper client expectations. Return ONLY valid JSON (no markdown backticks):\n{\n  \"milestone1\": \"Phase 1: [Discovery & Planning - specific activities]\",\n  \"timeline1\": \"Week 1\",\n  \"milestone2\": \"Phase 2: [Build & Configure - specific deliverables]\",\n  \"timeline2\": \"Week 2\",\n  \"milestone3\": \"Phase 3: [Testing & Refinement - specific activities]\",\n  \"timeline3\": \"Week 3\",\n  \"milestone4\": \"Phase 4: [Launch & Handoff - specific deliverables]\",\n  \"timeline4\": \"Week 4\"\n}"
            }
          ]
        },
        "jsonOutput": true
      },
      "typeVersion": 1.6
    },
    {
      "id": "711ec080-9ae2-442b-b984-2e238481db7e",
      "name": "\ud83d\udccb Parse Milestone Response",
      "type": "n8n-nodes-base.code",
      "position": [
        2272,
        0
      ],
      "parameters": {
        "jsCode": "// Parse milestones with fallback defaults\nconst raw = $input.first().json;\nlet content = raw.message?.content ?? raw.content ?? raw;\n\ntry {\n  if (typeof content === 'string') {\n    content = content.replace(/```json\\s*/g, '').replace(/```\\s*/g, '').trim();\n    content = JSON.parse(content);\n  }\n  return [{ json: { ...content, milestonesParseOk: true } }];\n} catch (e) {\n  // Return default milestones on parse error\n  return [{ json: {\n    milestone1: 'Phase 1: Discovery - Requirements gathering and solution design',\n    timeline1: 'Week 1',\n    milestone2: 'Phase 2: Build - Configure and develop core automation workflows',\n    timeline2: 'Week 2',\n    milestone3: 'Phase 3: Test - Quality assurance and refinements',\n    timeline3: 'Week 3',\n    milestone4: 'Phase 4: Launch - Training, documentation, and go-live support',\n    timeline4: 'Week 4',\n    milestonesParseOk: false,\n    milestonesParseError: e.message\n  } }];\n}"
      },
      "typeVersion": 2
    },
    {
      "id": "e3841932-fe5b-422f-9cb5-c99f96aa1d9d",
      "name": "\ud83d\udd17 Combine Proposal + Milestones",
      "type": "n8n-nodes-base.merge",
      "position": [
        1968,
        240
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3
    },
    {
      "id": "dc40c4b6-3362-4708-9285-0ca50b4f8f31",
      "name": "\u2705 Check: AI Parse Successful?",
      "type": "n8n-nodes-base.if",
      "position": [
        2688,
        240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "check-parse",
              "operator": {
                "type": "boolean",
                "operation": "equals"
              },
              "leftValue": "={{ $json.proposalParseOk }}",
              "rightValue": true
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "d5ab459d-2d7a-4ae0-9086-607c58690cd3",
      "name": "\ud83d\udcc4 Create PandaDoc Document",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2912,
        224
      ],
      "parameters": {
        "url": "https://api.pandadoc.com/public/v1/documents",
        "method": "POST",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "jsonBody": "={\n  \"name\": \"{{ $json.title }} - {{ $json.companyName }}\",\n  \"template_uuid\": \"{{ $json.pandaDocTemplateId }}\",\n  \"recipients\": [\n    {\n      \"email\": \"{{ $json.clientEmail }}\",\n      \"first_name\": \"{{ $json.clientFirstName }}\",\n      \"last_name\": \"{{ $json.clientLastName }}\",\n      \"role\": \"Client\"\n    }\n  ],\n  \"tokens\": [\n    { \"name\": \"Client.Company\", \"value\": \"{{ $json.companyName }}\" },\n    { \"name\": \"Client.FirstName\", \"value\": \"{{ $json.clientFirstName }}\" },\n    { \"name\": \"Client.LastName\", \"value\": \"{{ $json.clientLastName }}\" },\n    { \"name\": \"Client.ChallengeSummary\", \"value\": \"{{ $json.challengeSummary }}\" },\n    { \"name\": \"Project.Total\", \"value\": \"{{ $json.estimatedValue }}\" },\n    { \"name\": \"Project.Deposit\", \"value\": \"{{ $json.depositAmount }}\" },\n    { \"name\": \"Project.TimeSavings\", \"value\": \"{{ $json.timeSavings }}\" },\n    { \"name\": \"Project.CostSavings\", \"value\": \"{{ $json.costSavings }}\" },\n    { \"name\": \"Timeline.Phase1\", \"value\": \"{{ $json.milestone1 }}\" },\n    { \"name\": \"Timeline.Phase1Date\", \"value\": \"{{ $json.timeline1 }}\" },\n    { \"name\": \"Timeline.Phase2\", \"value\": \"{{ $json.milestone2 }}\" },\n    { \"name\": \"Timeline.Phase2Date\", \"value\": \"{{ $json.timeline2 }}\" },\n    { \"name\": \"Timeline.Phase3\", \"value\": \"{{ $json.milestone3 }}\" },\n    { \"name\": \"Timeline.Phase3Date\", \"value\": \"{{ $json.timeline3 }}\" },\n    { \"name\": \"Timeline.Phase4\", \"value\": \"{{ $json.milestone4 }}\" },\n    { \"name\": \"Timeline.Phase4Date\", \"value\": \"{{ $json.timeline4 }}\" },\n    { \"name\": \"Impact.Bullet1\", \"value\": \"{{ $json.impactBullet1 }}\" },\n    { \"name\": \"Impact.Bullet2\", \"value\": \"{{ $json.impactBullet2 }}\" },\n    { \"name\": \"Impact.Bullet3\", \"value\": \"{{ $json.impactBullet3 }}\" },\n    { \"name\": \"Proposal.ExpiryDate\", \"value\": \"{{ $json.proposalExpiryDate }}\" },\n    { \"name\": \"Document.Date\", \"value\": \"{{ $json.documentDate }}\" }\n  ],\n  \"pricing_tables\": [\n    {\n      \"name\": \"Pricing Table 1\",\n      \"sections\": [\n        {\n          \"title\": \"Project Investment\",\n          \"default\": true,\n          \"rows\": [\n            {\n              \"options\": { \"qty_editable\": false, \"optional\": false },\n              \"data\": {\n                \"name\": \"{{ $json.solutionType }}\",\n                \"description\": \"{{ $json.scopeDescription }}\",\n                \"price\": {{ $json.estimatedValue }},\n                \"qty\": 1\n              }\n            }\n          ]\n        }\n      ],\n      \"options\": {\n        \"currency\": \"USD\",\n        \"discount\": { \"type\": \"absolute\", \"name\": \"Discount\", \"value\": 0 }\n      }\n    }\n  ]\n}",
        "sendBody": true,
        "sendHeaders": true,
        "specifyBody": "json",
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth",
        "headerParameters": {
          "parameters": [
            {
              "name": "Content-Type",
              "value": "application/json"
            }
          ]
        }
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "2e9b50b3-85e0-4589-a4ea-06215dfe89c6",
      "name": "\u2705 Check: Document Created?",
      "type": "n8n-nodes-base.if",
      "position": [
        3104,
        224
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "check-id",
              "operator": {
                "type": "string",
                "operation": "notEmpty"
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "26eba8d4-81e9-4994-916f-545d9301d232",
      "name": "\ud83d\udcac Notify: Proposal Ready",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3424,
        96
      ],
      "parameters": {
        "url": "={{ $('\u2699\ufe0f Config').first().json.slackWebhookUrl }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({\n  \"text\": \"\u2705 Proposal Created!\",\n  \"blocks\": [\n    {\n      \"type\": \"header\",\n      \"text\": { \"type\": \"plain_text\", \"text\": \"\u2705 New Proposal Generated\", \"emoji\": true }\n    },\n    {\n      \"type\": \"section\",\n      \"fields\": [\n        { \"type\": \"mrkdwn\", \"text\": \"*Client:*\\n\" + $('\ud83d\udd04 Extract & Transform Data').first().json.companyName },\n        { \"type\": \"mrkdwn\", \"text\": \"*Value:*\\n$\" + $('\ud83d\udd04 Extract & Transform Data').first().json.estimatedValue },\n        { \"type\": \"mrkdwn\", \"text\": \"*Template:*\\n\" + ($('\ud83d\udd04 Extract & Transform Data').first().json.selectedTemplate === 'quick_quote' ? '\ud83d\udccb Quick Quote' : '\ud83d\udcc4 Standard Proposal') },\n        { \"type\": \"mrkdwn\", \"text\": \"*Expires:*\\n\" + $('\ud83d\udd04 Extract & Transform Data').first().json.proposalExpiryDate }\n      ]\n    },\n    {\n      \"type\": \"actions\",\n      \"elements\": [\n        {\n          \"type\": \"button\",\n          \"text\": { \"type\": \"plain_text\", \"text\": \"\ud83d\udcc4 View in PandaDoc\", \"emoji\": true },\n          \"url\": \"https://app.pandadoc.com/a/#/documents/\" + $json.id\n        }\n      ]\n    }\n  ]\n}) }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "04b2ac5e-9ad6-46f4-8d03-e03b1808a329",
      "name": "\ud83d\udea8 Notify: PandaDoc Failed",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        3424,
        288
      ],
      "parameters": {
        "url": "={{ $('\u2699\ufe0f Config').first().json.slackWebhookUrl }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({\n  \"text\": \"\u274c PandaDoc Error\",\n  \"blocks\": [\n    {\n      \"type\": \"header\",\n      \"text\": { \"type\": \"plain_text\", \"text\": \"\u274c PandaDoc Creation Failed\", \"emoji\": true }\n    },\n    {\n      \"type\": \"section\",\n      \"fields\": [\n        { \"type\": \"mrkdwn\", \"text\": \"*Client:*\\n\" + $('\ud83d\udd04 Extract & Transform Data').first().json.companyName },\n        { \"type\": \"mrkdwn\", \"text\": \"*Email:*\\n\" + $('\ud83d\udd04 Extract & Transform Data').first().json.clientEmail },\n        { \"type\": \"mrkdwn\", \"text\": \"*Template:*\\n\" + $('\ud83d\udd04 Extract & Transform Data').first().json.selectedTemplate }\n      ]\n    },\n    {\n      \"type\": \"section\",\n      \"text\": { \"type\": \"mrkdwn\", \"text\": \"*Error:* \" + ($json.message || $json.error || 'Unknown error - check PandaDoc API credentials and template IDs') }\n    }\n  ]\n}) }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "1f79534f-5d09-4b86-bcdc-0dedb03b77c8",
      "name": "\ud83d\udea8 Notify: GPT Parse Failed",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1040,
        768
      ],
      "parameters": {
        "url": "={{ $('\u2699\ufe0f Config').first().json.slackWebhookUrl }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({\n  \"text\": \"\u26a0\ufe0f GPT Parse Error\",\n  \"blocks\": [\n    {\n      \"type\": \"header\",\n      \"text\": { \"type\": \"plain_text\", \"text\": \"\u26a0\ufe0f AI Response Parse Failed\", \"emoji\": true }\n    },\n    {\n      \"type\": \"section\",\n      \"fields\": [\n        { \"type\": \"mrkdwn\", \"text\": \"*Client:*\\n\" + $json.companyName },\n        { \"type\": \"mrkdwn\", \"text\": \"*Email:*\\n\" + $json.clientEmail },\n        { \"type\": \"mrkdwn\", \"text\": \"*Template:*\\n\" + $json.selectedTemplate }\n      ]\n    },\n    {\n      \"type\": \"section\",\n      \"text\": { \"type\": \"mrkdwn\", \"text\": \"*Error:* \" + ($json.proposalParseError || 'GPT returned invalid JSON - you may need to manually create this proposal') }\n    }\n  ]\n}) }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "67f4d00b-f241-4b14-975c-d02ed6eb1ecb",
      "name": "\ud83d\udea8 Notify: Missing Required Fields",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1312,
        768
      ],
      "parameters": {
        "url": "={{ $('\u2699\ufe0f Config').first().json.slackWebhookUrl }}",
        "method": "POST",
        "options": {},
        "jsonBody": "={{ JSON.stringify({\n  \"text\": \"\u26a0\ufe0f Validation Failed\",\n  \"blocks\": [\n    {\n      \"type\": \"header\",\n      \"text\": { \"type\": \"plain_text\", \"text\": \"\u26a0\ufe0f Form Missing Required Fields\", \"emoji\": true }\n    },\n    {\n      \"type\": \"section\",\n      \"text\": { \"type\": \"mrkdwn\", \"text\": \"A Typeform submission was received but is missing required fields:\\n\\n*Email:* \" + ($json.clientEmail || '\u274c Missing') + \"\\n*Company:* \" + ($json.companyName || '\u274c Missing') + \"\\n\\n_This prospect may need manual follow-up if you have other contact info._\" }\n    }\n  ]\n}) }}",
        "sendBody": true,
        "specifyBody": "json"
      },
      "typeVersion": 4.2,
      "continueOnFail": true
    },
    {
      "id": "1d379c06-c99a-4313-a863-57917963c66a",
      "name": "Sticky Note Error",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        400,
        624
      ],
      "parameters": {
        "color": 6,
        "width": 1156,
        "height": 360,
        "content": "## \u26a0\ufe0f Error Handling\n\nCaptures issues at every stage:\n\n**Notify: GPT Parse Failed** \u2192 AI response wasn't valid JSON\n\n**Notify: Missing Required Fields** \u2192 Form submitted without email or company name\n\nBoth errors include client details so you can manually reach out"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "a9ce8e74-18da-448b-ac01-7e4f52a52b6b",
  "connections": {
    "\ud83d\udce5 Typeform Trigger": {
      "main": [
        [
          {
            "node": "\ud83d\udd04 Extract & Transform Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2705 Check Required Fields": {
      "main": [
        [
          {
            "node": "\ud83d\udd00 Route: Quick Quote or Standard?",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\udea8 Notify: Missing Required Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2705 Check: Document Created?": {
      "main": [
        [
          {
            "node": "\ud83d\udcac Notify: Proposal Ready",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\udea8 Notify: PandaDoc Failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udcc4 Create PandaDoc Document": {
      "main": [
        [
          {
            "node": "\u2705 Check: Document Created?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udccb Parse Milestone Response": {
      "main": [
        [
          {
            "node": "\ud83d\udd17 Combine Proposal + Milestones",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd04 Extract & Transform Data": {
      "main": [
        [
          {
            "node": "\u2705 Check Required Fields",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udd16 AI: Generate Quick Quote": {
      "main": [
        [
          {
            "node": "\ud83d\udccb Parse AI Proposal Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\u2705 Check: AI Parse Successful?": {
      "main": [
        [
          {
            "node": "\ud83d\udcc4 Create PandaDoc Document",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83d\udea8 Notify: GPT Parse Failed",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udccb Parse AI Proposal Response": {
      "main": [
        [
          {
            "node": "\ud83e\udd16 AI: Generate Project Milestones",
            "type": "main",
            "index": 0
          },
          {
            "node": "\ud83d\udd17 Combine Proposal + Milestones",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "\ud83d\udd17 Combine Proposal + Milestones": {
      "main": [
        [
          {
            "node": "\u2705 Check: AI Parse Successful?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udd16 AI: Generate Standard Proposal": {
      "main": [
        [
          {
            "node": "\ud83d\udccb Parse AI Proposal Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83d\udd00 Route: Quick Quote or Standard?": {
      "main": [
        [
          {
            "node": "\ud83e\udd16 AI: Generate Quick Quote",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "\ud83e\udd16 AI: Generate Standard Proposal",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "\ud83e\udd16 AI: Generate Project Milestones": {
      "main": [
        [
          {
            "node": "\ud83d\udccb Parse Milestone Response",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Turn discovery call forms into polished, personalized proposals in seconds. This workflow captures prospect information via Typeform, uses GPT-4 to write compelling proposal content, and automatically creates professional PandaDoc documents with pricing tables.

Source: https://n8n.io/workflows/12032/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

Stop spending hours formatting proposals. This workflow turns a short post-call form into a high-converting, fully-personalized PandaDoc proposal—plus updates your CRM and drafts the follow-up email f

OpenAI, HTTP Request, ClickUp +2
AI & RAG

Impress your leads with ultra-personalized “thank you” emails that look hand-written — sent automatically seconds after they submit your intake form.

Gmail, Typeform Trigger, HTTP Request +1
AI & RAG

Ask questions like “How much did I spend on food last month?” and get instant answers from your financial data — directly in Telegram.

Telegram Trigger, OpenAI, Google Sheets +2
AI & RAG

The Problem That it Solves

Google Drive Trigger, OpenAI, Google Drive +5
AI & RAG

This intelligent email automation workflow helps you maximize engagement through domain-based outreach. It utilizes AI-powered personalization and strategic follow-ups to increase response rates. The

Gmail, HTTP Request, Google Sheets +1