This workflow corresponds to n8n.io template #13725 — we link there as the canonical source.
This workflow follows the Emailsend → HTTP Request 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": "jztwkBCtrmbaV357",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "AI Financial Report Analyzer",
"tags": [],
"nodes": [
{
"id": "fa3d6986-029c-4604-b411-018d91531334",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-320,
-64
],
"parameters": {
"width": 920,
"height": 850,
"content": "## AI Financial Report Analyzer\n\nAutomates financial data analysis and generates executive summaries with AI-powered insights, anomaly detection, and management recommendations.\n\n## How it works\n\n1. **Trigger** \u2014 Runs monthly on the 1st at 8 AM to analyze financial data\n2. **Extract** \u2014 Fetches P&L statements, balance sheets, cash flow data from accounting systems\n3. **Normalize** \u2014 Standardizes formats and validates data integrity\n4. **Analyze** \u2014 Calculates KPIs, financial ratios, YoY/MoM trends\n5. **Detect** \u2014 Identifies anomalies, trends, and unusual patterns\n6. **Insights** \u2014 Uses AI to generate natural language summaries and management recommendations\n7. **Generate** \u2014 Creates professional PDF/HTML reports with visualizations\n8. **Distribute** \u2014 Sends to stakeholders via Email, Slack, and stores in document management\n\n## Setup steps\n\n1. **Accounting APIs** \u2014 Connect QuickBooks, Xero, SAP, or financial database\n2. **Data Validation** \u2014 Configure field mappings and normalization rules\n3. **AI/LLM** \u2014 Set up OpenAI or Claude API for insights generation\n4. **PDF Generation** \u2014 Configure report styling and layouts\n5. **Database** \u2014 Create tables for reports, metrics, and historical data\n6. **Distribution** \u2014 Add Slack webhooks, SMTP, OneDrive/Google Drive credentials\n7. **Test** \u2014 Validate with sample financial data, then activate"
},
"typeVersion": 1
},
{
"id": "23b8cef1-684a-4b1a-87f9-6bff9e1b6853",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
800,
96
],
"parameters": {
"color": 3,
"width": 520,
"height": 882,
"content": "## 1. Trigger & Extract Data\n\nMonthly schedule and fetch financial statements from accounting systems"
},
"typeVersion": 1
},
{
"id": "ac588f16-6d13-438b-8ed4-0eced4a8258b",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1344,
176
],
"parameters": {
"color": 3,
"width": 376,
"height": 642,
"content": "## 2. Data Normalization & Validation\n\nStandardize formats and calculate financial metrics & ratios"
},
"typeVersion": 1
},
{
"id": "e95b2ae4-4412-4ffc-b1bc-f66705a08392",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1744,
176
],
"parameters": {
"color": 3,
"width": 408,
"height": 650,
"content": "## 3. Analysis & Anomaly Detection\n\nDetect trends, analyze variance, and identify unusual patterns"
},
"typeVersion": 1
},
{
"id": "390d4191-07c1-448e-a44b-08fb019eb14d",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2192,
144
],
"parameters": {
"color": 3,
"width": 416,
"height": 678,
"content": "## 4. AI Insights & Report Generation\n\nGenerate executive summaries and professional reports with visualizations"
},
"typeVersion": 1
},
{
"id": "165661f0-6e1f-41de-a766-8036adfae0a2",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
2656,
160
],
"parameters": {
"color": 3,
"width": 672,
"height": 662,
"content": "## 5. Distribution & Notification\n\nSend reports to stakeholders and store for historical tracking"
},
"typeVersion": 1
},
{
"id": "575a55b8-8934-49d1-bee6-6fa1c9d71dfc",
"name": "Monthly analysis on 1st at 8 AM",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
896,
528
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 1 * *"
}
]
}
},
"typeVersion": 1.2
},
{
"id": "8ed15a21-42ed-49f6-9fcd-bbfc354da12d",
"name": "Fetch P&L statement",
"type": "n8n-nodes-base.httpRequest",
"position": [
1120,
240
],
"parameters": {
"url": "https://api.accounting.example.com/financial/income-statement",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "d47ff1e3-00de-4315-ac5e-b2cad509911d",
"name": "Fetch balance sheet",
"type": "n8n-nodes-base.httpRequest",
"position": [
1120,
432
],
"parameters": {
"url": "https://api.accounting.example.com/financial/balance-sheet",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "35dc354f-bca6-42ec-a9c3-fa5051be8735",
"name": "Fetch cash flow statement",
"type": "n8n-nodes-base.httpRequest",
"position": [
1120,
624
],
"parameters": {
"url": "https://api.accounting.example.com/financial/cash-flow",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "70c8bc63-01e0-4f90-92d3-69a880c68154",
"name": "Fetch previous period data for comparison",
"type": "n8n-nodes-base.httpRequest",
"position": [
1120,
816
],
"parameters": {
"url": "https://api.accounting.example.com/financial/historical",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "232f5f9e-6fd7-4bb9-a133-3578fd459b48",
"name": "Merge all financial statements",
"type": "n8n-nodes-base.merge",
"position": [
1344,
528
],
"parameters": {
"mode": "combine",
"options": {}
},
"typeVersion": 3
},
{
"id": "9e0a3cfb-9abf-4c63-b4b6-e69d4e17c778",
"name": "Normalize and validate financial data",
"type": "n8n-nodes-base.code",
"position": [
1568,
528
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Normalize and validate financial data\nconst data = $input.item.json;\n\n// Extract financial statements\nconst incomeStatement = data.income_statement || {};\nconst balanceSheet = data.balance_sheet || {};\nconst cashFlow = data.cash_flow || {};\nconst previous = data.previous_period || {};\n\nconst currentDate = new Date();\nconst reportMonth = currentDate.toLocaleString('en-US', { month: 'long', year: 'numeric' });\nconst reportId = `FRA-${currentDate.getFullYear()}-M${String(currentDate.getMonth() + 1).padStart(2, '0')}`;\nconst timestamp = currentDate.toISOString();\n\n// --- P&L Metrics ---\nconst revenue = incomeStatement.total_revenue || 0;\nconst costOfRevenue = incomeStatement.cost_of_revenue || 0;\nconst grossProfit = revenue - costOfRevenue;\nconst grossMargin = revenue > 0 ? (grossProfit / revenue * 100) : 0;\nconst operatingExpenses = incomeStatement.operating_expenses || 0;\nconst operatingIncome = grossProfit - operatingExpenses;\nconst operatingMargin = revenue > 0 ? (operatingIncome / revenue * 100) : 0;\nconst netIncome = incomeStatement.net_income || 0;\nconst netMargin = revenue > 0 ? (netIncome / revenue * 100) : 0;\nconst ebitda = incomeStatement.ebitda || operatingIncome + (incomeStatement.depreciation || 0);\n\n// --- Balance Sheet Metrics ---\nconst totalAssets = balanceSheet.total_assets || 0;\nconst totalLiabilities = balanceSheet.total_liabilities || 0;\nconst totalEquity = balanceSheet.total_equity || 0;\nconst currentAssets = balanceSheet.current_assets || 0;\nconst currentLiabilities = balanceSheet.current_liabilities || 0;\nconst cashAndEquivalents = balanceSheet.cash || 0;\nconst accountsReceivable = balanceSheet.accounts_receivable || 0;\nconst inventory = balanceSheet.inventory || 0;\nconst fixedAssets = balanceSheet.fixed_assets || 0;\nconst longTermDebt = balanceSheet.long_term_debt || 0;\n\n// --- Cash Flow Metrics ---\nconst operatingCashFlow = cashFlow.operating_cash_flow || 0;\nconst investingCashFlow = cashFlow.investing_cash_flow || 0;\nconst financingCashFlow = cashFlow.financing_cash_flow || 0;\nconst freeCashFlow = operatingCashFlow - (cashFlow.capital_expenditures || 0);\n\n// --- Financial Ratios ---\nconst currentRatio = currentLiabilities > 0 ? (currentAssets / currentLiabilities).toFixed(2) : 'N/A';\nconst quickRatio = currentLiabilities > 0 ? ((currentAssets - inventory) / currentLiabilities).toFixed(2) : 'N/A';\nconst debtToEquity = totalEquity > 0 ? (totalLiabilities / totalEquity).toFixed(2) : 'N/A';\nconst debtToAssets = totalAssets > 0 ? (totalLiabilities / totalAssets * 100).toFixed(2) : 'N/A';\nconst returnOnAssets = totalAssets > 0 ? (netIncome / totalAssets * 100).toFixed(2) : 'N/A';\nconst returnOnEquity = totalEquity > 0 ? (netIncome / totalEquity * 100).toFixed(2) : 'N/A';\nconst assetTurnover = revenue > 0 && totalAssets > 0 ? (revenue / totalAssets).toFixed(2) : 'N/A';\nconst interestCoverage = incomeStatement.interest_expense > 0 ? (ebitda / incomeStatement.interest_expense).toFixed(2) : 'N/A';\n\n// --- YoY/MoM Comparison ---\nconst prevRevenue = previous.revenue || revenue;\nconst prevNetIncome = previous.net_income || netIncome;\nconst prevTotalAssets = previous.total_assets || totalAssets;\n\nconst revenueChange = prevRevenue > 0 ? ((revenue - prevRevenue) / prevRevenue * 100).toFixed(2) : 0;\nconst incomeChange = prevNetIncome !== 0 ? ((netIncome - prevNetIncome) / Math.abs(prevNetIncome) * 100).toFixed(2) : 0;\nconst assetChange = prevTotalAssets > 0 ? ((totalAssets - prevTotalAssets) / prevTotalAssets * 100).toFixed(2) : 0;\n\n// --- Working Capital & Cash Analysis ---\nconst workingCapital = currentAssets - currentLiabilities;\nconst cashConversionCycle = (accountsReceivable + inventory) > 0 ? Math.round((accountsReceivable + inventory) / (revenue / 365)) : 0;\nconst daysInventoryOutstanding = revenue > 0 ? Math.round((inventory / (costOfRevenue / 365))) : 0;\nconst daysReceivablesOutstanding = revenue > 0 ? Math.round((accountsReceivable / (revenue / 365))) : 0;\nconst freeCashFlowMargin = revenue > 0 ? (freeCashFlow / revenue * 100).toFixed(2) : 0;\n\n// --- Financial Health Score (0-100) ---\nlet healthScore = 50; // Base score\nif (currentRatio >= 1.5) healthScore += 10; // Good liquidity\nif (debtToEquity < 1) healthScore += 10; // Healthy leverage\nif (netMargin > 10) healthScore += 10; // Good profitability\nif (freeCashFlow > 0) healthScore += 10; // Positive FCF\nif (revenueChange > 5) healthScore += 5; // Revenue growth\nif (returnOnEquity > 15) healthScore += 5; // Good ROE\nif (currentRatio < 1) healthScore -= 15; // Poor liquidity\nif (debtToEquity > 2) healthScore -= 15; // High leverage\nif (netMargin < 0) healthScore -= 20; // Unprofitable\nhealthScore = Math.max(0, Math.min(100, healthScore));\n\n// --- Health Category ---\nlet healthCategory = 'Excellent';\nif (healthScore < 30) healthCategory = 'Critical';\nelse if (healthScore < 50) healthCategory = 'Poor';\nelse if (healthScore < 70) healthCategory = 'Fair';\nelse if (healthScore < 85) healthCategory = 'Good';\n\nreturn {\n json: {\n // Report Identity\n reportId,\n reportMonth,\n timestamp,\n \n // P&L Statement\n revenue: Math.round(revenue),\n cost_of_revenue: Math.round(costOfRevenue),\n gross_profit: Math.round(grossProfit),\n gross_margin_percent: parseFloat(grossMargin.toFixed(2)),\n operating_expenses: Math.round(operatingExpenses),\n operating_income: Math.round(operatingIncome),\n operating_margin_percent: parseFloat(operatingMargin.toFixed(2)),\n ebitda: Math.round(ebitda),\n net_income: Math.round(netIncome),\n net_margin_percent: parseFloat(netMargin.toFixed(2)),\n \n // Balance Sheet\n total_assets: Math.round(totalAssets),\n total_liabilities: Math.round(totalLiabilities),\n total_equity: Math.round(totalEquity),\n current_assets: Math.round(currentAssets),\n current_liabilities: Math.round(currentLiabilities),\n cash_equivalents: Math.round(cashAndEquivalents),\n accounts_receivable: Math.round(accountsReceivable),\n inventory: Math.round(inventory),\n fixed_assets: Math.round(fixedAssets),\n long_term_debt: Math.round(longTermDebt),\n working_capital: Math.round(workingCapital),\n \n // Cash Flow\n operating_cash_flow: Math.round(operatingCashFlow),\n investing_cash_flow: Math.round(investingCashFlow),\n financing_cash_flow: Math.round(financingCashFlow),\n free_cash_flow: Math.round(freeCashFlow),\n free_cash_flow_margin_percent: parseFloat(freeCashFlowMargin),\n \n // Financial Ratios\n current_ratio: currentRatio,\n quick_ratio: quickRatio,\n debt_to_equity: debtToEquity,\n debt_to_assets_percent: debtToAssets,\n return_on_assets_percent: returnOnAssets,\n return_on_equity_percent: returnOnEquity,\n asset_turnover: assetTurnover,\n interest_coverage: interestCoverage,\n \n // Operational Metrics\n days_inventory_outstanding: daysInventoryOutstanding,\n days_receivables_outstanding: daysReceivablesOutstanding,\n cash_conversion_cycle_days: cashConversionCycle,\n \n // YoY/MoM Changes\n revenue_change_percent: parseFloat(revenueChange),\n net_income_change_percent: parseFloat(incomeChange),\n total_assets_change_percent: parseFloat(assetChange),\n \n // Health Score\n financial_health_score: healthScore,\n financial_health_category: healthCategory,\n \n // Original data\n original_data: data\n }\n};"
},
"typeVersion": 2
},
{
"id": "b27ded34-c82c-4c72-b3d5-f50c7612a1bc",
"name": "Analyze trends and detect anomalies",
"type": "n8n-nodes-base.code",
"position": [
1792,
528
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Analyze financial trends and detect anomalies\nconst data = $input.item.json;\n\n// --- Revenue Trend Analysis ---\nconst revenueTrend = data.revenue_change_percent > 5 ? 'Growing' \n : data.revenue_change_percent > 0 ? 'Stable Growth' \n : data.revenue_change_percent > -5 ? 'Minor Decline' \n : 'Significant Decline';\n\nconst marginTrend = data.operating_margin_percent > 15 ? 'Healthy' \n : data.operating_margin_percent > 5 ? 'Acceptable' \n : data.operating_margin_percent > 0 ? 'Weak' \n : 'Unprofitable';\n\n// --- Anomaly Detection ---\nconst anomalies = [];\nconst warnings = [];\nconst recommendations = [];\n\n// Liquidity anomalies\nif (parseFloat(data.current_ratio) < 1) {\n anomalies.push('Critical: Current ratio below 1.0 indicates potential liquidity crisis');\n recommendations.push('Improve short-term liquidity by increasing current assets or reducing current liabilities');\n}\nif (parseFloat(data.current_ratio) < 1.5) {\n warnings.push('Low current ratio may indicate tight working capital management');\n}\nif (data.cash_equivalents < data.current_liabilities * 0.2) {\n warnings.push('Cash reserves are low relative to current liabilities');\n}\n\n// Profitability anomalies\nif (data.net_margin_percent < 0) {\n anomalies.push('Critical: Company is unprofitable with negative net margin');\n recommendations.push('Review cost structure and operating expenses to achieve profitability');\n}\nif (data.net_margin_percent < 5 && data.revenue > 0) {\n warnings.push('Low net profit margin indicates thin profitability');\n}\nif (data.gross_margin_percent < 20) {\n warnings.push('Low gross margin suggests high cost of goods sold');\n recommendations.push('Analyze pricing strategy and COGS reduction opportunities');\n}\n\n// Leverage anomalies\nif (parseFloat(data.debt_to_equity) > 2) {\n anomalies.push('Critical: Debt-to-equity ratio exceeds 2.0, high financial risk');\n recommendations.push('Consider debt reduction or equity injection to strengthen balance sheet');\n}\nif (parseFloat(data.debt_to_equity) > 1.5) {\n warnings.push('High leverage may limit financial flexibility');\n}\n\n// Cash flow anomalies\nif (data.free_cash_flow < 0) {\n anomalies.push('Critical: Negative free cash flow unsustainable long-term');\n recommendations.push('Reduce capital expenditures or improve operating cash flow generation');\n}\nif (data.free_cash_flow < data.net_income * 0.5) {\n warnings.push('Free cash flow significantly lower than net income (quality of earnings concern)');\n recommendations.push('Investigate working capital changes and cash conversion efficiency');\n}\n\n// Growth vs. profitability\nif (data.revenue_change_percent > 10 && data.net_income_change_percent < data.revenue_change_percent - 5) {\n warnings.push('Revenue growth outpacing profit growth indicates margin pressure');\n recommendations.push('Monitor cost control and operational efficiency during growth phase');\n}\n\n// ROE anomalies\nif (parseFloat(data.return_on_equity_percent) < 10) {\n warnings.push('Return on equity below 10% suggests suboptimal capital efficiency');\n}\nif (parseFloat(data.return_on_equity_percent) > 30) {\n recommendations.push('Exceptional ROE - consider whether leverage is sustainable');\n}\n\n// Working capital issues\nif (data.cash_conversion_cycle_days > 90) {\n warnings.push('Long cash conversion cycle indicates working capital pressure');\n recommendations.push('Improve inventory turnover or accelerate receivables collection');\n}\n\n// Asset utilization\nif (parseFloat(data.asset_turnover) < 0.5) {\n warnings.push('Low asset turnover suggests inefficient use of assets');\n recommendations.push('Review asset base efficiency and consider divestments if needed');\n}\n\n// Interest coverage\nif (data.interest_coverage !== 'N/A' && parseFloat(data.interest_coverage) < 2) {\n anomalies.push('Low interest coverage ratio (< 2.0) indicates debt service risk');\n recommendations.push('Prioritize debt reduction or EBITDA improvement');\n}\n\n// Revenue stability check\nif (Math.abs(data.revenue_change_percent) > 20) {\n warnings.push('Large revenue variance from prior period warrants investigation');\n}\n\n// --- Key Strengths ---\nconst strengths = [];\nif (parseFloat(data.current_ratio) > 2) strengths.push('Strong liquidity position');\nif (data.net_margin_percent > 15) strengths.push('Excellent profit margins');\nif (parseFloat(data.debt_to_equity) < 0.5) strengths.push('Conservative debt levels');\nif (data.free_cash_flow > data.net_income) strengths.push('Strong cash generation');\nif (data.revenue_change_percent > 10) strengths.push('Robust revenue growth');\nif (parseFloat(data.return_on_equity_percent) > 20) strengths.push('Excellent return on equity');\n\n// --- Performance Rating ---\nlet performanceRating = 'Average';\nif (anomalies.length > 2) performanceRating = 'Poor';\nelse if (anomalies.length > 0 || warnings.length > 3) performanceRating = 'Below Average';\nelse if (warnings.length > 0) performanceRating = 'Average';\nelse if (strengths.length > 3) performanceRating = 'Strong';\nelse if (strengths.length > 5) performanceRating = 'Excellent';\n\nreturn {\n json: {\n ...data,\n \n // Trend Analysis\n revenue_trend: revenueTrend,\n margin_trend: marginTrend,\n \n // Anomalies & Warnings\n critical_anomalies: anomalies,\n anomaly_count: anomalies.length,\n warnings: warnings,\n warning_count: warnings.length,\n \n // Recommendations\n strategic_recommendations: recommendations,\n \n // Strengths\n key_strengths: strengths,\n strength_count: strengths.length,\n \n // Overall Assessment\n performance_rating: performanceRating,\n analysis_timestamp: new Date().toISOString()\n }\n};"
},
"typeVersion": 2
},
{
"id": "145cc376-6846-4a02-8d91-d2be55c6f62c",
"name": "Generate AI-powered insights",
"type": "n8n-nodes-base.httpRequest",
"position": [
2016,
528
],
"parameters": {
"url": "https://api.openai.com/v1/chat/completions",
"method": "POST",
"options": {},
"sendBody": true,
"bodyParameters": {
"parameters": [
{
"name": "model",
"value": "gpt-4o-mini"
},
{
"name": "messages",
"value": "=[{\"role\": \"system\", \"content\": \"You are a financial analyst expert. Generate concise, executive-level financial insights based on the provided data.\"}, {\"role\": \"user\", \"content\": \"Analyze this financial data and provide 3-4 key insights:\\n\\nRevenue: $\" + $json.revenue + \"\\nNet Income: $\" + $json.net_income + \"\\nNet Margin: \" + $json.net_margin_percent + \"%\\nCash Flow: $\" + $json.free_cash_flow + \"\\nDebt/Equity: \" + $json.debt_to_equity + \"\\nHealth Score: \" + $json.financial_health_score + \"/100\\n\\nAnomalies: \" + $json.critical_anomalies.join(', ') + \"\\nRecommendations: \" + $json.strategic_recommendations.join(', ') + \"\"}]"
},
{
"name": "temperature",
"value": "0.7"
},
{
"name": "max_tokens",
"value": "500"
}
]
}
},
"typeVersion": 4.2
},
{
"id": "d281d367-1a9b-45c9-a7ee-4851da626664",
"name": "Extract and format AI insights",
"type": "n8n-nodes-base.code",
"position": [
2240,
528
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Extract AI insights from API response\nconst response = $input.item.json;\nconst data = $input.item.json.original_data || {};\n\nlet aiInsights = '';\nif (response.choices && response.choices.length > 0) {\n aiInsights = response.choices[0].message.content;\n}\n\nconst executiveSummary = `\nFINANCIAL PERFORMANCE SUMMARY (${data.reportMonth}):\n\n\ud83c\udfaf KEY METRICS:\n- Total Revenue: $${(data.revenue / 1000000).toFixed(1)}M (${data.revenue_change_percent > 0 ? '+' : ''}${data.revenue_change_percent}% YoY)\n- Net Income: $${(data.net_income / 1000000).toFixed(1)}M\n- Operating Margin: ${data.operating_margin_percent.toFixed(1)}%\n- Free Cash Flow: $${(data.free_cash_flow / 1000000).toFixed(1)}M\n- Financial Health Score: ${data.financial_health_score}/100 (${data.financial_health_category})\n\n\ud83d\udcca BALANCE SHEET STRENGTH:\n- Current Ratio: ${data.current_ratio} (Liquidity)\n- Debt-to-Equity: ${data.debt_to_equity} (Leverage)\n- Return on Equity: ${data.return_on_equity_percent}%\n- Working Capital: $${(data.working_capital / 1000000).toFixed(1)}M\n\n\ud83d\udea8 CRITICAL ITEMS (${data.anomaly_count}):\n${data.critical_anomalies.length > 0 ? data.critical_anomalies.map(a => '- ' + a).join('\\n') : '- No critical anomalies detected'}\n\n\u26a0\ufe0f WARNINGS (${data.warning_count}):\n${data.warnings.length > 0 ? data.warnings.map(w => '- ' + w).join('\\n') : '- No warnings'}\n\n\ud83d\udcaa STRENGTHS (${data.strength_count}):\n${data.key_strengths.length > 0 ? data.key_strengths.map(s => '- ' + s).join('\\n') : '- Standard performance'}\n\n\ud83c\udfaf STRATEGIC RECOMMENDATIONS:\n${data.strategic_recommendations.length > 0 ? data.strategic_recommendations.map(r => '- ' + r).join('\\n') : '- No immediate actions required'}\n\n\ud83e\udd16 AI ANALYSIS:\n${aiInsights}\n`;\n\nreturn {\n json: {\n ...data,\n ai_insights: aiInsights,\n executive_summary: executiveSummary,\n summary_generated: true\n }\n};"
},
"typeVersion": 2
},
{
"id": "9a54d6f7-4178-4302-b38d-6466b9ff38c2",
"name": "Generate professional HTML report",
"type": "n8n-nodes-base.code",
"position": [
2464,
528
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Generate professional HTML report\nconst data = $input.item.json;\n\nconst healthColor = data.financial_health_category === 'Excellent' ? '#22c55e' \n : data.financial_health_category === 'Good' ? '#84cc16' \n : data.financial_health_category === 'Fair' ? '#f59e0b' \n : data.financial_health_category === 'Poor' ? '#ef4444' \n : '#6b7280';\n\nconst healthIcon = data.financial_health_category === 'Excellent' ? '\u2b50\u2b50\u2b50' \n : data.financial_health_category === 'Good' ? '\u2b50\u2b50' \n : data.financial_health_category === 'Fair' ? '\u2b50' \n : '\u274c';\n\nconst reportHtml = `\n<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n <meta charset=\"UTF-8\">\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">\n <title>Financial Report - ${data.reportMonth}</title>\n <style>\n * { margin: 0; padding: 0; box-sizing: border-box; }\n body { font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; color: #1f2937; background: #f3f4f6; }\n .container { max-width: 1200px; margin: 0 auto; padding: 20px; }\n .header { background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); color: white; padding: 40px; border-radius: 12px; margin-bottom: 30px; }\n .header h1 { font-size: 32px; margin-bottom: 10px; }\n .header p { opacity: 0.9; font-size: 14px; }\n .metrics-grid { display: grid; grid-template-columns: repeat(4, 1fr); gap: 20px; margin-bottom: 30px; }\n .metric-card { background: white; padding: 20px; border-radius: 8px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }\n .metric-value { font-size: 32px; font-weight: bold; color: #667eea; margin-bottom: 5px; }\n .metric-label { font-size: 12px; color: #6b7280; text-transform: uppercase; letter-spacing: 0.5px; }\n .metric-change { font-size: 12px; margin-top: 5px; padding: 4px 8px; border-radius: 4px; display: inline-block; }\n .metric-change.positive { background: #d1fae5; color: #047857; }\n .metric-change.negative { background: #fee2e2; color: #dc2626; }\n .section { background: white; padding: 30px; border-radius: 8px; margin-bottom: 20px; box-shadow: 0 2px 8px rgba(0,0,0,0.1); }\n .section h2 { font-size: 18px; margin-bottom: 20px; padding-bottom: 15px; border-bottom: 2px solid #e5e7eb; }\n .health-badge { display: inline-block; padding: 12px 24px; border-radius: 8px; background: ${healthColor}; color: white; font-weight: bold; margin: 10px 0; }\n .alert { padding: 15px; margin: 10px 0; border-radius: 6px; border-left: 4px solid; }\n .alert-critical { background: #fee2e2; border-color: #dc2626; color: #991b1b; }\n .alert-warning { background: #fef3c7; border-color: #f59e0b; color: #92400e; }\n .alert-success { background: #d1fae5; border-color: #10b981; color: #065f46; }\n table { width: 100%; border-collapse: collapse; margin-top: 15px; }\n th { background: #f3f4f6; padding: 12px; text-align: left; font-size: 12px; font-weight: 600; text-transform: uppercase; border-bottom: 2px solid #e5e7eb; }\n td { padding: 12px; border-bottom: 1px solid #e5e7eb; }\n .footer { text-align: center; padding: 20px; color: #6b7280; font-size: 12px; margin-top: 40px; }\n .footer p { margin: 5px 0; }\n </style>\n</head>\n<body>\n <div class=\"container\">\n <div class=\"header\">\n <h1>Financial Report</h1>\n <p>Executive Summary for ${data.reportMonth}</p>\n <p>Report ID: ${data.reportId}</p>\n </div>\n\n <div class=\"metrics-grid\">\n <div class=\"metric-card\">\n <div class=\"metric-value\">\\$${(data.revenue / 1000000).toFixed(1)}M</div>\n <div class=\"metric-label\">Total Revenue</div>\n <div class=\"metric-change ${data.revenue_change_percent > 0 ? 'positive' : 'negative'}\">${data.revenue_change_percent > 0 ? '+' : ''}${data.revenue_change_percent}% YoY</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-value\">\\$${(data.net_income / 1000000).toFixed(1)}M</div>\n <div class=\"metric-label\">Net Income</div>\n <div class=\"metric-change ${data.net_income_change_percent > 0 ? 'positive' : 'negative'}\">${data.net_income_change_percent > 0 ? '+' : ''}${data.net_income_change_percent}%</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-value\">${data.net_margin_percent.toFixed(1)}%</div>\n <div class=\"metric-label\">Net Margin</div>\n <div class=\"metric-change ${data.net_margin_percent > 10 ? 'positive' : 'warning'}\">Operating Health</div>\n </div>\n <div class=\"metric-card\">\n <div class=\"metric-value\">\\$${(data.free_cash_flow / 1000000).toFixed(1)}M</div>\n <div class=\"metric-label\">Free Cash Flow</div>\n <div class=\"metric-change ${data.free_cash_flow > 0 ? 'positive' : 'negative'}\">Cash Generation</div>\n </div>\n </div>\n\n <div class=\"section\">\n <h2>\ud83d\udcca Financial Health Assessment</h2>\n <div class=\"health-badge\">${healthIcon} ${data.financial_health_category} (Score: ${data.financial_health_score}/100)</div>\n <table>\n <tr><td><strong>Current Ratio</strong></td><td>${data.current_ratio} (Liquidity)</td></tr>\n <tr><td><strong>Debt-to-Equity</strong></td><td>${data.debt_to_equity} (Leverage)</td></tr>\n <tr><td><strong>Return on Equity</strong></td><td>${data.return_on_equity_percent}% (ROE)</td></tr>\n <tr><td><strong>Asset Turnover</strong></td><td>${data.asset_turnover}x</td></tr>\n <tr><td><strong>Working Capital</strong></td><td>\\$${(data.working_capital / 1000000).toFixed(1)}M</td></tr>\n </table>\n </div>\n\n ${data.critical_anomalies.length > 0 ? `\n <div class=\"section\">\n <h2>\ud83d\udea8 Critical Anomalies (${data.anomaly_count})</h2>\n ${data.critical_anomalies.map(a => `<div class=\"alert alert-critical\">\u26a0\ufe0f ${a}</div>`).join('')}\n </div>\n ` : ''}\n\n ${data.warnings.length > 0 ? `\n <div class=\"section\">\n <h2>\u26a0\ufe0f Warnings & Observations (${data.warning_count})</h2>\n ${data.warnings.map(w => `<div class=\"alert alert-warning\">\ud83d\udccc ${w}</div>`).join('')}\n </div>\n ` : ''}\n\n ${data.key_strengths.length > 0 ? `\n <div class=\"section\">\n <h2>\ud83d\udcaa Key Strengths (${data.strength_count})</h2>\n ${data.key_strengths.map(s => `<div class=\"alert alert-success\">\u2713 ${s}</div>`).join('')}\n </div>\n ` : ''}\n\n <div class=\"section\">\n <h2>\ud83c\udfaf Strategic Recommendations</h2>\n <ol style=\"margin-left: 20px; line-height: 1.8;\">\n ${data.strategic_recommendations.length > 0 ? data.strategic_recommendations.map(r => `<li>${r}</li>`).join('') : '<li>Continue monitoring financial metrics quarterly</li>'}\n </ol>\n </div>\n\n <div class=\"section\">\n <h2>\ud83e\udd16 AI-Powered Analysis</h2>\n <p style=\"line-height: 1.6; white-space: pre-wrap; color: #4b5563;\">${data.ai_insights}</p>\n </div>\n\n <div class=\"section\">\n <h2>\ud83d\udcc8 Detailed Metrics</h2>\n <table>\n <thead>\n <tr><th>Metric</th><th>Value</th></tr>\n </thead>\n <tbody>\n <tr><td>Gross Profit</td><td>\\$${(data.gross_profit / 1000000).toFixed(1)}M</td></tr>\n <tr><td>Gross Margin</td><td>${data.gross_margin_percent.toFixed(1)}%</td></tr>\n <tr><td>Operating Income</td><td>\\$${(data.operating_income / 1000000).toFixed(1)}M</td></tr>\n <tr><td>EBITDA</td><td>\\$${(data.ebitda / 1000000).toFixed(1)}M</td></tr>\n <tr><td>Operating Cash Flow</td><td>\\$${(data.operating_cash_flow / 1000000).toFixed(1)}M</td></tr>\n <tr><td>Days Receivables Outstanding</td><td>${data.days_receivables_outstanding} days</td></tr>\n <tr><td>Days Inventory Outstanding</td><td>${data.days_inventory_outstanding} days</td></tr>\n <tr><td>Cash Conversion Cycle</td><td>${data.cash_conversion_cycle_days} days</td></tr>\n <tr><td>Total Assets</td><td>\\$${(data.total_assets / 1000000).toFixed(1)}M</td></tr>\n <tr><td>Total Liabilities</td><td>\\$${(data.total_liabilities / 1000000).toFixed(1)}M</td></tr>\n <tr><td>Total Equity</td><td>\\$${(data.total_equity / 1000000).toFixed(1)}M</td></tr>\n </tbody>\n </table>\n </div>\n\n <div class=\"footer\">\n <p><strong>AI Financial Report Analyzer</strong></p>\n <p>Generated: ${data.timestamp}</p>\n <p>This report is for management review and decision-making purposes</p>\n </div>\n </div>\n</body>\n</html>\n`;\n\nreturn {\n json: {\n ...data,\n report_html: reportHtml,\n report_generated: true,\n report_title: `Financial Report - ${data.reportMonth}`,\n report_size_kb: Math.round(reportHtml.length / 1024)\n }\n};"
},
"typeVersion": 2
},
{
"id": "abdb8991-a0f3-4fef-aa36-c62a80fab38e",
"name": "Store report in database",
"type": "n8n-nodes-base.postgres",
"position": [
2688,
528
],
"parameters": {
"table": "financial_reports",
"schema": {
"__rl": true,
"mode": "list",
"value": "public"
},
"columns": {
"value": {},
"schema": [],
"mappingMode": "autoMapInputData",
"matchingColumns": [],
"attemptToConvertTypes": false,
"convertFieldsToString": false
},
"options": {}
},
"credentials": {
"postgres": {
"name": "<your credential>"
}
},
"typeVersion": 2.5
},
{
"id": "b67b4383-3cb0-45ac-bb00-19eb5763bba4",
"name": "Post report summary to Slack",
"type": "n8n-nodes-base.httpRequest",
"position": [
2912,
432
],
"parameters": {
"url": "YOUR_SLACK_WEBHOOK_URL",
"method": "POST",
"options": {},
"jsonBody": "={\n \"text\": \"\ud83d\udcca Monthly Financial Report - {{ $json.reportMonth }}\",\n \"blocks\": [\n {\n \"type\": \"section\",\n \"text\": {\n \"type\": \"mrkdwn\",\n \"text\": \"*Financial Report for {{ $json.reportMonth }}*\\n\\n\ud83d\udcb0 *Revenue:* ${{ ($json.revenue / 1000000).toFixed(1) }}M ({{ $json.revenue_change_percent > 0 ? '+' : '' }}{{ $json.revenue_change_percent }}% YoY)\\n\ud83d\udcb5 *Net Income:* ${{ ($json.net_income / 1000000).toFixed(1) }}M\\n\ud83d\udcc8 *Net Margin:* {{ $json.net_margin_percent.toFixed(1) }}%\\n\ud83d\udcb8 *Free Cash Flow:* ${{ ($json.free_cash_flow / 1000000).toFixed(1) }}M\\n\u2b50 *Health Score:* {{ $json.financial_health_score }}/100 ({{ $json.financial_health_category }})\\n\\n\ud83c\udfaf *Performance:* {{ $json.performance_rating }}\\n\ud83d\udea8 *Anomalies:* {{ $json.anomaly_count }}\\n\u26a0\ufe0f *Warnings:* {{ $json.warning_count }}\"\n }\n }\n ]\n}",
"sendBody": true,
"specifyBody": "json"
},
"typeVersion": 4.2
},
{
"id": "9baeaf5c-5030-4215-8199-ca0302039cdd",
"name": "Email report to management",
"type": "n8n-nodes-base.emailSend",
"position": [
2912,
624
],
"parameters": {
"html": "={{ $json.report_html }}",
"options": {},
"subject": "{{ $json.report_title }}",
"toEmail": "user@example.com",
"fromEmail": "noreply@example.com"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "cfbdf0ec-94f2-41b5-8c62-d0bfade59083",
"name": "Log report generation completion",
"type": "n8n-nodes-base.code",
"position": [
3136,
528
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "// Log report completion and track statistics\nconst timestamp = new Date().toISOString();\nconst data = $input.item.json;\n\nconsole.log(`\u2705 FINANCIAL REPORT GENERATED: ${data.reportId} | Month: ${data.reportMonth} | Revenue: $${(data.revenue/1000000).toFixed(1)}M | Health: ${data.financial_health_score}/100 | Status: ${data.performance_rating} | Time: ${timestamp}`);\n\n// Aggregate statistics\nconst stats = $getWorkflowStaticData('global').stats || {\n total_reports_generated: 0,\n avg_revenue: 0,\n avg_net_margin: 0,\n avg_health_score: 0,\n critical_months: 0,\n excellent_months: 0,\n total_anomalies: 0,\n last_generated: null\n};\n\nstats.total_reports_generated++;\nstats.avg_revenue = ((stats.avg_revenue * (stats.total_reports_generated - 1)) + data.revenue) / stats.total_reports_generated;\nstats.avg_net_margin = ((stats.avg_net_margin * (stats.total_reports_generated - 1)) + data.net_margin_percent) / stats.total_reports_generated;\nstats.avg_health_score = ((stats.avg_health_score * (stats.total_reports_generated - 1)) + data.financial_health_score) / stats.total_reports_generated;\nif (data.financial_health_category === 'Critical') stats.critical_months++;\nif (data.financial_health_category === 'Excellent') stats.excellent_months++;\nstats.total_anomalies += data.anomaly_count;\nstats.last_generated = timestamp;\n\n$getWorkflowStaticData('global').stats = stats;\n\nreturn {\n json: {\n success: true,\n report_id: data.reportId,\n month: data.reportMonth,\n revenue: data.revenue,\n health_score: data.financial_health_score,\n health_category: data.financial_health_category,\n performance_rating: data.performance_rating,\n anomalies: data.anomaly_count,\n warnings: data.warning_count,\n timestamp,\n cumulativeStats: stats\n }\n};"
},
"typeVersion": 2
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "8bb8c85c-5b9d-4e56-8673-f03c1f259acf",
"connections": {
"Fetch P&L statement": {
"main": [
[
{
"node": "Merge all financial statements",
"type": "main",
"index": 0
}
]
]
},
"Fetch balance sheet": {
"main": [
[
{
"node": "Merge all financial statements",
"type": "main",
"index": 1
}
]
]
},
"Store report in database": {
"main": [
[
{
"node": "Post report summary to Slack",
"type": "main",
"index": 0
},
{
"node": "Email report to management",
"type": "main",
"index": 0
}
]
]
},
"Fetch cash flow statement": {
"main": [
[
{
"node": "Merge all financial statements",
"type": "main",
"index": 0
}
]
]
},
"Email report to management": {
"main": [
[
{
"node": "Log report generation completion",
"type": "main",
"index": 0
}
]
]
},
"Generate AI-powered insights": {
"main": [
[
{
"node": "Extract and format AI insights",
"type": "main",
"index": 0
}
]
]
},
"Post report summary to Slack": {
"main": [
[
{
"node": "Log report generation completion",
"type": "main",
"index": 0
}
]
]
},
"Extract and format AI insights": {
"main": [
[
{
"node": "Generate professional HTML report",
"type": "main",
"index": 0
}
]
]
},
"Merge all financial statements": {
"main": [
[
{
"node": "Normalize and validate financial data",
"type": "main",
"index": 0
}
]
]
},
"Monthly analysis on 1st at 8 AM": {
"main": [
[
{
"node": "Fetch P&L statement",
"type": "main",
"index": 0
},
{
"node": "Fetch balance sheet",
"type": "main",
"index": 0
},
{
"node": "Fetch cash flow statement",
"type": "main",
"index": 0
},
{
"node": "Fetch previous period data for comparison",
"type": "main",
"index": 0
}
]
]
},
"Generate professional HTML report": {
"main": [
[
{
"node": "Store report in database",
"type": "main",
"index": 0
}
]
]
},
"Analyze trends and detect anomalies": {
"main": [
[
{
"node": "Generate AI-powered insights",
"type": "main",
"index": 0
}
]
]
},
"Normalize and validate financial data": {
"main": [
[
{
"node": "Analyze trends and detect anomalies",
"type": "main",
"index": 0
}
]
]
},
"Fetch previous period data for comparison": {
"main": [
[
{
"node": "Merge all financial statements",
"type": "main",
"index": 1
}
]
]
}
}
}
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.
postgressmtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This n8n workflow automatically fetches monthly financial statements, normalizes the data, performs KPI calculations and trend analysis, detects anomalies, generates AI-powered executive insights and recommendations, creates professional reports, and distributes them to…
Source: https://n8n.io/workflows/13725/ — 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.
This n8n workflow automates the monitoring of warehouse inventory and sales velocity to predict demand, generate purchase orders automatically, send them to suppliers, and record all transactions in E
Use cases are many: Automate your personal trading strategy, monitor a portfolio for significant trend changes, or provide automated analysis highlights for a trading community or client group.
Who is this for? Event organizers losing 80% of form starters who never finish registration and want automated follow-up emails triggered by abandonment beacons. What problem is this workflow solving?
n8n_email_diario_sem_ollama_fixed. Uses httpRequest, emailSend. Scheduled trigger; 10 nodes.
Weekly Documentation Update. Uses executeCommand, httpRequest, emailSend. Scheduled trigger; 8 nodes.