AutomationFlowsAI & RAG › Analyze Contract Pdfs and Score Risk with Claude 3.5, Postgres, Email and…

Analyze Contract Pdfs and Score Risk with Claude 3.5, Postgres, Email and…

Original n8n title: Analyze Contract Pdfs and Score Risk with Claude 3.5, Postgres, Email and Slack Alerts

ByResilNext @rnair1996 on n8n.io

This workflow automates end-to-end contract analysis using AI. It extracts clauses, evaluates risks, tracks obligations, and generates an executive summary from uploaded contracts.

Webhook trigger★★★★★ complexityAI-powered36 nodesAgentAnthropic ChatOutput Parser StructuredPostgresGmailSlack
AI & RAG Trigger: Webhook Nodes: 36 Complexity: ★★★★★ AI nodes: yes Added:

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

This workflow follows the Agent → Gmail 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
{
  "nodes": [
    {
      "id": "1bedb5f1-de65-490d-bea0-2f926f50a7c8",
      "name": "Contract Upload Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -912,
        656
      ],
      "parameters": {
        "path": "contract-upload",
        "options": {},
        "httpMethod": "POST",
        "responseMode": "responseNode"
      },
      "typeVersion": 2.1
    },
    {
      "id": "804bbbc4-2fa3-4e9c-9032-d20f321813d1",
      "name": "Workflow Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -672,
        656
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "riskThreshold",
              "type": "number",
              "value": 0.7
            },
            {
              "id": "id-2",
              "name": "alertRecipients",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Email addresses for high-risk alerts__>"
            },
            {
              "id": "id-3",
              "name": "slackChannel",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__Slack channel ID for alerts__>"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "3fd1b6cb-e8c7-498d-9ea3-970a1b6a588f",
      "name": "Extract PDF Text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        -336,
        656
      ],
      "parameters": {
        "options": {},
        "operation": "pdf"
      },
      "typeVersion": 1.1
    },
    {
      "id": "4970b244-9446-47d0-9173-b6f80cb09440",
      "name": "Clause Extraction Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        96,
        -32
      ],
      "parameters": {
        "text": "={{ $json.text }}",
        "options": {
          "systemMessage": "You are a legal contract analysis expert specializing in clause extraction.\n\nYour task is to:\n1. Identify and extract ALL contract clauses from the provided text\n2. Categorize each clause by type: payment_terms, termination, liability, ip, confidentiality, warranty, or indemnification\n3. Extract the exact clause text\n4. Provide your confidence level (0-1) for each extraction\n\nReturn a structured array of clauses with: clause_type, clause_text, and ai_confidence fields."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "b2b72df7-5866-46ac-a720-bb1094b7a7b0",
      "name": "Risk Assessment Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        80,
        512
      ],
      "parameters": {
        "text": "={{ $json.text }}",
        "options": {
          "systemMessage": "You are a legal risk assessment expert specializing in contract analysis.\n\nYour task is to:\n1. Analyze each clause for potential risks\n2. Assign risk levels: critical, high, medium, low, or none\n3. Identify specific risk factors:\n   - Payment terms: Late penalties, disputed amounts, unfavorable terms\n   - Liability: Unlimited liability, indemnification scope\n   - Termination: Lock-in periods, exit difficulty\n   - IP: Ownership ambiguity, broad assignments\n   - Confidentiality: Overly broad NDAs, unreasonable duration\n4. Provide risk descriptions and recommendations\n5. Calculate confidence level (0-1) for each assessment\n\nReturn structured risk analysis with: clause_type, risk_level, risk_description, recommendation, and ai_confidence."
        },
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "482d49a0-ddfc-4013-9a6a-57b0c342abe2",
      "name": "Obligation Extraction Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        64,
        944
      ],
      "parameters": {
        "text": "={{ $json.text }}",
        "options": {
          "systemMessage": "You are a legal obligation tracking expert.\n\nYour task is to:\n1. Extract ALL obligations from the contract text\n2. Look for keywords: \"must\", \"shall\", \"required\", \"obligated\", \"agrees to\"\n3. Categorize each obligation: payment, delivery, reporting, or compliance\n4. Extract due dates, deadlines, or timeframes\n5. Identify the responsible party (if specified)\n6. Set initial status as \"pending\"\n\nReturn structured obligations with: obligation_text, obligation_type, due_date (ISO format or null), responsible_party, and status fields."
        },
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "9d693aa1-48a3-415f-ba71-99cb2462c9bf",
      "name": "Executive Summary Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        32,
        1344
      ],
      "parameters": {
        "text": "={{ $json.text }}",
        "options": {
          "systemMessage": "You are a legal contract summarization expert.\n\nYour task is to:\n1. Generate a concise executive summary of the contract\n2. Highlight key terms and conditions\n3. Identify the contract parties\n4. Note contract value, dates (execution, expiry)\n5. Summarize major obligations and rights\n6. Flag any unusual or noteworthy provisions\n7. Provide an overall assessment\n\nReturn a structured summary with: contract_name, parties, contract_type, key_terms, major_obligations, notable_provisions, and overall_assessment fields."
        },
        "hasOutputParser": true
      },
      "typeVersion": 3
    },
    {
      "id": "83060009-2191-4d6e-976f-23d16dca9932",
      "name": "Claude 3.5 Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatAnthropic",
      "position": [
        928,
        1408
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "claude-3-5-sonnet-20241022"
        },
        "options": {}
      },
      "typeVersion": 1.3
    },
    {
      "id": "2631b1e3-9e6d-4c7a-b299-9e3132d6cbdb",
      "name": "Clause Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        288,
        160
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"clauses\": [\n    {\n      \"clause_type\": \"payment_terms\",\n      \"clause_text\": \"Payment due within 30 days\",\n      \"ai_confidence\": 0.95\n    }\n  ]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "e89e8d7a-5df6-4544-9b8f-f3b40345c047",
      "name": "Risk Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        320,
        656
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"risks\": [\n    {\n      \"clause_type\": \"payment_terms\",\n      \"risk_level\": \"high\",\n      \"risk_description\": \"60-day payment terms exceed industry standard\",\n      \"recommendation\": \"Negotiate to 30-day terms\",\n      \"ai_confidence\": 0.92\n    }\n  ]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "7ed92ab4-629c-4618-b4ef-22ada1aa711b",
      "name": "Obligation Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        160,
        1104
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"obligations\": [\n    {\n      \"obligation_text\": \"Vendor shall deliver within 30 days\",\n      \"obligation_type\": \"delivery\",\n      \"due_date\": \"2024-12-31\",\n      \"responsible_party\": \"Vendor\",\n      \"status\": \"pending\"\n    }\n  ]\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "a65fa73b-6b31-4c91-bf4f-57a224cd0f3c",
      "name": "Summary Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        240,
        1552
      ],
      "parameters": {
        "jsonSchemaExample": "{\n  \"contract_name\": \"Vendor Services Agreement\",\n  \"parties\": [\"Company A\", \"Vendor B\"],\n  \"contract_type\": \"vendor\",\n  \"execution_date\": \"2024-01-01\",\n  \"expiry_date\": \"2025-01-01\",\n  \"value\": 50000.00,\n  \"key_terms\": \"Monthly service delivery with 30-day payment terms\",\n  \"major_obligations\": \"Vendor provides services, Company pays monthly\",\n  \"notable_provisions\": \"Auto-renewal clause with 60-day notice\",\n  \"overall_assessment\": \"Standard vendor agreement with favorable terms\"\n}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "bbafa2e7-13e2-44c2-b97e-7cbe7d32bae9",
      "name": "Calculate Risk Score",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        656
      ],
      "parameters": {
        "jsCode": "// Extract data from merged inputs\nconst clauseData = $input.first().json.clauses || [];\nconst riskData = $input.item(1).json.risks || [];\nconst obligationData = $input.item(2).json.obligations || [];\nconst summaryData = $input.item(3).json;\n\n// Risk weights by category\nconst riskWeights = {\n  payment_terms: 0.25,\n  liability: 0.30,\n  termination: 0.15,\n  ip: 0.15,\n  confidentiality: 0.10,\n  warranty: 0.03,\n  indemnification: 0.02\n};\n\n// Risk level scores\nconst riskScores = {\n  critical: 1.0,\n  high: 0.75,\n  medium: 0.5,\n  low: 0.25,\n  none: 0.0\n};\n\n// Calculate weighted risk score\nlet scoreBreakdown = {};\nlet totalWeightedScore = 0;\nlet redFlags = [];\nlet recommendations = [];\n\nriskData.forEach(risk => {\n  const weight = riskWeights[risk.clause_type] || 0.01;\n  const score = riskScores[risk.risk_level] || 0;\n  const weightedScore = score * weight;\n  \n  scoreBreakdown[risk.clause_type + '_risk'] = score;\n  totalWeightedScore += weightedScore;\n  \n  if (risk.risk_level === 'critical' || risk.risk_level === 'high') {\n    redFlags.push(risk.risk_description);\n    recommendations.push(risk.recommendation);\n  }\n});\n\n// Check for missing critical clauses\nconst criticalClauses = ['payment_terms', 'liability', 'termination'];\nconst foundClauses = clauseData.map(c => c.clause_type);\ncriticalClauses.forEach(critical => {\n  if (!foundClauses.includes(critical)) {\n    redFlags.push(`Missing critical clause: ${critical}`);\n    recommendations.push(`Add ${critical} clause to contract`);\n  }\n});\n\n// Check AI confidence levels\nconst lowConfidenceItems = [...clauseData, ...riskData].filter(item => item.ai_confidence < 0.6);\nif (lowConfidenceItems.length > 0) {\n  redFlags.push(`${lowConfidenceItems.length} items flagged for manual legal review (low AI confidence)`);\n  recommendations.push('Schedule legal review for low-confidence extractions');\n}\n\nreturn {\n  clauses: clauseData,\n  risks: riskData,\n  obligations: obligationData,\n  summary: summaryData,\n  overall_risk_score: Math.round(totalWeightedScore * 100) / 100,\n  score_breakdown: scoreBreakdown,\n  red_flags: redFlags,\n  recommendations: recommendations,\n  calculated_at: new Date().toISOString()\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "1fece3f3-7743-4da3-91c8-280d795a9938",
      "name": "Merge Analysis Results",
      "type": "n8n-nodes-base.merge",
      "position": [
        560,
        624
      ],
      "parameters": {
        "numberInputs": 4
      },
      "typeVersion": 3.2
    },
    {
      "id": "69956926-17f3-425e-be8b-aaeecd551d19",
      "name": "Prepare Contract Data",
      "type": "n8n-nodes-base.set",
      "position": [
        992,
        656
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "id-1",
              "name": "contract_id",
              "type": "string",
              "value": "={{ $now.toISO() }}-{{ $json.summary.contract_name.replace(/\\s+/g, \"-\").toLowerCase() }}"
            },
            {
              "id": "id-2",
              "name": "contract_name",
              "type": "string",
              "value": "={{ $json.summary.contract_name }}"
            },
            {
              "id": "id-3",
              "name": "contract_type",
              "type": "string",
              "value": "={{ $json.summary.contract_type }}"
            },
            {
              "id": "id-4",
              "name": "execution_date",
              "type": "string",
              "value": "={{ $json.summary.execution_date }}"
            },
            {
              "id": "id-5",
              "name": "expiry_date",
              "type": "string",
              "value": "={{ $json.summary.expiry_date }}"
            },
            {
              "id": "id-6",
              "name": "value",
              "type": "string",
              "value": "={{ $json.summary.value }}"
            },
            {
              "id": "id-7",
              "name": "status",
              "type": "string",
              "value": "draft"
            },
            {
              "id": "id-8",
              "name": "uploaded_by",
              "type": "string",
              "value": "<__PLACEHOLDER_VALUE__User ID or email__>"
            },
            {
              "id": "id-9",
              "name": "upload_date",
              "type": "string",
              "value": "={{ $now.toISO() }}"
            },
            {
              "id": "id-10",
              "name": "document_hash",
              "type": "number",
              "value": "={{ $json.summary.contract_name.length }}"
            },
            {
              "id": "id-11",
              "name": "clauses",
              "type": "string",
              "value": "={{ $json.clauses }}"
            },
            {
              "id": "id-12",
              "name": "risks",
              "type": "string",
              "value": "={{ $json.risks }}"
            },
            {
              "id": "id-13",
              "name": "obligations",
              "type": "string",
              "value": "={{ $json.obligations }}"
            },
            {
              "id": "id-14",
              "name": "overall_risk_score",
              "type": "number",
              "value": "={{ $json.overall_risk_score }}"
            },
            {
              "id": "id-15",
              "name": "score_breakdown",
              "type": "string",
              "value": "={{ $json.score_breakdown }}"
            },
            {
              "id": "id-16",
              "name": "red_flags",
              "type": "string",
              "value": "={{ $json.red_flags }}"
            },
            {
              "id": "id-17",
              "name": "recommendations",
              "type": "string",
              "value": "={{ $json.recommendations }}"
            },
            {
              "id": "id-18",
              "name": "calculated_at",
              "type": "string",
              "value": "={{ $json.calculated_at }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "61c5b5fc-568e-4479-91d0-9ea506b153db",
      "name": "Insert Contract",
      "type": "n8n-nodes-base.postgres",
      "position": [
        1232,
        656
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "name",
          "value": "contracts"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "id": "={{ $json.contract_id }}",
            "value": "={{ $json.value }}",
            "status": "={{ $json.status }}",
            "created_at": "={{ $now.toISO() }}",
            "expiry_date": "={{ $json.expiry_date }}",
            "upload_date": "={{ $json.upload_date }}",
            "uploaded_by": "={{ $json.uploaded_by }}",
            "contract_name": "={{ $json.contract_name }}",
            "contract_type": "={{ $json.contract_type }}",
            "document_hash": "={{ $json.document_hash }}",
            "execution_date": "={{ $json.execution_date }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {}
      },
      "typeVersion": 2.6
    },
    {
      "id": "671ebaaf-a69b-4e6e-8039-91425bbf9f79",
      "name": "Insert Clauses",
      "type": "n8n-nodes-base.postgres",
      "position": [
        1456,
        656
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "name",
          "value": "contract_clauses"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "clause_text": "={{ $json.clause_text }}",
            "clause_type": "={{ $json.clause_type }}",
            "contract_id": "={{ $json.contract_id }}",
            "ai_confidence": "={{ $json.ai_confidence }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {
          "queryBatching": "single"
        }
      },
      "typeVersion": 2.6
    },
    {
      "id": "b8c5ba5f-f1b3-4d84-a168-8df19e38464b",
      "name": "Insert Obligations",
      "type": "n8n-nodes-base.postgres",
      "position": [
        1680,
        656
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "name",
          "value": "contract_obligations"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "status": "={{ $json.status }}",
            "due_date": "={{ $json.due_date }}",
            "contract_id": "={{ $json.contract_id }}",
            "obligation_text": "={{ $json.obligation_text }}",
            "obligation_type": "={{ $json.obligation_type }}",
            "responsible_party": "={{ $json.responsible_party }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {}
      },
      "typeVersion": 2.6
    },
    {
      "id": "ef451585-d769-4629-a053-9a8c44f52cb9",
      "name": "Insert Risk Scoring",
      "type": "n8n-nodes-base.postgres",
      "position": [
        1904,
        656
      ],
      "parameters": {
        "table": {
          "__rl": true,
          "mode": "name",
          "value": "risk_scoring"
        },
        "schema": {
          "__rl": true,
          "mode": "list",
          "value": "public"
        },
        "columns": {
          "value": {
            "red_flags": "={{ $json.red_flags }}",
            "contract_id": "={{ $json.contract_id }}",
            "calculated_at": "={{ $json.calculated_at }}",
            "recommendations": "={{ $json.recommendations }}",
            "score_breakdown": "={{ $json.score_breakdown }}",
            "overall_risk_score": "={{ $json.overall_risk_score }}"
          },
          "mappingMode": "defineBelow"
        },
        "options": {}
      },
      "typeVersion": 2.6
    },
    {
      "id": "83bd70fa-c70b-4a57-b657-fafecc7b32fd",
      "name": "Check Risk Level",
      "type": "n8n-nodes-base.if",
      "position": [
        2208,
        656
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "id-1",
              "operator": {
                "type": "number",
                "operation": "gte"
              },
              "leftValue": "={{ $json.overall_risk_score }}",
              "rightValue": "={{ $('Workflow Configuration').first().json.riskThreshold }}"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "f0ee12f3-5a87-4d9b-ba36-5af6fef4ab3c",
      "name": "Send Email Alert",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2656,
        336
      ],
      "parameters": {
        "sendTo": "={{ $('Workflow Configuration').first().json.alertRecipients }}",
        "message": "=<h2>High Risk Contract Detected</h2><p><strong>Contract:</strong> {{ $json.contract_name }}</p><p><strong>Risk Score:</strong> {{ $json.overall_risk_score }} (Threshold: {{ $('Workflow Configuration').first().json.riskThreshold }})</p><h3>Red Flags:</h3><ul>{{ $json.red_flags.map(flag => \"<li>\" + flag + \"</li>\").join(\"\") }}</ul><h3>Recommendations:</h3><ul>{{ $json.recommendations.map(rec => \"<li>\" + rec + \"</li>\").join(\"\") }}</ul><p>Please review this contract immediately.</p>",
        "options": {},
        "subject": "=HIGH RISK CONTRACT ALERT: {{ $json.contract_name }}"
      },
      "typeVersion": 2.2
    },
    {
      "id": "0bc821ff-528f-4087-9d51-09bb5a203c67",
      "name": "Send Slack Alert",
      "type": "n8n-nodes-base.slack",
      "position": [
        2672,
        752
      ],
      "parameters": {
        "text": "=:warning: *HIGH RISK CONTRACT ALERT*\n\n*Contract:* {{ $json.contract_name }}\n*Risk Score:* {{ $json.overall_risk_score }} (Threshold: {{ $('Workflow Configuration').first().json.riskThreshold }})\n\n*Red Flags:*\n{{ $json.red_flags.map((flag, i) => (i+1) + \". \" + flag).join(\"\\n\") }}\n\n*Recommendations:*\n{{ $json.recommendations.map((rec, i) => (i+1) + \". \" + rec).join(\"\\n\") }}\n\nPlease review immediately.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "id",
          "value": "={{ $('Workflow Configuration').first().json.slackChannel }}"
        },
        "otherOptions": {}
      },
      "typeVersion": 2.4
    },
    {
      "id": "cd7698c8-0219-4ed5-bb88-8d96e815d3e6",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2560,
        240
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 320,
        "content": "## Alert System\nemail for high-risk cases"
      },
      "typeVersion": 1
    },
    {
      "id": "f6a5f945-b9c0-449a-9b86-d577b4c71567",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2592,
        672
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 240,
        "content": "## Alert System\nSend Slack"
      },
      "typeVersion": 1
    },
    {
      "id": "d47fd412-07ce-48aa-ba54-e498a8b3a50e",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2144,
        528
      ],
      "parameters": {
        "color": 7,
        "width": 294,
        "height": 384,
        "content": "## Risk Evaluation\nCompare score with risk threshold"
      },
      "typeVersion": 1
    },
    {
      "id": "11f44590-eba8-4feb-ad0e-136aea9bca65",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1168,
        528
      ],
      "parameters": {
        "color": 7,
        "width": 944,
        "height": 368,
        "content": "## Data Storage\nStore contract, clauses, and risk data"
      },
      "typeVersion": 1
    },
    {
      "id": "105ab5e6-fad8-4b81-817e-4485c03e3a77",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        768,
        560
      ],
      "parameters": {
        "color": 7,
        "width": 368,
        "height": 320,
        "content": "## Risk Scoring\nCalculate weighted contract risk score"
      },
      "typeVersion": 1
    },
    {
      "id": "fff17866-f91e-4069-bce8-89314f159acc",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        448,
        544
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 336,
        "content": "## Data Aggregation\nMerge outputs from all AI agents"
      },
      "typeVersion": 1
    },
    {
      "id": "af3ae9e1-e476-434c-9be0-01613708802c",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        -144
      ],
      "parameters": {
        "color": 7,
        "width": 480,
        "height": 416,
        "content": "## Clause Analysis\nIdentify and categorize contract clauses"
      },
      "typeVersion": 1
    },
    {
      "id": "3022b2c1-2b30-4e79-b792-b66696229f07",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        304
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 432,
        "content": "## Risk Analysis\nEvaluate clause risks and recommendations"
      },
      "typeVersion": 1
    },
    {
      "id": "9ba5907c-df59-4474-ad05-4c09ee5ef29e",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -48,
        784
      ],
      "parameters": {
        "color": 7,
        "width": 464,
        "height": 416,
        "content": "## Obligation Tracking\nExtract duties, deadlines, and responsibilities"
      },
      "typeVersion": 1
    },
    {
      "id": "9bdb8efe-bbe8-47e0-8c7d-ab2bc0e7c1e9",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        784,
        1312
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 240,
        "content": "## AI Model\nClaude 3.5 language model configuration"
      },
      "typeVersion": 1
    },
    {
      "id": "1a58481d-e882-40fa-a2e3-4c7045abd01d",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -64,
        1248
      ],
      "parameters": {
        "color": 7,
        "width": 512,
        "height": 416,
        "content": "## Executive Summary\nGenerate structured contract overview"
      },
      "typeVersion": 1
    },
    {
      "id": "4271a106-22ff-4230-9d45-b31099df0c5c",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -448,
        512
      ],
      "parameters": {
        "color": 7,
        "width": 304,
        "height": 384,
        "content": "## Text Extraction\nExtract text from uploaded PDF file"
      },
      "typeVersion": 1
    },
    {
      "id": "1491ce9a-c12a-490f-a245-e291c39f77ca",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -928,
        512
      ],
      "parameters": {
        "color": 7,
        "width": 416,
        "height": 400,
        "content": "## Input Layer\nUpload contract via webhook trigger and \nconfigure risk"
      },
      "typeVersion": 1
    },
    {
      "id": "81ad3f21-ab85-4333-b294-616de122217f",
      "name": "Sticky Note13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2016,
        528
      ],
      "parameters": {
        "width": 592,
        "height": 528,
        "content": "## How it works\nThis workflow analyzes uploaded contracts using AI to extract clauses, assess risks, track obligations, and generate a structured summary.\n\nAfter a contract is uploaded, the PDF text is extracted and processed by multiple AI agents in parallel. These agents identify clauses, evaluate risks, extract obligations, and generate an executive summary.\n\nThe workflow calculates an overall risk score using weighted logic and flags high-risk contracts. All results are stored in a database, including clauses, obligations, and risk insights.\n\nIf the risk score exceeds the defined threshold, alerts are automatically sent via email and Slack for immediate review.\n\n## Setup steps\n- Configure webhook for contract upload\n- Add AI model credentials (Anthropic/OpenAI)\n- Set Postgres database connection\n- Configure Slack and email alerts\n- Adjust risk threshold and alert settings"
      },
      "typeVersion": 1
    }
  ],
  "connections": {
    "Risk Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Risk Assessment Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Clause Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Clause Extraction Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Insert Clauses": {
      "main": [
        [
          {
            "node": "Insert Obligations",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Summary Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Executive Summary Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Insert Contract": {
      "main": [
        [
          {
            "node": "Insert Clauses",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check Risk Level": {
      "main": [
        [
          {
            "node": "Send Email Alert",
            "type": "main",
            "index": 0
          },
          {
            "node": "Send Slack Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Claude 3.5 Model": {
      "ai_languageModel": [
        [
          {
            "node": "Clause Extraction Agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Risk Assessment Agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Obligation Extraction Agent",
            "type": "ai_languageModel",
            "index": 0
          },
          {
            "node": "Executive Summary Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Extract PDF Text": {
      "main": [
        [
          {
            "node": "Clause Extraction Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Risk Assessment Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Obligation Extraction Agent",
            "type": "main",
            "index": 0
          },
          {
            "node": "Executive Summary Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Obligation Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Obligation Extraction Agent",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Insert Obligations": {
      "main": [
        [
          {
            "node": "Insert Risk Scoring",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Insert Risk Scoring": {
      "main": [
        [
          {
            "node": "Check Risk Level",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Calculate Risk Score": {
      "main": [
        [
          {
            "node": "Prepare Contract Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Contract Data": {
      "main": [
        [
          {
            "node": "Insert Contract",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Risk Assessment Agent": {
      "main": [
        [
          {
            "node": "Merge Analysis Results",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Merge Analysis Results": {
      "main": [
        [
          {
            "node": "Calculate Risk Score",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workflow Configuration": {
      "main": [
        [
          {
            "node": "Extract PDF Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clause Extraction Agent": {
      "main": [
        [
          {
            "node": "Merge Analysis Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Contract Upload Webhook": {
      "main": [
        [
          {
            "node": "Workflow Configuration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Executive Summary Agent": {
      "main": [
        [
          {
            "node": "Merge Analysis Results",
            "type": "main",
            "index": 3
          }
        ]
      ]
    },
    "Obligation Extraction Agent": {
      "main": [
        [
          {
            "node": "Merge Analysis Results",
            "type": "main",
            "index": 2
          }
        ]
      ]
    }
  }
}
Pro

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

About this workflow

This workflow automates end-to-end contract analysis using AI. It extracts clauses, evaluates risks, tracks obligations, and generates an executive summary from uploaded contracts.

Source: https://n8n.io/workflows/14823/ — 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

This workflow captures incoming leads from a webhook, enriches them using AI, and automates the entire sales pipeline. It validates data, scores leads as hot, warm, or cold, assigns them to sales reps

Agent, OpenAI Chat, Output Parser Structured +5
AI & RAG

This workflow automates CSV data processing from upload to database insertion.

Agent, Anthropic Chat, Output Parser Structured +3
AI & RAG

Enhance your support, onboarding, and internal knowledge workflows with an intelligent RAG-powered chatbot that responds using live data stored in Google Sheets. 🤖📚 Built for teams that rely on struct

Chat Trigger, Output Parser Structured, Memory Buffer Window +6
AI & RAG

Fully automates your service order pipeline from incoming booking to supplier confirmation — with built-in SLA enforcement and automatic escalation if a supplier goes silent. 📥 Receives orders via web

HTTP Request, Google Sheets, Agent +4
AI & RAG

This workflow automates enterprise resource planning (ERP) operations across Engineering, Finance, HR, and Admin departments for operations managers, ERP administrators, and business process owners wh

Agent, Gmail, Slack +6