This workflow follows the HTTP Request → Microsoft Outlook 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 →
{
"name": "LoanOS \u2014 Pre-Approval Email",
"nodes": [
{
"parameters": {
"path": "loanos-pre-approval",
"httpMethod": "POST",
"options": {}
},
"id": "webhook",
"name": "Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
220,
300
]
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": ""
},
"conditions": [
{
"id": "pa-check",
"leftValue": "={{ $json.body.doc_type }}",
"rightValue": "pre_approval",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
},
"id": "is-pa",
"name": "Is Pre-Approval?",
"type": "n8n-nodes-base.if",
"typeVersion": 2.2,
"position": [
440,
300
]
},
{
"parameters": {
"url": "=https://uuqedsvjlkeszrbwzizl.supabase.co/storage/v1/object/{{ $json.body.file_path }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "Authorization",
"value": "<redacted-credential>"
}
]
},
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"id": "download-pdf",
"name": "Download PDF",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
660,
300
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const binaryKey = Object.keys($input.item.binary)[0];\nconst pdfBuffer = await this.helpers.getBinaryDataBuffer(0, binaryKey);\nconst base64PDF = pdfBuffer.toString('base64');\n\nconst systemPrompt = `You are extracting fields from a Pre-Approval Letter PDF for a mortgage loan. Extract EXACTLY these fields and return valid JSON only \u2014 no markdown, no explanation.\n\nRequired fields:\n- first_name (borrower first name only)\n- full_name (borrower full legal name)\n- borrower_email (if present in the letter, otherwise null)\n- purchase_price (maximum approved purchase price \u2014 dollar amount, numbers only)\n- loan_amount (maximum approved loan amount \u2014 dollar amount, numbers only)\n- loan_type (Conventional, FHA, VA, USDA, etc.)\n- expiration_date (letter expiration date \u2014 YYYY-MM-DD format)\n- property_type (Single Family, Condo, Townhome, etc. \u2014 null if not specified)\n\nReturn JSON like:\n{\"first_name\":\"Maria\",\"full_name\":\"Maria Johnson\",\"borrower_email\":null,\"purchase_price\":\"450000\",\"loan_amount\":\"360000\",\"loan_type\":\"Conventional\",\"expiration_date\":\"2026-03-31\",\"property_type\":\"Single Family\"}`;\n\nconst userPrompt = 'Extract the pre-approval letter fields from this PDF. Return ONLY the JSON object, nothing else.';\n\nconst claudeBody = {\n model: 'claude-sonnet-4-5-20251022',\n max_tokens: 2048,\n system: systemPrompt,\n messages: [{\n role: 'user',\n content: [\n { type: 'document', source: { type: 'base64', media_type: 'application/pdf', data: base64PDF } },\n { type: 'text', text: userPrompt }\n ]\n }]\n};\n\nreturn [{ json: { claudeBody, webhookBody: $('Webhook').item.json.body } }];"
},
"id": "build-claude-req",
"name": "Build Claude Request",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
880,
300
]
},
{
"parameters": {
"method": "POST",
"url": "https://api.anthropic.com/v1/messages",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "anthropic-version",
"value": "2023-06-01"
},
{
"name": "content-type",
"value": "application/json"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={{ JSON.stringify($json.claudeBody) }}",
"options": {
"timeout": 120000
}
},
"id": "call-claude",
"name": "Call Claude API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1100,
300
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"jsCode": "const raw = $json.content[0].text;\nlet pa;\ntry {\n const jsonMatch = raw.match(/\\{[\\s\\S]*\\}/);\n pa = JSON.parse(jsonMatch ? jsonMatch[0] : raw);\n} catch (e) {\n throw new Error('Failed to parse Claude response as JSON: ' + raw.substring(0, 200));\n}\n\nconst val = (v) => (v !== null && v !== undefined && v !== '') ? v : '[MISSING]';\nconst fmt$ = (n) => {\n if (!n) return '[MISSING]';\n return '$' + Number(n).toLocaleString('en-US', { minimumFractionDigits: 0, maximumFractionDigits: 0 });\n};\nconst fmtDate = (d) => {\n if (!d) return '[MISSING]';\n return new Date(d + 'T00:00:00').toLocaleDateString('en-US', { year: 'numeric', month: 'long', day: 'numeric' });\n};\n\nreturn [{ json: {\n first_name: val(pa.first_name),\n full_name: val(pa.full_name),\n borrower_email: pa.borrower_email || '[BORROWER_EMAIL]',\n purchase_price: fmt$(pa.purchase_price),\n loan_amount: fmt$(pa.loan_amount),\n loan_type: val(pa.loan_type),\n expiration_date: fmtDate(pa.expiration_date),\n property_type: pa.property_type || null,\n webhookBody: $('Build Claude Request').item.json.webhookBody\n}}];"
},
"id": "parse-pa",
"name": "Parse PA Fields",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1320,
300
]
},
{
"parameters": {
"jsCode": "const f = $json;\n\nconst subject = `\\ud83c\\udf89 You're Pre-Approved, ${f.first_name}! Here's What Happens Next`;\n\nconst html = `<!DOCTYPE html><html><head><meta charset=\"UTF-8\"></head><body style=\"margin:0;padding:0;background-color:#f4f4f4;font-family:Arial,sans-serif;\"><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f4f4f4;padding:30px 0;\"><tr><td align=\"center\"><table width=\"600\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#ffffff;border-radius:8px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,0.08);\"><tr><td style=\"background-color:#003366;padding:30px 40px;text-align:center;\"><h1 style=\"color:#ffffff;margin:0;font-size:24px;font-weight:700;letter-spacing:0.5px;\">The Styer Mortgage Team</h1><p style=\"color:#a8c4e0;margin:6px 0 0 0;font-size:14px;\">Senior Loan Officer | NMLS# 513013</p></td></tr><tr><td style=\"padding:40px 40px 20px 40px;\"><h2 style=\"color:#003366;margin:0 0 20px 0;font-size:22px;\">\\ud83c\\udf89 Congratulations, ${f.first_name}!</h2><p style=\"color:#333333;font-size:16px;line-height:1.7;margin:0 0 16px 0;\">You\\u2019re officially pre-approved \\u2014 and that\\u2019s a big deal. Here are your approval details:</p><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#f0f5ff;border-left:4px solid #003366;border-radius:4px;margin:0 0 24px 0;\"><tr><td style=\"padding:20px 24px;\"><p style=\"margin:0 0 8px 0;color:#333333;font-size:15px;\"><strong>Borrower:</strong> ${f.full_name}</p><p style=\"margin:0 0 8px 0;color:#333333;font-size:15px;\"><strong>Purchase Price:</strong> Up to ${f.purchase_price}</p><p style=\"margin:0 0 8px 0;color:#333333;font-size:15px;\"><strong>Loan Amount:</strong> Up to ${f.loan_amount}</p><p style=\"margin:0 0 8px 0;color:#333333;font-size:15px;\"><strong>Loan Type:</strong> ${f.loan_type}</p><p style=\"margin:0;color:#333333;font-size:15px;\"><strong>Letter Expires:</strong> ${f.expiration_date}</p></td></tr></table><p style=\"color:#333333;font-size:16px;line-height:1.7;margin:0 0 16px 0;\"><strong>A quick note about this letter:</strong> The pre-approval I\\u2019ve attached is a general starter letter based on your financial profile. It reflects the maximum purchase price you qualify for.</p><p style=\"color:#333333;font-size:16px;line-height:1.7;margin:0 0 16px 0;\">When you\\u2019re ready to make an offer on a specific property, I\\u2019ll send you and your real estate agent a <strong>customized pre-approval letter</strong> that matches the exact offer price. That letter will be tailored to strengthen your offer and protect your privacy \\u2014 it won\\u2019t show a higher approval than you need.</p><p style=\"color:#333333;font-size:16px;line-height:1.7;margin:0 0 24px 0;\">In the meantime, here\\u2019s what to keep in mind as you shop:</p><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"background-color:#fff8e1;border-left:4px solid #f5a623;border-radius:4px;margin:0 0 28px 0;\"><tr><td style=\"padding:20px 24px;\"><p style=\"margin:0 0 10px 0;color:#333333;font-size:15px;font-weight:700;\">Keep Your Approval Strong:</p><ul style=\"margin:0;padding-left:20px;color:#333333;font-size:15px;line-height:1.8;\"><li>Don\\u2019t open new credit cards or take on new debt</li><li>Don\\u2019t make large cash deposits without documenting the source</li><li>Avoid switching jobs before closing</li><li>Run any big purchases by me before you make them</li></ul></td></tr></table><p style=\"color:#333333;font-size:16px;line-height:1.7;margin:0 0 16px 0;\">Have questions or found a house you want to make an offer on? Reach out any time \\u2014 I\\u2019m here to move fast when you need me.</p><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin:24px 0;\"><tr><td align=\"center\"><a href=\"https://calendly.com/adamstyer/15minutes\" style=\"display:inline-block;background-color:#003366;color:#ffffff;padding:14px 32px;border-radius:6px;font-size:15px;font-weight:700;text-decoration:none;letter-spacing:0.3px;\">Schedule a Quick Call</a></td></tr></table></td></tr><tr><td style=\"padding:0 40px 40px 40px;border-top:1px solid #eeeeee;\"><table cellpadding=\"0\" cellspacing=\"0\" style=\"margin-top:24px;\"><tr><td style=\"padding-right:16px;vertical-align:top;\"><div style=\"width:50px;height:50px;background-color:#003366;border-radius:50%;display:flex;align-items:center;justify-content:center;\"><span style=\"color:#ffffff;font-size:20px;font-weight:700;\">AS</span></div></td><td style=\"vertical-align:top;\"><p style=\"margin:0;font-size:16px;font-weight:700;color:#003366;\">Adam Styer</p><p style=\"margin:2px 0;font-size:13px;color:#666666;\">Senior Loan Officer | Mortgage Solutions LP</p><p style=\"margin:2px 0;font-size:13px;color:#666666;\">NMLS# 513013</p><p style=\"margin:2px 0;font-size:13px;color:#003366;\"><a href=\"tel:5129566010\" style=\"color:#003366;text-decoration:none;\">(512) 956-6010</a></p><p style=\"margin:2px 0;font-size:13px;color:#003366;\"><a href=\"mailto:adam@thestyerteam.com\" style=\"color:#003366;text-decoration:none;\">adam@thestyerteam.com</a></p></td></tr></table><table width=\"100%\" cellpadding=\"0\" cellspacing=\"0\" style=\"margin-top:20px;padding-top:16px;border-top:1px solid #eeeeee;\"><tr><td align=\"center\"><p style=\"margin:0 0 8px 0;font-size:13px;color:#888888;\">Happy with your experience? A review means the world:</p><a href=\"https://share.google/ddpwv31jI2oqzN5Ia\" style=\"display:inline-block;margin:0 8px;font-size:13px;color:#003366;text-decoration:none;font-weight:600;\">\\u2b50 Google Review</a><span style=\"color:#cccccc;\">|</span><a href=\"https://www.zillow.com/lender-profile/adamstyer/\" style=\"display:inline-block;margin:0 8px;font-size:13px;color:#003366;text-decoration:none;font-weight:600;\">\\ud83c\\udfe1 Zillow Review</a></td></tr></table></td></tr></table></td></tr></table></body></html>`;\n\nreturn [{ json: { subject, html, to: 'adam@thestyerteam.com', fields: f } }];"
},
"id": "build-email",
"name": "Build PA Email",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1540,
300
]
},
{
"parameters": {
"resource": "draft",
"subject": "={{ $json.subject }}",
"bodyContent": "={{ $json.html }}",
"additionalFields": {
"bodyContentType": "html"
}
},
"id": "draft-email",
"name": "Draft PA Email",
"type": "n8n-nodes-base.microsoftOutlook",
"typeVersion": 2,
"position": [
1760,
300
],
"credentials": {
"microsoftOutlookOAuth2Api": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "PATCH",
"url": "=https://uuqedsvjlkeszrbwzizl.supabase.co/rest/v1/loans?id=eq.{{ $('Parse PA Fields').item.json.webhookBody.loan_id }}",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "<redacted-credential>"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=minimal"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"status\": \"pre_approved\", \"pre_approval_date\": \"{{ new Date().toISOString().split('T')[0] }}\"}"
},
"id": "update-loan",
"name": "Update Loan Record",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1540,
520
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
},
{
"parameters": {
"method": "POST",
"url": "https://uuqedsvjlkeszrbwzizl.supabase.co/rest/v1/activity_log",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"sendHeaders": true,
"headerParameters": {
"parameters": [
{
"name": "apikey",
"value": "<redacted-credential>"
},
{
"name": "Content-Type",
"value": "application/json"
},
{
"name": "Prefer",
"value": "return=minimal"
}
]
},
"sendBody": true,
"specifyBody": "json",
"jsonBody": "={\"loan_id\": \"{{ $('Parse PA Fields').item.json.webhookBody.loan_id }}\", \"action\": \"pre_approval_email_drafted\", \"details\": \"Pre-approval email drafted in Outlook. Borrower: {{ $('Parse PA Fields').item.json.full_name }}. Purchase price: {{ $('Parse PA Fields').item.json.purchase_price }}. Loan type: {{ $('Parse PA Fields').item.json.loan_type }}.\"}"
},
"id": "log-activity",
"name": "Log PA Email",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
1980,
300
],
"credentials": {
"httpHeaderAuth": {
"name": "<your credential>"
}
}
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Is Pre-Approval?",
"type": "main",
"index": 0
}
]
]
},
"Is Pre-Approval?": {
"main": [
[
{
"node": "Download PDF",
"type": "main",
"index": 0
}
],
[]
]
},
"Download PDF": {
"main": [
[
{
"node": "Build Claude Request",
"type": "main",
"index": 0
}
]
]
},
"Build Claude Request": {
"main": [
[
{
"node": "Call Claude API",
"type": "main",
"index": 0
}
]
]
},
"Call Claude API": {
"main": [
[
{
"node": "Parse PA Fields",
"type": "main",
"index": 0
}
]
]
},
"Parse PA Fields": {
"main": [
[
{
"node": "Build PA Email",
"type": "main",
"index": 0
},
{
"node": "Update Loan Record",
"type": "main",
"index": 0
}
]
]
},
"Build PA Email": {
"main": [
[
{
"node": "Draft PA Email",
"type": "main",
"index": 0
}
]
]
},
"Draft PA Email": {
"main": [
[
{
"node": "Log PA Email",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
},
"staticData": null
}
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.
httpHeaderAuthmicrosoftOutlookOAuth2Api
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
LoanOS — Pre-Approval Email. Uses httpRequest, microsoftOutlook. Webhook trigger; 10 nodes.
Source: https://github.com/AStyer8345/loanos/blob/b68ee65b8ebcac9cc34df97c831527ee0c99cc2c/n8n-workflows/pre-approval-email.json — 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.
Hectelion | Evaluation d'entreprise. Uses googleDrive, httpRequest, microsoftOutlook, googleSheets. Webhook trigger; 64 nodes.
Hectelion | NDA. Uses googleSheets, googleDrive, httpRequest, microsoftOutlook. Webhook trigger; 50 nodes.
This workflow listens for DocuSign Connect envelope-completed events, looks up the related assessment in Supabase, updates contract and client records, sends a welcome email (optionally drafted with A
This workflow connects Salesforce and Geotab to streamline fleet tracking for field service jobs (Work Orders). When a new Work Order is created in Salesforce (with a 'New' status and valid coordinate
This template is built for consultants, agencies, and service businesses that quote custom engagements and want to eliminate the manual work of building, formatting, and delivering pricing proposals.