{
  "id": "p4J3f2FvJmmgum8I",
  "meta": {
    "builderVariant": "mcp",
    "aiBuilderAssisted": true
  },
  "name": "Explain any contract PDF in plain language with Gemini and flag risky clauses",
  "tags": [],
  "nodes": [
    {
      "id": "0dcadb7b-aa71-440d-a8b1-0a20012916e9",
      "name": "Contract Upload Form",
      "type": "n8n-nodes-base.formTrigger",
      "position": [
        48,
        48
      ],
      "parameters": {
        "options": {
          "buttonLabel": "Explain my contract",
          "respondWithOptions": {
            "values": {
              "formSubmittedText": "Thanks! Your plain-language summary will arrive by email shortly."
            }
          }
        },
        "formTitle": "Explain this contract to me",
        "formFields": {
          "values": [
            {
              "fieldType": "email",
              "fieldLabel": "Your email",
              "requiredField": true
            },
            {
              "fieldType": "dropdown",
              "fieldLabel": "Document type",
              "fieldOptions": {
                "values": [
                  {
                    "option": "Rental or lease agreement"
                  },
                  {
                    "option": "Insurance policy"
                  },
                  {
                    "option": "Employment contract"
                  },
                  {
                    "option": "Terms of service"
                  },
                  {
                    "option": "Other"
                  }
                ]
              },
              "requiredField": true
            },
            {
              "fieldType": "textarea",
              "fieldLabel": "What worries you",
              "placeholder": "e.g. Can the landlord raise the rent mid-term?"
            },
            {
              "fieldType": "file",
              "fieldLabel": "Contract",
              "multipleFiles": false,
              "requiredField": true,
              "acceptFileTypes": ".pdf"
            }
          ]
        },
        "formDescription": "Upload a lease, insurance policy, employment contract or terms of service and get it explained in plain language with the risky parts flagged."
      },
      "typeVersion": 2.6
    },
    {
      "id": "4bce86a7-2f5c-4e47-8406-0856d34305df",
      "name": "Extract Contract Text",
      "type": "n8n-nodes-base.extractFromFile",
      "position": [
        272,
        48
      ],
      "parameters": {
        "options": {},
        "operation": "pdf",
        "binaryPropertyName": "Contract"
      },
      "typeVersion": 1.1
    },
    {
      "id": "1e6e9405-39a5-4bb5-9bb9-5d8833ec3545",
      "name": "Has Readable Text",
      "type": "n8n-nodes-base.if",
      "position": [
        480,
        48
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": false,
            "typeValidation": "loose"
          },
          "combinator": "and",
          "conditions": [
            {
              "operator": {
                "type": "number",
                "operation": "gt"
              },
              "leftValue": "={{ ($json.text || \"\").length }}",
              "rightValue": 300
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f98fae34-1c47-4d19-8c29-de61b5437687",
      "name": "Explain Contract with Gemini",
      "type": "@n8n/n8n-nodes-langchain.chainLlm",
      "onError": "continueErrorOutput",
      "position": [
        928,
        32
      ],
      "parameters": {
        "text": "=You are a careful contract reviewer helping an ordinary person who is not a lawyer. Explain the {{ $('Contract Upload Form').item.json['Document type'] }} below in plain language with no legal jargon. Give a short plain summary, an overall risk_level of low, medium or high, the obligations this person is taking on, the key dates and notice periods, the costs and penalties, and any clauses that are unusual or one-sided with why they matter and a severity. Also list the questions they should ask before signing. If they raised a specific concern, answer it directly in answer_to_concern, quoting the relevant clause. Be accurate and never invent clauses that are not in the text.\n\nTheir concern: {{ $('Contract Upload Form').item.json['What worries you'] }}\n\nContract:\n{{ $json.text }}",
        "batching": {},
        "promptType": "define",
        "hasOutputParser": true
      },
      "typeVersion": 1.9
    },
    {
      "id": "edd31b1a-a64b-4db4-99b6-be22b98bbbe6",
      "name": "Google Gemini Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
      "position": [
        912,
        192
      ],
      "parameters": {
        "options": {
          "temperature": 0.2,
          "maxOutputTokens": 4096
        },
        "modelName": "models/gemini-3.1-flash-lite"
      },
      "credentials": {
        "googlePalmApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.1
    },
    {
      "id": "ef743ce4-0bc6-45ef-ba3a-9c23ecc1e2bf",
      "name": "Contract Review Parser",
      "type": "@n8n/n8n-nodes-langchain.outputParserStructured",
      "position": [
        1088,
        192
      ],
      "parameters": {
        "jsonSchemaExample": "{\"plain_summary\":\"You rent the flat for 12 months at 1200 a month\",\"risk_level\":\"medium\",\"your_obligations\":[\"Pay rent by the 1st\"],\"key_dates\":[\"Notice must be given 2 months before the end\"],\"costs\":[\"Deposit of 2400\"],\"risky_clauses\":[{\"clause\":\"Landlord may increase rent with 30 days notice\",\"why\":\"No cap on the increase\",\"severity\":\"high\"}],\"questions_to_ask\":[\"Is there a cap on rent increases?\"],\"answer_to_concern\":\"Yes, clause 8 allows a mid-term increase\"}"
      },
      "typeVersion": 1.3
    },
    {
      "id": "2d2dcdd1-1407-42dc-ae10-87623fa44283",
      "name": "Parse Contract Review",
      "type": "n8n-nodes-base.code",
      "position": [
        1584,
        16
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const src = $json.output || $json;\nconst f = $('Contract Upload Form').item.json;\nconst list = function (x) { return Array.isArray(x) ? x : []; };\nconst bullets = function (x) { return list(x).map(function (i) { return '- ' + i; }).join('\\n'); };\nconst risky = list(src.risky_clauses).map(function (c) { return { clause: c.clause || '', why: c.why || '', severity: String(c.severity || 'medium').toLowerCase() }; });\nreturn {\n  email: f['Your email'] || '',\n  docType: f['Document type'] || '',\n  concern: f['What worries you'] || '',\n  plainSummary: src.plain_summary || '',\n  riskLevel: String(src.risk_level || 'medium').toLowerCase(),\n  obligations: bullets(src.your_obligations),\n  keyDates: bullets(src.key_dates),\n  costs: bullets(src.costs),\n  questions: bullets(src.questions_to_ask),\n  answerToConcern: src.answer_to_concern || '',\n  riskyCount: risky.length,\n  riskyText: risky.map(function (c) { return '- [' + c.severity.toUpperCase() + '] ' + c.clause + ' -> ' + c.why; }).join('\\n'),\n  riskyClauses: risky\n};"
      },
      "typeVersion": 2
    },
    {
      "id": "ab800c31-19d1-4865-bdef-e820cbca80bf",
      "name": "Log Contract Review",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1824,
        16
      ],
      "parameters": {
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Contract Reviews"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "",
          "cachedResultName": "Select your spreadsheet"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.7
    },
    {
      "id": "1aa0e448-5b25-4318-b9b7-40b410c8cfdb",
      "name": "Route by Risk Level",
      "type": "n8n-nodes-base.switch",
      "position": [
        2112,
        -16
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $(\"Parse Contract Review\").item.json.riskLevel }}",
                    "rightValue": "high"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $(\"Parse Contract Review\").item.json.riskLevel }}",
                    "rightValue": "medium"
                  }
                ]
              }
            },
            {
              "conditions": {
                "options": {
                  "version": 1,
                  "leftValue": "",
                  "caseSensitive": false,
                  "typeValidation": "loose"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $(\"Parse Contract Review\").item.json.riskLevel }}",
                    "rightValue": "low"
                  }
                ]
              }
            }
          ]
        },
        "options": {
          "fallbackOutput": "extra",
          "renameFallbackOutput": "Other"
        }
      },
      "typeVersion": 3.2
    },
    {
      "id": "fcc5e76c-3e6a-41eb-bd06-f99d957a6f22",
      "name": "Email Do Not Sign Yet",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2384,
        -32
      ],
      "parameters": {
        "sendTo": "={{ $(\"Parse Contract Review\").item.json.email }}",
        "message": "={{ \"In plain language:\\n\" + $(\"Parse Contract Review\").item.json.plainSummary + \"\\n\\nThis contract has clauses worth pushing back on:\\n\" + $(\"Parse Contract Review\").item.json.riskyText + \"\\n\\nAsk these before you sign:\\n\" + $(\"Parse Contract Review\").item.json.questions + \"\\n\\nYour obligations:\\n\" + $(\"Parse Contract Review\").item.json.obligations + \"\\n\\nKey dates:\\n\" + $(\"Parse Contract Review\").item.json.keyDates + \"\\n\\nCosts:\\n\" + $(\"Parse Contract Review\").item.json.costs + \"\\n\\nOn your question:\\n\" + $(\"Parse Contract Review\").item.json.answerToConcern + \"\\n\\nThis is an AI summary, not legal advice. For anything significant, have a qualified lawyer review it.\" }}",
        "options": {},
        "subject": "={{ \"Do not sign yet - \" + $(\"Parse Contract Review\").item.json.docType }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "279592d8-b555-452c-9016-00b7a0888f3a",
      "name": "Email Review Before Signing",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2384,
        128
      ],
      "parameters": {
        "sendTo": "={{ $(\"Parse Contract Review\").item.json.email }}",
        "message": "={{ \"In plain language:\\n\" + $(\"Parse Contract Review\").item.json.plainSummary + \"\\n\\nClauses to check:\\n\" + $(\"Parse Contract Review\").item.json.riskyText + \"\\n\\nQuestions to ask:\\n\" + $(\"Parse Contract Review\").item.json.questions + \"\\n\\nYour obligations:\\n\" + $(\"Parse Contract Review\").item.json.obligations + \"\\n\\nKey dates:\\n\" + $(\"Parse Contract Review\").item.json.keyDates + \"\\n\\nCosts:\\n\" + $(\"Parse Contract Review\").item.json.costs + \"\\n\\nOn your question:\\n\" + $(\"Parse Contract Review\").item.json.answerToConcern + \"\\n\\nThis is an AI summary, not legal advice.\" }}",
        "options": {},
        "subject": "={{ \"Worth a closer look - \" + $(\"Parse Contract Review\").item.json.docType }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "060d8a75-9fe0-4ce6-aa27-17ba13179ba5",
      "name": "Email Plain Summary",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2384,
        288
      ],
      "parameters": {
        "sendTo": "={{ $(\"Parse Contract Review\").item.json.email }}",
        "message": "={{ \"In plain language:\\n\" + $(\"Parse Contract Review\").item.json.plainSummary + \"\\n\\nNothing unusual stood out.\\n\\nYour obligations:\\n\" + $(\"Parse Contract Review\").item.json.obligations + \"\\n\\nKey dates:\\n\" + $(\"Parse Contract Review\").item.json.keyDates + \"\\n\\nCosts:\\n\" + $(\"Parse Contract Review\").item.json.costs + \"\\n\\nOn your question:\\n\" + $(\"Parse Contract Review\").item.json.answerToConcern + \"\\n\\nThis is an AI summary, not legal advice.\" }}",
        "options": {},
        "subject": "={{ \"Your \" + $(\"Parse Contract Review\").item.json.docType + \" explained\" }}",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "58d6d58d-70e1-475d-a20d-a4b497075e8c",
      "name": "Email Generic Summary",
      "type": "n8n-nodes-base.gmail",
      "position": [
        2384,
        448
      ],
      "parameters": {
        "sendTo": "={{ $(\"Parse Contract Review\").item.json.email }}",
        "message": "={{ $(\"Parse Contract Review\").item.json.plainSummary + \"\\n\\nObligations:\\n\" + $(\"Parse Contract Review\").item.json.obligations + \"\\n\\nQuestions to ask:\\n\" + $(\"Parse Contract Review\").item.json.questions + \"\\n\\nThis is an AI summary, not legal advice.\" }}",
        "options": {},
        "subject": "Your contract summary",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "32d66f49-a555-424f-a782-0cfc7a2289cf",
      "name": "Email Unreadable PDF",
      "type": "n8n-nodes-base.gmail",
      "position": [
        688,
        160
      ],
      "parameters": {
        "sendTo": "={{ $(\"Contract Upload Form\").item.json[\"Your email\"] }}",
        "message": "Your PDF did not contain enough selectable text - it is probably a scan or photo. Please upload a text-based PDF and try again.",
        "options": {},
        "subject": "We could not read your contract",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "86077289-4f2c-478f-b072-d2d704d2ec32",
      "name": "Email Review Failure",
      "type": "n8n-nodes-base.gmail",
      "position": [
        1296,
        160
      ],
      "parameters": {
        "sendTo": "={{ $(\"Contract Upload Form\").item.json[\"Your email\"] }}",
        "message": "Something went wrong while reviewing your document. Please try again, or upload a shorter extract of the contract.",
        "options": {},
        "subject": "We could not review your contract",
        "emailType": "text"
      },
      "credentials": {
        "gmailOAuth2": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "35aa1a4c-728a-4a9d-b5ef-9ba4867eb1c2",
      "name": "Overview Sticky",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -624,
        -288
      ],
      "parameters": {
        "width": 600,
        "height": 676,
        "content": "## Explain any contract PDF in plain language with Gemini and flag risky clauses\n\n### How it works\nMost people sign leases, insurance policies and job contracts without reading them, because the language is impenetrable. Upload the PDF through the built-in n8n form, pick the document type and optionally say what worries you. A Basic LLM Chain with Google Gemini rewrites the contract in plain language, lists the obligations you are taking on, the key dates and notice periods, the costs and penalties, and flags every unusual or one-sided clause with a severity and why it matters - then answers your specific concern by pointing at the relevant clause. Scanned PDFs are rejected up front. Reviews are logged to Google Sheets and a Switch sends a different email by risk: high risk gets a do-not-sign-yet warning with negotiation questions, low risk gets a simple summary.\n\n### Setup\n1. Connect Google Gemini (PaLM) API, Google Sheets and Gmail.\n2. Point the Sheets node at your spreadsheet.\n3. Open the form URL and upload a text-based PDF.\n\n### Customization tips\nAdd your own red-flag list, or route high-risk contracts to a lawyer."
      },
      "typeVersion": 1
    },
    {
      "id": "7a48b829-c8d9-408a-bd0e-12e0e979247b",
      "name": "S1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        0,
        -288
      ],
      "parameters": {
        "color": 7,
        "width": 864,
        "height": 900,
        "content": "## 1. Upload & validate\nThe built-in n8n form takes the document type, your specific worry and the PDF. Scans without selectable text are rejected with a helpful email."
      },
      "typeVersion": 1
    },
    {
      "id": "250f0e66-0dcc-4dd4-9c47-bd4001be9a89",
      "name": "S2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        880,
        -288
      ],
      "parameters": {
        "color": 7,
        "width": 628,
        "height": 900,
        "content": "## 2. Plain-language review (Basic LLM Chain)\nGemini returns a plain summary, risk level, obligations, dates, costs, risky clauses with severity, and a direct answer to your concern."
      },
      "typeVersion": 1
    },
    {
      "id": "de68cfc4-38ba-4d9d-bd0d-69d3526276ec",
      "name": "S3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1520,
        -288
      ],
      "parameters": {
        "color": 7,
        "width": 500,
        "height": 900,
        "content": "## 3. Parse & log\nFlatten the review into readable sections and append it to your Google Sheets history."
      },
      "typeVersion": 1
    },
    {
      "id": "209b2d1b-f887-484d-9709-737f5bb9d03c",
      "name": "S4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2032,
        -288
      ],
      "parameters": {
        "color": 7,
        "width": 552,
        "height": 900,
        "content": "## 4. Route by risk\nHigh risk gets a do-not-sign-yet email with negotiation questions, medium gets the check-list, low gets the plain summary. Every email states it is not legal advice."
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": true,
    "executionOrder": "v1"
  },
  "versionId": "63cbfe24-a946-4aa2-9dd4-0309a752ecb2",
  "nodeGroups": [],
  "connections": {
    "Has Readable Text": {
      "main": [
        [
          {
            "node": "Explain Contract with Gemini",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Email Unreadable PDF",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Log Contract Review": {
      "main": [
        [
          {
            "node": "Route by Risk Level",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Risk Level": {
      "main": [
        [
          {
            "node": "Email Do Not Sign Yet",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Email Review Before Signing",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Email Plain Summary",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Email Generic Summary",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Contract Upload Form": {
      "main": [
        [
          {
            "node": "Extract Contract Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract Contract Text": {
      "main": [
        [
          {
            "node": "Has Readable Text",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Contract Review": {
      "main": [
        [
          {
            "node": "Log Contract Review",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Contract Review Parser": {
      "ai_outputParser": [
        [
          {
            "node": "Explain Contract with Gemini",
            "type": "ai_outputParser",
            "index": 0
          }
        ]
      ]
    },
    "Google Gemini Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "Explain Contract with Gemini",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Explain Contract with Gemini": {
      "main": [
        [
          {
            "node": "Parse Contract Review",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Email Review Failure",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}