This workflow corresponds to n8n.io template #16603 — we link there as the canonical source.
This workflow follows the Agent → Error Trigger 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 →
{
"id": "GbgBBwQmXxtCr2yq",
"name": "Automated Loan Risk Analysis Agent for Underwriting Teams",
"tags": [],
"nodes": [
{
"id": "307f0acc-6128-409f-a1d1-4667089a94a5",
"name": "Overview",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1712,
-576
],
"parameters": {
"width": 680,
"height": 508,
"content": "## \ud83c\udfe6 AI Loan Underwriting Copilot\n\n### How it works\nThis workflow automates the initial mortgage underwriting process. When a new loan application PDF lands in a designated Google Drive folder, it's downloaded, parsed, and passed through four sequential AI analysis stages \u2014 extracting applicant data, scoring risk, writing a lending summary, and issuing a final underwriting recommendation. The completed report is emailed to the loan officer automatically.\n\nIt solves the bottleneck of manually reviewing application packages, cutting initial review time from hours to minutes without sacrificing the depth of analysis.\n\n### Setup steps\n1. **Google Drive** \u2014 Connect your OAuth2 credentials and point the trigger to your loan applications folder.\n2. **OpenAI** \u2014 Add your OpenAI API key (GPT-4o-mini is used across all four AI stages).\n3. **Gmail** \u2014 Connect via OAuth2 and update the recipient email in the *Send Email* node.\n4. **Slack** \u2014 Connect your workspace OAuth2 credentials and confirm the error-alert channel ID.\n5. Run a test with a sample loan application PDF to verify the full pipeline end-to-end.\n\n> \u26a0\ufe0f Do not hardcode personal emails or API keys. Use n8n credentials manager for all secrets."
},
"typeVersion": 1
},
{
"id": "6fab6bb2-f807-4065-b819-c892cef2ba3c",
"name": "Section: File Ingestion",
"type": "n8n-nodes-base.stickyNote",
"position": [
-848,
96
],
"parameters": {
"color": 7,
"width": 536,
"height": 440,
"content": "## \ud83d\udcc2 File Ingestion\nWatches a Google Drive folder for new loan application PDFs, downloads each file, and extracts raw text for downstream AI processing."
},
"typeVersion": 1
},
{
"id": "cc47ccc5-8ab8-423a-b30b-102fbd0e5239",
"name": "Section: Data Extraction",
"type": "n8n-nodes-base.stickyNote",
"position": [
-208,
32
],
"parameters": {
"color": 7,
"width": 584,
"height": 680,
"content": "## \ud83d\udd0d Applicant Data Extraction\nParses the raw PDF text and uses GPT-4o-mini to extract structured applicant fields \u2014 income, employment, credit score, assets, liabilities, and DTI ratio \u2014 into a validated JSON object."
},
"typeVersion": 1
},
{
"id": "7368e88d-f61e-4670-b2d9-f71c438e3f5e",
"name": "Section: Risk Scoring",
"type": "n8n-nodes-base.stickyNote",
"position": [
464,
32
],
"parameters": {
"color": 7,
"width": 764,
"height": 696,
"content": "## \ud83d\udcca Risk Scoring & Lending Summary\nA second AI agent scores applicant risk (0\u2013100) and sets approval confidence. A third agent then drafts a plain-text lending summary covering income, assets, liabilities, and financial strengths and concerns."
},
"typeVersion": 1
},
{
"id": "caa24544-f641-468a-adf4-6662957ad84e",
"name": "Section: Decision & Delivery",
"type": "n8n-nodes-base.stickyNote",
"position": [
1264,
16
],
"parameters": {
"color": 7,
"width": 940,
"height": 680,
"content": "## \u2705 Final Decision & Delivery\nThe final AI agent issues one of four recommendations (APPROVE / CONDITIONAL APPROVAL / FURTHER REVIEW / DECLINE). A JavaScript node assembles the full report, which is then emailed to the loan officer."
},
"typeVersion": 1
},
{
"id": "58aaccd3-1564-498a-be2b-126359fa86c6",
"name": "Section: Error Handling",
"type": "n8n-nodes-base.stickyNote",
"position": [
336,
816
],
"parameters": {
"color": 7,
"width": 844,
"height": 436,
"content": "## \u26a0\ufe0f Error Handling\nIf either the data extraction or risk scoring agents fail, a Slack alert is sent to the designated channel and the workflow retries from the file download step."
},
"typeVersion": 1
},
{
"id": "e3a558f4-e504-400e-a2c7-97b04e628424",
"name": "Security & Credentials",
"type": "n8n-nodes-base.stickyNote",
"position": [
2288,
432
],
"parameters": {
"color": 3,
"width": 328,
"height": 304,
"content": "## \ud83d\udd10 Credentials & Security\nUse OAuth2 for Google Drive, Gmail, and Slack. Store your OpenAI API key in n8n's credentials manager \u2014 never paste it directly into node fields. Replace all personal emails and channel IDs with your own before publishing."
},
"typeVersion": 1
},
{
"id": "25d59d9a-b8dd-4b02-bdd4-454f540ac9c0",
"name": "Watch Loan Applications Folder",
"type": "n8n-nodes-base.googleDriveTrigger",
"position": [
-720,
288
],
"parameters": {
"event": "fileCreated",
"options": {},
"pollTimes": {
"item": [
{
"mode": "everyMinute"
}
]
},
"triggerOn": "specificFolder",
"folderToWatch": {
"__rl": true,
"mode": "list",
"value": "YOUR_GOOGLE_DRIVE_FOLDER_ID",
"cachedResultUrl": "https://drive.google.com/drive/folders/YOUR_GOOGLE_DRIVE_FOLDER_ID",
"cachedResultName": "Loan Applications"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "6ce99c80-bca1-4c32-807f-307391741228",
"name": "Download Application PDF",
"type": "n8n-nodes-base.googleDrive",
"position": [
-448,
288
],
"parameters": {
"fileId": {
"__rl": true,
"mode": "id",
"value": "={{ $json.id }}"
},
"options": {},
"operation": "download"
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "ace5aa6b-4d60-48a3-aee0-889f07b97e9e",
"name": "Extract PDF Text",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-160,
288
],
"parameters": {
"options": {},
"operation": "pdf"
},
"typeVersion": 1.1
},
{
"id": "50beb882-4c81-420b-80e0-9d4c6fb4e913",
"name": "Extract Applicant Data (AI)",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueErrorOutput",
"position": [
80,
288
],
"parameters": {
"text": "=You are an expert mortgage underwriter.\n\nAnalyze the following loan application package.\n\n{{ $json.text }}\n\nExtract and return ONLY valid JSON.\n\n{\n \"applicant_name\":\"\",\n \"loan_amount\":\"\",\n \"annual_income\":\"\",\n \"monthly_income\":\"\",\n \"employer\":\"\",\n \"employment_duration\":\"\",\n \"credit_score\":\"\",\n \"assets\":\"\",\n \"liabilities\":\"\",\n \"debt_to_income_ratio\":\"\"\n}",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": false,
"typeVersion": 3
},
{
"id": "665449b4-d6d0-4409-bf6c-0678d5cf48fb",
"name": "GPT-4o-mini: Data Extraction",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
48,
528
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "fde581a8-19cc-434d-bd46-823df1da24f1",
"name": "Parse Applicant Data Schema",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
240,
528
],
"parameters": {
"jsonSchemaExample": "{\n \"applicant_name\": \"string\",\n \"loan_amount\": \"string\",\n \"annual_income\": \"string\",\n \"monthly_income\": \"string\",\n \"employer\": \"string\",\n \"employment_duration\": \"string\",\n \"credit_score\": \"string\",\n \"assets\": \"string\",\n \"liabilities\": \"string\",\n \"debt_to_income_ratio\": \"string\"\n}"
},
"typeVersion": 1.3
},
{
"id": "f86a26fc-f4e0-47e8-920e-f103f73c3969",
"name": "Score Applicant Risk (AI)",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueErrorOutput",
"position": [
544,
272
],
"parameters": {
"text": "=You are a senior mortgage risk analyst.\n\nApplicant Data:\n\n{{ $('Extract PDF Text').item.json.text }}\n\nCalculate:\n\n1. Risk Score (0-100)\n2. Risk Level\n3. Key Findings\n4. Approval Confidence %\n\nReturn JSON only.\n\n{\n \"risk_score\": 0,\n \"risk_level\": \"\",\n \"approval_confidence\": \"\",\n \"key_findings\": []\n}",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": false,
"typeVersion": 3
},
{
"id": "4f7bd9a6-d8e8-43db-b309-5d50c2a4250d",
"name": "GPT-4o-mini: Risk Scoring",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
544,
512
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "190a21d1-f473-4e41-a469-85dd0413da56",
"name": "Parse Risk Score Schema",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
736,
496
],
"parameters": {
"jsonSchemaExample": "\n{\n \"risk_score\": 0,\n \"risk_level\": \"\",\n \"approval_confidence\": \"\",\n \"key_findings\": []\n}"
},
"typeVersion": 1.3
},
{
"id": "1e55e53a-8bbd-4558-8db4-e634f836f35e",
"name": "Generate Lending Summary (AI)",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueRegularOutput",
"position": [
992,
256
],
"parameters": {
"text": "=You are a professional loan underwriter.\n\nApplicant Information:\n\n{{ JSON.stringify($('Extract Applicant Data (AI)').item.json.output, null, 2) }}\n\nRisk Assessment:\n\n{{ JSON.stringify($json.output, null, 2) }}\n\nCreate a professional lending summary.\n\nInclude:\n\n1. Applicant Overview\n2. Income Analysis\n3. Asset Analysis\n4. Liability Analysis\n5. Risk Assessment Summary\n6. Financial Strengths\n7. Financial Concerns\n\nReturn plain text only.",
"options": {},
"promptType": "define"
},
"retryOnFail": false,
"typeVersion": 3
},
{
"id": "ca0ac7a6-2198-4c0b-b57d-6d0470efe5b2",
"name": "GPT-4o-mini: Lending Summary",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
928,
496
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "b8e1d758-4fc8-4fd6-b835-0291e9c450d5",
"name": "Issue Underwriting Decision (AI)",
"type": "@n8n/n8n-nodes-langchain.agent",
"onError": "continueRegularOutput",
"position": [
1376,
256
],
"parameters": {
"text": "=You are a senior mortgage underwriter.\n\nApplicant Information:\n\n{{ JSON.stringify($('Extract Applicant Data (AI)').item.json.output, null, 2) }}\n\nRisk Assessment:\n\n{{ JSON.stringify($('Score Applicant Risk (AI)').item.json.output, null, 2) }}\n\nLending Summary:\n\n{{ $json.output }}\n\nProvide a final underwriting recommendation.\n\nChoose exactly one:\n\nAPPROVE\nCONDITIONAL APPROVAL\nFURTHER REVIEW\nDECLINE\n\nReturn ONLY JSON:\n\n{\n \"decision\":\"\",\n \"reasoning\":\"\",\n \"conditions\":[]\n}",
"options": {},
"promptType": "define",
"hasOutputParser": true
},
"retryOnFail": false,
"typeVersion": 3
},
{
"id": "0b2a6126-a0a3-425f-bacf-42393d4af30d",
"name": "GPT-4o-mini: Final Decision",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
1312,
480
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4o-mini",
"cachedResultName": "gpt-4o-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "21565e14-1896-4afc-8fe5-7f384942afa6",
"name": "Parse Decision Schema",
"type": "@n8n/n8n-nodes-langchain.outputParserStructured",
"position": [
1552,
496
],
"parameters": {
"jsonSchemaExample": "\n{\n \"decision\":\"\",\n \"reasoning\":\"\",\n \"conditions\":[]\n}"
},
"typeVersion": 1.3
},
{
"id": "ae9e64d4-dcf6-4b15-9b54-2074c454688b",
"name": "Assemble Final Report",
"type": "n8n-nodes-base.code",
"position": [
1776,
256
],
"parameters": {
"jsCode": "const applicant = $('Extract Applicant Data (AI)').first().json.output;\nconst risk = $('Score Applicant Risk (AI)').first().json.output;\nconst summary = $('Generate Lending Summary (AI)').first().json.output;\nconst recommendation = $('Issue Underwriting Decision (AI)').first().json.output;\n\nreturn [{\n report: `\nLOAN OFFICER COPILOT REPORT\n\n====================================\n\nFINAL DECISION\n${recommendation.decision}\n\nREASONING\n${recommendation.reasoning}\n\n====================================\n\nAPPLICANT INFORMATION\n\nApplicant Name: ${applicant.applicant_name}\nLoan Amount: ${applicant.loan_amount}\nAnnual Income: ${applicant.annual_income}\nEmployer: ${applicant.employer}\nCredit Score: ${applicant.credit_score}\n\n====================================\n\nRISK ASSESSMENT\n\nRisk Score: ${risk.risk_score}\nRisk Level: ${risk.risk_level}\nApproval Confidence: ${risk.approval_confidence}\n\nKey Findings:\n${risk.key_findings.join('\\n')}\n\n====================================\n\nLENDING SUMMARY\n\n${summary}\n\n====================================\n`\n}];"
},
"typeVersion": 2
},
{
"id": "9f41e4b7-871d-4280-a710-0b6e5eee84cd",
"name": "Email Report to Loan Officer",
"type": "n8n-nodes-base.gmail",
"position": [
2032,
256
],
"parameters": {
"sendTo": "=loan-officer@example.com",
"message": "={{ $json.report }}",
"options": {},
"subject": "=Loan Review Completed - {{ $('Extract Applicant Data (AI)').item.json.output.applicant_name }}",
"emailType": "text"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "c6b038db-49c9-41ce-bd45-8013d511864a",
"name": "Slack Alert: Extraction Failed",
"type": "n8n-nodes-base.slack",
"position": [
512,
1024
],
"parameters": {
"text": "=\u26a0\ufe0f Loan underwriting error: Data extraction failed for file {{ $('Watch Loan Applications Folder').item.json.name }}. Check the workflow execution log.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SLACK_CHANNEL_ID",
"cachedResultName": "your-alerts-channel"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "090f57da-a6aa-459a-91c5-4ce08415c047",
"name": "Slack Alert: Risk Scoring Failed",
"type": "n8n-nodes-base.slack",
"position": [
944,
960
],
"parameters": {
"text": "=\u26a0\ufe0f Loan underwriting error: Risk scoring failed for file {{ $('Watch Loan Applications Folder').item.json.name }}. Check the workflow execution log.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "YOUR_SLACK_CHANNEL_ID",
"cachedResultName": "your-alerts-channel"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "018bf86a-ce9a-4935-8d8e-c020be355ffd",
"name": "On Workflow Error",
"type": "n8n-nodes-base.errorTrigger",
"position": [
-992,
1024
],
"parameters": {},
"typeVersion": 1
},
{
"id": "5f63e86b-f358-4b89-875a-37245062db84",
"name": "Slack: Error Alert",
"type": "n8n-nodes-base.slack",
"position": [
-736,
1024
],
"parameters": {
"text": "=Error occured ",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C0AN1UGL0RM",
"cachedResultName": "all-n8n-automations"
},
"otherOptions": {},
"authentication": "oAuth2"
},
"credentials": {
"slackOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "e6c53e2f-539b-420b-b773-efbb7450f99e",
"name": "Section: Error Handler",
"type": "n8n-nodes-base.stickyNote",
"position": [
-1072,
880
],
"parameters": {
"color": 7,
"width": 508,
"height": 328,
"content": "## \u26a0\ufe0f Error Handler\nCatches any failure across the entire workflow and immediately sends a Slack alert to the ops channel. Wire this to every sub-workflow or critical node to ensure no silent failures."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"versionId": "553cd3ba-3c97-44c0-9672-8ad735f91b2c",
"connections": {
"Extract PDF Text": {
"main": [
[
{
"node": "Extract Applicant Data (AI)",
"type": "main",
"index": 0
}
]
]
},
"On Workflow Error": {
"main": [
[
{
"node": "Slack: Error Alert",
"type": "main",
"index": 0
}
]
]
},
"Assemble Final Report": {
"main": [
[
{
"node": "Email Report to Loan Officer",
"type": "main",
"index": 0
}
]
]
},
"Parse Decision Schema": {
"ai_outputParser": [
[
{
"node": "Issue Underwriting Decision (AI)",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Parse Risk Score Schema": {
"ai_outputParser": [
[
{
"node": "Score Applicant Risk (AI)",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"Download Application PDF": {
"main": [
[
{
"node": "Extract PDF Text",
"type": "main",
"index": 0
}
]
]
},
"GPT-4o-mini: Risk Scoring": {
"ai_languageModel": [
[
{
"node": "Score Applicant Risk (AI)",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Score Applicant Risk (AI)": {
"main": [
[
{
"node": "Generate Lending Summary (AI)",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack Alert: Risk Scoring Failed",
"type": "main",
"index": 0
}
]
]
},
"Extract Applicant Data (AI)": {
"main": [
[
{
"node": "Score Applicant Risk (AI)",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack Alert: Extraction Failed",
"type": "main",
"index": 0
}
]
]
},
"GPT-4o-mini: Final Decision": {
"ai_languageModel": [
[
{
"node": "Issue Underwriting Decision (AI)",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Parse Applicant Data Schema": {
"ai_outputParser": [
[
{
"node": "Extract Applicant Data (AI)",
"type": "ai_outputParser",
"index": 0
}
]
]
},
"GPT-4o-mini: Data Extraction": {
"ai_languageModel": [
[
{
"node": "Extract Applicant Data (AI)",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"GPT-4o-mini: Lending Summary": {
"ai_languageModel": [
[
{
"node": "Generate Lending Summary (AI)",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Generate Lending Summary (AI)": {
"main": [
[
{
"node": "Issue Underwriting Decision (AI)",
"type": "main",
"index": 0
}
]
]
},
"Slack Alert: Extraction Failed": {
"main": [
[
{
"node": "Download Application PDF",
"type": "main",
"index": 0
}
]
]
},
"Watch Loan Applications Folder": {
"main": [
[
{
"node": "Download Application PDF",
"type": "main",
"index": 0
}
]
]
},
"Issue Underwriting Decision (AI)": {
"main": [
[
{
"node": "Assemble Final Report",
"type": "main",
"index": 0
}
]
]
},
"Slack Alert: Risk Scoring Failed": {
"main": [
[
{
"node": "Download Application PDF",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2googleDriveOAuth2ApiopenAiApislackOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow monitors a Google Drive folder for new loan application PDFs, extracts text, and uses OpenAI (GPT-4o-mini) to structure applicant data, score risk, generate a lending summary, and produce an underwriting recommendation, then emails the final report via Gmail and…
Source: https://n8n.io/workflows/16603/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Who is this for? Agencies, consultants, and service providers who conduct discovery calls and need to quickly turn conversations into professional proposals.
Transcript Evalu8r V2 is a robust browser-based transcript analysis tool powered by Deepgram’s speech-to-text API and built into an n8n workflow template. This release introduces full in-browser audio
Transcript Evalu8r is an AI-powered transcript analysis workflow that automates the processing, visualization, and evaluation of transcribed conversations. This n8n workflow template is designed to he
Transform your manual hiring process into an intelligent evaluation system that saves 15-20 minutes per candidate! This workflow automates the entire candidate assessment pipeline - from CSV/XLSX uplo
Streamline customer support with a real-time, AI-powered answer engine that detects incoming support emails, classifies intent, identifies the customer’s GEO region, and generates a tailored reply rea