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": "extraction-automation",
"nodes": [
{
"parameters": {
"httpMethod": "POST",
"path": "/ingest-file",
"responseMode": "responseNode",
"options": {
"binaryPropertyName": "file"
}
},
"type": "n8n-nodes-base.webhook",
"typeVersion": 2.1,
"position": [
-368,
-816
],
"id": "05e853fd-3056-45fe-8297-64f6a4b23622",
"name": "Webhook"
},
{
"parameters": {
"assignments": {
"assignments": [
{
"id": "105f5d55-5c1c-47f0-bd6a-14121a90d600",
"name": "File Name",
"value": "={{$binary.file0.fileName}}",
"type": "string"
},
{
"id": "5db364a7-675b-4a66-86aa-86f0e3b1fef3",
"name": "Mime Type",
"value": "={{$binary.file0.mimeType}}",
"type": "string"
},
{
"id": "8095b594-6dce-48c5-9b07-5881a4c87ca5",
"name": "File Size",
"value": "={{$binary.file0.fileSize}}",
"type": "string"
},
{
"id": "841ccb3b-8111-4f11-97ec-382baf848e08",
"name": "isBinary",
"value": "={{!!$binary.file0}}",
"type": "string"
}
]
},
"includeOtherFields": true,
"options": {}
},
"type": "n8n-nodes-base.set",
"typeVersion": 3.4,
"position": [
-144,
-816
],
"id": "c2970f8c-5f5a-48e5-bfc5-a573554889ed",
"name": "Edit Fields"
},
{
"parameters": {
"respondWith": "json",
"responseBody": "{\n \"status\": \"400\",\n \"message\": \"Unsupported file type\"\n}",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
864,
-112
],
"id": "91accdd5-1791-41ac-948e-16a5664d102b",
"name": "Respond to Webhook"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "e7acff39-3107-473e-b2d3-d51e65ae0877",
"leftValue": "={{ $json['File Name'] }}",
"rightValue": ".xlsx",
"operator": {
"type": "string",
"operation": "endsWith"
}
},
{
"id": "685323a6-545b-482e-a2e0-4cb87e9b654f",
"leftValue": "={{ $json['Mime Type'] }}",
"rightValue": "spreadsheet",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "or"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
528,
-816
],
"id": "5dccd18a-5331-42c9-8ed1-d889475f3be0",
"name": "If - .xlsx"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "5196ac4d-dc2b-418f-9cd7-d198b5479786",
"leftValue": "={{ $('Edit Fields').item.json['File Name'] }}",
"rightValue": ".csv",
"operator": {
"type": "string",
"operation": "endsWith"
}
}
],
"combinator": "or"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
512,
-624
],
"id": "2a3052f0-7306-40d0-94d3-c7bf7d45ac90",
"name": "If- .csv"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "5196ac4d-dc2b-418f-9cd7-d198b5479786",
"leftValue": "={{ $('Edit Fields').item.json['File Name'] }}",
"rightValue": ".docx",
"operator": {
"type": "string",
"operation": "endsWith"
}
},
{
"id": "82b86833-71b6-490c-8fb5-dc8cbba54f4a",
"leftValue": "={{ $('Edit Fields').item.json['Mime Type'] }}",
"rightValue": "wordprocessingml",
"operator": {
"type": "string",
"operation": "contains"
}
}
],
"combinator": "or"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
528,
-368
],
"id": "dd4c9f6e-8257-4906-8fe4-92279101cf0d",
"name": "If- .docx"
},
{
"parameters": {
"conditions": {
"options": {
"caseSensitive": true,
"leftValue": "",
"typeValidation": "strict",
"version": 3
},
"conditions": [
{
"id": "5196ac4d-dc2b-418f-9cd7-d198b5479786",
"leftValue": "={{ $('Edit Fields').item.json['File Name'] }}",
"rightValue": ".pdf",
"operator": {
"type": "string",
"operation": "endsWith"
}
}
],
"combinator": "and"
},
"options": {}
},
"type": "n8n-nodes-base.if",
"typeVersion": 2.3,
"position": [
528,
-128
],
"id": "1cd84799-ec83-455d-8150-a857f265861e",
"name": "If- .pdf"
},
{
"parameters": {
"operation": "xlsx",
"binaryPropertyName": "file0",
"options": {
"headerRow": true,
"rawData": false
}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1.1,
"position": [
752,
-1008
],
"id": "2659516f-d122-4761-8a7e-1ae15a161a7e",
"name": "Extract from xlsx"
},
{
"parameters": {
"operation": "xlsx",
"binaryPropertyName": "file0",
"options": {
"headerRow": true,
"rawData": false
}
},
"type": "n8n-nodes-base.extractFromFile",
"typeVersion": 1.1,
"position": [
768,
-640
],
"id": "86f8e8ef-4a62-400a-b2f1-46d57f9df41a",
"name": "Extract from csv"
},
{
"parameters": {
"jsCode": "// ======================================================\n// Schema-Driven Normalization (Correct, Stable Version)\n// ======================================================\n\n// ------------------\n// Fetch envelope\n// ------------------\nconst envelope = items[0]?.json;\n\nif (!envelope?.inputSchema || !envelope.inputSchema.input_columns) {\n throw new Error(\"inputSchema missing or invalid\");\n}\n\nif (!Array.isArray(envelope.rows)) {\n throw new Error(\"rows missing or invalid\");\n}\n\nconst inputSchema = envelope.inputSchema;\nconst schemaColumns = inputSchema.input_columns;\nconst rows = envelope.rows;\n\n// ------------------\n// Type converters\n// ------------------\nfunction toNumber(value, decimals) {\n if (value === null || value === undefined || value === \"\") return null;\n const num = Number(value);\n if (Number.isNaN(num)) return null;\n return typeof decimals === \"number\"\n ? Number(num.toFixed(decimals))\n : num;\n}\n\nfunction toDate(value) {\n if (!value) return null;\n const d = new Date(value);\n return isNaN(d.getTime()) ? null : d.toISOString().split(\"T\")[0];\n}\n\nfunction toString(value) {\n if (value === null || value === undefined) return null;\n return String(value).trim();\n}\n\n// ------------------\n// Normalize rows\n// ------------------\nconst normalizedRows = rows.map((row) => {\n const normalized = {};\n\n for (const [outputKey, columnDef] of Object.entries(schemaColumns)) {\n const inputColumnName = columnDef.label;\n const rawValue = row[inputColumnName];\n\n switch (columnDef.type) {\n case \"number\":\n normalized[outputKey] = toNumber(rawValue, columnDef.decimal_places);\n break;\n case \"date\":\n normalized[outputKey] = toDate(rawValue);\n break;\n case \"string\":\n normalized[outputKey] = toString(rawValue);\n break;\n default:\n normalized[outputKey] = null;\n }\n }\n\n return normalized;\n});\n\n// ------------------\n// Output (deterministic envelope)\n// ------------------\nreturn [{\n json: {\n documentType: envelope.documentType,\n inputSchema: envelope.inputSchema,\n rows: normalizedRows\n }\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1168,
-1008
],
"id": "89070a8d-f53e-4b2c-a68c-023c25d487a2",
"name": "normalization- xlsx"
},
{
"parameters": {
"jsCode": "// Input rows from Normalize step\nconst inputRows = items[0].json.rows;\n\n// === OUTPUT SCHEMA (Option A: hardcoded) ===\nconst fieldMappings = {\n CONTRACT_ID: { label: 'ID', visible: true },\n Col_B: { label: 'Process Type', visible: true },\n Col_C: { label: 'New OR Renewal', visible: true, default_value: 'New' },\n Col_D: { label: 'Previous Policy No', visible: true },\n CONTRACT_CODE: { label: 'UMR No.', visible: true },\n CEDANT: { label: 'Cedant Code', visible: true },\n CEDANT_NAME: { label: 'Cedant Name', visible: true },\n Col_H: { label: 'Billing Entity', visible: true },\n Col_I: { label: 'Original Insured', visible: true },\n BROKER_NAME: { label: 'Placing Co-Broker', visible: true },\n SUB_CLASS_NAME: { label: 'Insurance Class', visible: true },\n Col_L: { label: 'Insurance Product Name', visible: true },\n CONTRACT_NAME: { label: 'CONTRACT', visible: true },\n Col_N: { label: 'Issue Date', visible: true },\n EFFECTIVE_PERIOD_FROM: { label: 'Policy Effective Date', visible: true },\n EFFECTIVE_PERIOD_TO: { label: 'Policy Expiry Date', visible: true },\n PREM_WARR_DAYS: { label: 'Premium Warranty', visible: true },\n PREM_WARR_DATE: { label: 'PPW Date', visible: true },\n Col_S: { label: 'Type of Placement', visible: true },\n CONTRACT_TYPE: { label: 'Contract Type', visible: true },\n BROKER_IN_CHARGE_NAME: { label: 'Servicer Name', visible: true },\n BROKER_IN_CHARGE_CODE: { label: 'Servicer Short Name', visible: true },\n ACCEPTANCE_STATUS: { label: 'Status', visible: true },\n ORIG_CURR_EPI: { label: 'Min Deposit Premium', visible: true },\n SIGNED_SHARE: { label: 'RI Order(%)', visible: true },\n CURRENCY: { label: 'Currency', visible: true },\n Col_AA: { label: 'Premium Amount', visible: true },\n Col_AB: { label: 'RI Comm(%)', visible: true },\n Col_AC: { label: 'RI Comm Amt', visible: true },\n Col_AD: { label: 'Net RI Prem', visible: true },\n Col_AE: { label: 'Total Amt', visible: true },\n Col_AF: { label: 'Total', visible: true },\n Col_AG: { label: 'PremiumP', visible: true },\n REINSURER_NAME: { label: 'Re Insurer', visible: true },\n Col_AI: { label: 'LOL', visible: true },\n BRKG_CALC_METHOD: { label: 'Brokerage Basis', visible: true },\n EGNPI: { label: 'GNPI', visible: true },\n PREM_RATING_BASE: { label: 'Rate', visible: true },\n Col_AM: { label: 'Prem', visible: true },\n PREM_RATE_PCT: { label: 'Prem Rate %', visible: true },\n Col_AP: { label: 'Premium Amt', visible: true },\n RI_SIGNED_SHARE: { label: 'Pre%', visible: true },\n Col_AR: { label: 'Gross Prem', visible: true },\n GROSS_BRKG_PCT: { label: 'Brkg %', visible: true },\n Col_AT: { label: 'Brkg Amt', visible: true },\n RI_BROKER_NAME: { label: 'RI Placing Co-Broker', visible: true },\n Col_AV: { label: 'Quantity', visible: true },\n Col_AW: { label: 'Leader', visible: true },\n Col_AX: { label: 'Tax Type', visible: true },\n Col_AY: { label: 'Branch Details', visible: true },\n Col_AZ: { label: 'Assigned To', visible: true },\n UW_YEAR: { label: 'UW Year', visible: true },\n ENDORSEMENT_NO: { label: 'Endorsement No.', visible: true },\n BRANCH_NAME: { label: 'Branch Name', visible: true },\n DEPARTMENT_NAME: { label: 'Department Name', visible: true },\n OUR_REF: { label: 'ASF No.', visible: true },\n FUND_TYPE_NAME: { label: 'Fund Type', visible: true },\n PREM_ALERT: { label: 'Prem Alert', visible: true },\n PROCESS_STATUS: { label: 'Process Status', visible: true },\n BILL_TYPE: { label: 'Bill Type', visible: true },\n CLASS_NAME: { label: 'Class', visible: true },\n CLAIM_ALERT: { label: 'Claim Alert', visible: true },\n LAYER: { label: 'Layer', visible: true },\n BASIS_OF_COVER: { label: 'Basis of Cover', visible: true },\n PORTFOLIO: { label: 'Portfolio', visible: true },\n NOTICE_PERIOD: { label: 'Notice Period', visible: true },\n ACC_FREQ: { label: 'Acc Freq', visible: true },\n RENDER_DEADLINE: { label: 'Render Deadline', visible: true },\n SETTLEMENT_DEADLINE: { label: 'Statement Deadline', visible: true },\n PLA_LIMIT: { label: 'PLA Limit', visible: true },\n CASH_CALL_LIMIT: { label: 'Cash Call Limit', visible: true },\n ORIG_CURR_DEDUCTIBLE: { label: 'Original Currency Deductible', visible: true },\n RATE_ON_LINE: { label: 'Rate on Line', visible: true },\n QS_CEDED: { label: 'QS Ceded', visible: true },\n NO_OF_LINES: { label: 'No of Lines', visible: true },\n MAX_RETENTION: { label: 'Max Retention', visible: true },\n MAX_LIMIT: { label: 'Max Limit', visible: true },\n ORIGINAL_EPI: { label: 'Original EPI', visible: true },\n REVISED_EPI: { label: 'Revised EPI', visible: true },\n PREMIUM_RESERVE_PCT: { label: 'Premium Reserve %', visible: true },\n PREMIUM_RESERVE_DESC: { label: 'Premium Reserve Description', visible: true },\n LOSS_RESERVE_PCT: { label: 'Loss Reserve %', visible: true },\n INT_ON_RESERVE_PCT: { label: 'INT on Reserve %', visible: true },\n INT_ON_RESERVE_DESC: { label: 'INT on Reserve Description', visible: true },\n TAX_ON_INTEREST_PCT: { label: 'Tax on Interest %', visible: true },\n TAX_ON_INTEREST_DESC: { label: 'Tax on Interest Description', visible: true },\n COMMISSION_PCT: { label: 'Commission %', visible: true },\n COMMISSION_DESC: { label: 'Commission Description', visible: true },\n PROVISIONAL_COMM_PCT: { label: 'Provisional Commission %', visible: true },\n OVERRIDING_COMM: { label: 'Overriding Commission', visible: true },\n TAXES_AND_CHARGES: { label: 'Taxes and Charges', visible: true },\n PROFIT_COMM: { label: 'Profit Commission', visible: true },\n PROFIT_COMM_ME: { label: 'Profit Commission Me', visible: true },\n PROFIT_COMM_BASIS: { label: 'Profit Comm Basis', visible: true },\n PORTFOLIO_PREM_IN: { label: 'Portfolio Prem In', visible: true },\n PORTFOLIO_LOSS_IN: { label: 'Portfolio Loss In', visible: true },\n PORTFOLIO_LOSS_OUT: { label: 'Portfolio Loss Out', visible: true },\n SOURCE_BRKG_PCT: { label: 'Source Brkg%', visible: true },\n ORIG_CURR_AGG_LIMIT: { label: 'Original Currency Agg Limit', visible: true },\n ORIG_CURR_AGG_DEDUCTIBLE: { label: 'Original Currency Agg Deductible', visible: true },\n ORIG_CURR_AGG_INDEM_PER_EVENT: {\n label: 'Original Currency Agg Indem Per Event',\n visible: true\n },\n NO_OF_REINSTATEMENT: { label: 'No. of Reinstatement', visible: true },\n REINSTATEMENT_BASIS: { label: 'Reinstatement Basis', visible: true },\n REINSTATEMENT_AGG_LIMIT: { label: 'Reinstatement Agg Limit', visible: true },\n NO_OF_STATEMENTS: { label: 'No. of Statements', visible: true },\n FIRST_STATEMENT_DUE: { label: 'First Statement Due', visible: true },\n INFORMATION: { label: 'Information', visible: true }\n};\n\n\n// === SCHEMA APPLICATION ===\nconst outputRows = inputRows.map(row => {\n const out = {};\n\n for (const [sourceKey, config] of Object.entries(fieldMappings)) {\n if (config.visible === false) continue;\n\n let value = row[sourceKey];\n\n if (\n (value === undefined || value === null || value === '') &&\n config.default_value !== undefined\n ) {\n value = config.default_value;\n }\n\n out[config.label] = value ?? '';\n }\n\n return out;\n});\n\n// n8n expects array of items\nreturn outputRows.map(r => ({ json: r }));\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1632,
-1008
],
"id": "88f80d18-c14f-49b4-bc02-ccc9b2e55c6f",
"name": "mapping schema"
},
{
"parameters": {
"operation": "xlsx",
"binaryPropertyName": "output",
"options": {}
},
"type": "n8n-nodes-base.convertToFile",
"typeVersion": 1.1,
"position": [
1856,
-1008
],
"id": "e8c6ba04-8e51-45b4-be8c-94c533ec78de",
"name": "Convert to File"
},
{
"parameters": {
"respondWith": "binary",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
2080,
-1008
],
"id": "f0cef090-1ce5-43a8-9c50-a08d49c3c482",
"name": "Respond to Webhook1"
},
{
"parameters": {
"jsCode": "const docType = $json.query?.document_type;\n\nif (!docType) {\n throw new Error(\"document_type is required\");\n}\n\nconst SUPPORTED = [\"generic_v1\"];\n\nif (!SUPPORTED.includes(docType)) {\n throw new Error(`Unsupported document type: ${docType}`);\n}\n\nreturn [{\n json: {\n ...$json,\n documentType: docType\n },\n binary: $binary\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
80,
-816
],
"id": "9f4b24e9-2e98-43f8-93de-fd52b0b212eb",
"name": "Resolve document type"
},
{
"parameters": {
"jsCode": "// ======================================================\n// Input Schema Selector\n// - Schema is treated as authoritative contract\n// ======================================================\n\n// Step 1 must already have set this\nconst documentType = $json.documentType;\n\nif (!documentType) {\n throw new Error(\"documentType missing. Step 1 not executed.\");\n}\n\n// ====================\n// INPUT SCHEMAS\n// ====================\nconst INPUT_SCHEMAS = {\n generic_v1: {\n \"schema_version\": \"1.0\",\n \"description\": \"Auto-generated schema for data\",\n \"sheet_name\": \"data\",\n \"data_type_support\": {\n \"string\": \"Text values - preserved as-is from Excel cells\",\n \"number\": \"Numeric values - converted to float for proper decimal precision handling\",\n \"date\": \"Date values - converted to datetime objects for proper date handling\"\n },\n \"input_columns\": {\n \"UW_YEAR\": { \"label\": \"UW_YEAR\", \"type\": \"number\" },\n \"CONTRACT_ID\": { \"label\": \"CONTRACT_ID\", \"type\": \"number\" },\n \"CONTRACT_CODE\": { \"label\": \"CONTRACT_CODE\", \"type\": \"string\" },\n \"CONTRACT_TYPE\": { \"label\": \"CONTRACT_TYPE\", \"type\": \"string\" },\n \"ORIGINAL_CONTRACT_ID\": { \"label\": \"ORIGINAL_CONTRACT_ID\", \"type\": \"number\" },\n \"COUNTRY_ID\": { \"label\": \"COUNTRY_ID\", \"type\": \"number\" },\n \"COUNTRY\": { \"label\": \"COUNTRY\", \"type\": \"string\" },\n \"CEDANT\": { \"label\": \"CEDANT\", \"type\": \"number\" },\n \"CEDANT_NAME\": { \"label\": \"CEDANT_NAME\", \"type\": \"string\" },\n \"BROKER\": { \"label\": \"BROKER\", \"type\": \"number\" },\n \"BROKER_NAME\": { \"label\": \"BROKER_NAME\", \"type\": \"string\" },\n \"CLASS\": { \"label\": \"CLASS\", \"type\": \"number\" },\n \"CLASS_NAME\": { \"label\": \"CLASS_NAME\", \"type\": \"string\" },\n \"SUB_CLASS\": { \"label\": \"SUB_CLASS\", \"type\": \"number\" },\n \"SUB_CLASS_NAME\": { \"label\": \"SUB_CLASS_NAME\", \"type\": \"string\" },\n \"SUBTYPE\": { \"label\": \"SUBTYPE\", \"type\": \"number\" },\n \"SUBTYPE_NAME\": { \"label\": \"SUBTYPE_NAME\", \"type\": \"string\" },\n \"CONTRACT_NAME\": { \"label\": \"CONTRACT_NAME\", \"type\": \"string\" },\n \"ENDORSEMENT_NO\": { \"label\": \"ENDORSEMENT_NO\", \"type\": \"number\" },\n \"PERIOD_FROM\": { \"label\": \"PERIOD_FROM\", \"type\": \"date\" },\n \"PERIOD_TO\": { \"label\": \"PERIOD_TO\", \"type\": \"date\" },\n \"EFFECTIVE_PERIOD_FROM\": { \"label\": \"EFFECTIVE_PERIOD_FROM\", \"type\": \"date\" },\n \"EFFECTIVE_PERIOD_TO\": { \"label\": \"EFFECTIVE_PERIOD_TO\", \"type\": \"date\" },\n \"ACCEPTANCE_STATUS\": { \"label\": \"ACCEPTANCE_STATUS\", \"type\": \"string\" },\n \"PROCESS_STATUS\": { \"label\": \"PROCESS_STATUS\", \"type\": \"string\" },\n \"PREM_WARR_DAYS\": { \"label\": \"PREM_WARR_DAYS\", \"type\": \"number\", \"decimal_places\": 1 },\n \"PREM_WARR_DATE\": { \"label\": \"PREM_WARR_DATE\", \"type\": \"date\" },\n \"PREM_ALERT\": { \"label\": \"PREM_ALERT\", \"type\": \"string\" },\n \"CLAIM_ALERT\": { \"label\": \"CLAIM_ALERT\", \"type\": \"string\" },\n \"BILL_TYPE\": { \"label\": \"BILL_TYPE\", \"type\": \"string\" },\n \"BRANCH_ID\": { \"label\": \"BRANCH_ID\", \"type\": \"number\" },\n \"BRANCH_NAME\": { \"label\": \"BRANCH_NAME\", \"type\": \"string\" },\n \"DEPARTMENT_ID\": { \"label\": \"DEPARTMENT_ID\", \"type\": \"number\", \"decimal_places\": 1 },\n \"DEPARTMENT_NAME\": { \"label\": \"DEPARTMENT_NAME\", \"type\": \"string\" },\n \"BROKER_IN_CHARGE_NAME\": { \"label\": \"BROKER_IN_CHARGE_NAME\", \"type\": \"string\" },\n \"BROKER_IN_CHARGE_CODE\": { \"label\": \"BROKER_IN_CHARGE_CODE\", \"type\": \"string\" },\n \"OUR_REF\": { \"label\": \"OUR_REF\", \"type\": \"string\" },\n \"FUND_TYPE\": { \"label\": \"FUND_TYPE\", \"type\": \"number\" },\n \"FUND_TYPE_NAME\": { \"label\": \"FUND_TYPE_NAME\", \"type\": \"string\" },\n \"ORDER_SHARE\": { \"label\": \"ORDER_SHARE\", \"type\": \"number\", \"decimal_places\": 2 },\n \"WRITTEN_SHARE\": { \"label\": \"WRITTEN_SHARE\", \"type\": \"number\", \"decimal_places\": 2 },\n \"SIGNED_SHARE\": { \"label\": \"SIGNED_SHARE\", \"type\": \"number\", \"decimal_places\": 2 },\n \"CURRENCY_ID\": { \"label\": \"CURRENCY_ID\", \"type\": \"number\" },\n \"CURRENCY\": { \"label\": \"CURRENCY\", \"type\": \"string\" },\n \"LAYER\": { \"label\": \"LAYER\", \"type\": \"number\", \"decimal_places\": 1 },\n \"BASIS_OF_COVER\": { \"label\": \"BASIS_OF_COVER\", \"type\": \"string\" },\n \"PORTFOLIO\": { \"label\": \"PORTFOLIO\", \"type\": \"string\" },\n \"NOTICE_PERIOD\": { \"label\": \"NOTICE_PERIOD\", \"type\": \"number\", \"decimal_places\": 1 },\n \"ACC_FREQ\": { \"label\": \"ACC_FREQ\", \"type\": \"string\" },\n \"RENDER_DEADLINE\": { \"label\": \"RENDER_DEADLINE\", \"type\": \"number\", \"decimal_places\": 1 },\n \"SETTLEMENT_DEADLINE\": { \"label\": \"SETTLEMENT_DEADLINE\", \"type\": \"number\", \"decimal_places\": 1 },\n \"PLA_LIMIT\": { \"label\": \"PLA_LIMIT\", \"type\": \"number\", \"decimal_places\": 2 },\n \"CASH_CALL_LIMIT\": { \"label\": \"CASH_CALL_LIMIT\", \"type\": \"number\", \"decimal_places\": 2 },\n \"ORIG_CURR_LIMIT\": { \"label\": \"ORIG_CURR_LIMIT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"ORIG_CURR_DEDUCTIBLE\": { \"label\": \"ORIG_CURR_DEDUCTIBLE\", \"type\": \"number\", \"decimal_places\": 1 },\n \"EGNPI\": { \"label\": \"EGNPI\", \"type\": \"number\", \"decimal_places\": 1 },\n \"PREM_RATING_BASE\": { \"label\": \"PREM_RATING_BASE\", \"type\": \"string\" },\n \"PREM_RATE_PCT\": { \"label\": \"PREM_RATE_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"ORIG_CURR_MINIMUM\": { \"label\": \"ORIG_CURR_MINIMUM\", \"type\": \"number\", \"decimal_places\": 1 },\n \"ORIG_CURR_DEPOSIT\": { \"label\": \"ORIG_CURR_DEPOSIT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"ORIG_CURR_EPI\": { \"label\": \"ORIG_CURR_EPI\", \"type\": \"number\", \"decimal_places\": 1 },\n \"RATE_ON_LINE\": { \"label\": \"RATE_ON_LINE\", \"type\": \"number\", \"decimal_places\": 1 },\n \"QS_CEDED\": { \"label\": \"QS_CEDED\", \"type\": \"string\" },\n \"NO_OF_LINES\": { \"label\": \"NO_OF_LINES\", \"type\": \"number\" },\n \"MAX_RETENTION\": { \"label\": \"MAX_RETENTION\", \"type\": \"string\" },\n \"MAX_LIMIT\": { \"label\": \"MAX_LIMIT\", \"type\": \"number\", \"decimal_places\": 2 },\n \"ORIGINAL_EPI\": { \"label\": \"ORIGINAL_EPI\", \"type\": \"number\", \"decimal_places\": 1 },\n \"REVISED_EPI\": { \"label\": \"REVISED_EPI\", \"type\": \"number\", \"decimal_places\": 1 },\n \"PREMIUM_RESERVE_PCT\": { \"label\": \"PREMIUM_RESERVE_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"PREMIUM_RESERVE_DESC\": { \"label\": \"PREMIUM_RESERVE_DESC\", \"type\": \"string\" },\n \"LOSS_RESERVE_PCT\": { \"label\": \"LOSS_RESERVE_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"LOSS_RESERVE_DESC\": { \"label\": \"LOSS_RESERVE_DESC\", \"type\": \"string\" },\n \"INT_ON_RESERVE_PCT\": { \"label\": \"INT_ON_RESERVE_PCT\", \"type\": \"number\" },\n \"INT_ON_RESERVE_DESC\": { \"label\": \"INT_ON_RESERVE_DESC\", \"type\": \"string\" },\n \"TAX_ON_INTEREST_PCT\": { \"label\": \"TAX_ON_INTEREST_PCT\", \"type\": \"number\" },\n \"TAX_ON_INTEREST_DESC\": { \"label\": \"TAX_ON_INTEREST_DESC\", \"type\": \"string\" },\n \"COMMISSION_PCT\": { \"label\": \"COMMISSION_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"COMMISSION_DESC\": { \"label\": \"COMMISSION_DESC\", \"type\": \"string\" },\n \"PROVISIONAL_COMM_PCT\": { \"label\": \"PROVISIONAL_COMM_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"OVERRIDING_COMM\": { \"label\": \"OVERRIDING_COMM\", \"type\": \"string\" },\n \"TAXES_AND_CHARGES\": { \"label\": \"TAXES_AND_CHARGES\", \"type\": \"string\" },\n \"PROFIT_COMM\": { \"label\": \"PROFIT_COMM\", \"type\": \"string\" },\n \"PROFIT_COMM_ME\": { \"label\": \"PROFIT_COMM_ME\", \"type\": \"string\" },\n \"PROFIT_COMM_BASIS\": { \"label\": \"PROFIT_COMM_BASIS\", \"type\": \"string\" },\n \"PORTFOLIO_PREM_IN\": { \"label\": \"PORTFOLIO_PREM_IN\", \"type\": \"string\" },\n \"PORTFOLIO_PREM_OUT\": { \"label\": \"PORTFOLIO_PREM_OUT\", \"type\": \"string\" },\n \"PORTFOLIO_LOSS_IN\": { \"label\": \"PORTFOLIO_LOSS_IN\", \"type\": \"string\" },\n \"PORTFOLIO_LOSS_OUT\": { \"label\": \"PORTFOLIO_LOSS_OUT\", \"type\": \"string\" },\n \"GROSS_BRKG_PCT\": { \"label\": \"GROSS_BRKG_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"SOURCE_BRKG_PCT\": { \"label\": \"SOURCE_BRKG_PCT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"ORIG_CURR_AGG_LIMIT\": { \"label\": \"ORIG_CURR_AGG_LIMIT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"ORIG_CURR_AGG_DEDUCTIBLE\": { \"label\": \"ORIG_CURR_AGG_DEDUCTIBLE\", \"type\": \"number\", \"decimal_places\": 1 },\n \"ORIG_CURR_AGG_INDEM_PER_EVENT\": { \"label\": \"ORIG_CURR_AGG_INDEM_PER_EVENT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"NO_OF_REINSTATEMENT\": { \"label\": \"NO_OF_REINSTATEMENT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"REINSTATEMENT_BASIS\": { \"label\": \"REINSTATEMENT_BASIS\", \"type\": \"string\" },\n \"REINSTATEMENT_AGG_LIMIT\": { \"label\": \"REINSTATEMENT_AGG_LIMIT\", \"type\": \"number\", \"decimal_places\": 1 },\n \"NO_OF_STATEMENTS\": { \"label\": \"NO_OF_STATEMENTS\", \"type\": \"number\" },\n \"FIRST_STATEMENT_DUE\": { \"label\": \"FIRST_STATEMENT_DUE\", \"type\": \"date\" },\n \"INFORMATION\": { \"label\": \"INFORMATION\", \"type\": \"string\" }\n },\n \"source_file\": \"data.xlsx\",\n \"generated_at\": \"2025-12-19T08:43:58.206388\"\n }\n};\n\n// ====================\n// Schema Resolution\n// ====================\nconst inputSchema = INPUT_SCHEMAS[documentType];\n\nif (!inputSchema) {\n throw new Error(`Unsupported document type: ${documentType}`);\n}\n\n// Pass schema downstream untouched\nreturn [{\n json: {\n ...$json,\n inputSchema\n },\n binary: $binary\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
304,
-816
],
"id": "382fc10d-4a04-40a0-832c-fac8d7edfa15",
"name": "Select Input Schema"
},
{
"parameters": {
"jsCode": "// ======================================================\n// Validation (Hard Fail)\n// ======================================================\n\nconst rows = $json.rows;\nconst schema = $json.inputSchema;\n\nif (!Array.isArray(rows)) {\n throw new Error(\"rows missing or invalid\");\n}\n\nif (!schema || !schema.input_columns) {\n throw new Error(\"inputSchema missing during validation\");\n}\n\n// ------------------\n// Define critical fields\n// ------------------\nconst REQUIRED_FIELDS = [\n \"UW_YEAR\",\n \"CONTRACT_ID\",\n \"CONTRACT_CODE\"\n];\n\n// ------------------\n// Type check helpers\n// ------------------\nfunction isValidType(value, type) {\n if (value === null) return true; // null allowed unless required\n if (type === \"number\") return typeof value === \"number\";\n if (type === \"string\") return typeof value === \"string\";\n if (type === \"date\") return typeof value === \"string\"; // ISO date\n return false;\n}\n\n// ------------------\n// Validate rows\n// ------------------\nrows.forEach((row, rowIndex) => {\n // Required fields\n REQUIRED_FIELDS.forEach((field) => {\n if (row[field] === null || row[field] === undefined) {\n throw new Error(\n `Validation error: Missing required field '${field}' at row ${rowIndex + 1}`\n );\n }\n });\n\n // Type validation\n for (const [field, def] of Object.entries(schema.input_columns)) {\n if (!isValidType(row[field], def.type)) {\n throw new Error(\n `Validation error: Field '${field}' expected ${def.type} at row ${rowIndex + 1}`\n );\n }\n }\n});\n\n// ------------------\n// Pass through if valid\n// ------------------\nreturn [{\n json: $json\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1392,
-1008
],
"id": "e7771816-941e-48d8-b9df-177620a88727",
"name": "validate-normalized-data"
},
{
"parameters": {
"jsCode": "const inputSchema = $node[\"Select Input Schema\"].json.inputSchema;\n\nif (!inputSchema) {\n throw new Error(\"inputSchema not found\");\n}\n\n// Collect all extracted rows\nconst rows = items.map(item => item.json);\n\nreturn [{\n json: {\n rows,\n inputSchema\n },\n binary: $binary\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
960,
-1008
],
"id": "7553ea0b-f787-46a9-bcea-2fc4dbdb687b",
"name": "Reattach Input Schema"
},
{
"parameters": {
"jsCode": "const inputSchema = $node[\"Select Input Schema\"].json.inputSchema;\n\nif (!inputSchema) {\n throw new Error(\"inputSchema not found\");\n}\n\n// Collect all extracted rows\nconst rows = items.map(item => item.json);\n\nreturn [{\n json: {\n rows,\n inputSchema\n },\n binary: $binary\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
960,
-640
],
"id": "536d6956-8997-4318-944b-08869f7f5f0a",
"name": "Reattach Input Schema1"
},
{
"parameters": {
"jsCode": "// ======================================================\n// Schema-Driven Normalization (Correct, Stable Version)\n// ======================================================\n\n// ------------------\n// Fetch envelope\n// ------------------\nconst envelope = items[0]?.json;\n\nif (!envelope?.inputSchema || !envelope.inputSchema.input_columns) {\n throw new Error(\"inputSchema missing or invalid\");\n}\n\nif (!Array.isArray(envelope.rows)) {\n throw new Error(\"rows missing or invalid\");\n}\n\nconst inputSchema = envelope.inputSchema;\nconst schemaColumns = inputSchema.input_columns;\nconst rows = envelope.rows;\n\n// ------------------\n// Type converters\n// ------------------\nfunction toNumber(value, decimals) {\n if (value === null || value === undefined || value === \"\") return null;\n const num = Number(value);\n if (Number.isNaN(num)) return null;\n return typeof decimals === \"number\"\n ? Number(num.toFixed(decimals))\n : num;\n}\n\nfunction toDate(value) {\n if (!value) return null;\n const d = new Date(value);\n return isNaN(d.getTime()) ? null : d.toISOString().split(\"T\")[0];\n}\n\nfunction toString(value) {\n if (value === null || value === undefined) return null;\n return String(value).trim();\n}\n\n// ------------------\n// Normalize rows\n// ------------------\nconst normalizedRows = rows.map((row) => {\n const normalized = {};\n\n for (const [outputKey, columnDef] of Object.entries(schemaColumns)) {\n const inputColumnName = columnDef.label;\n const rawValue = row[inputColumnName];\n\n switch (columnDef.type) {\n case \"number\":\n normalized[outputKey] = toNumber(rawValue, columnDef.decimal_places);\n break;\n case \"date\":\n normalized[outputKey] = toDate(rawValue);\n break;\n case \"string\":\n normalized[outputKey] = toString(rawValue);\n break;\n default:\n normalized[outputKey] = null;\n }\n }\n\n return normalized;\n});\n\n// ------------------\n// Output (deterministic envelope)\n// ------------------\nreturn [{\n json: {\n documentType: envelope.documentType,\n inputSchema: envelope.inputSchema,\n rows: normalizedRows\n }\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1168,
-640
],
"id": "505d32c2-0e10-406c-abe9-e1de4f7ee929",
"name": "normalization- xlsx1"
},
{
"parameters": {
"jsCode": "// ======================================================\n// Validation (Hard Fail)\n// ======================================================\n\nconst rows = $json.rows;\nconst schema = $json.inputSchema;\n\nif (!Array.isArray(rows)) {\n throw new Error(\"rows missing or invalid\");\n}\n\nif (!schema || !schema.input_columns) {\n throw new Error(\"inputSchema missing during validation\");\n}\n\n// ------------------\n// Define critical fields\n// ------------------\nconst REQUIRED_FIELDS = [\n \"UW_YEAR\",\n \"CONTRACT_ID\",\n \"CONTRACT_CODE\"\n];\n\n// ------------------\n// Type check helpers\n// ------------------\nfunction isValidType(value, type) {\n if (value === null) return true; // null allowed unless required\n if (type === \"number\") return typeof value === \"number\";\n if (type === \"string\") return typeof value === \"string\";\n if (type === \"date\") return typeof value === \"string\"; // ISO date\n return false;\n}\n\n// ------------------\n// Validate rows\n// ------------------\nrows.forEach((row, rowIndex) => {\n // Required fields\n REQUIRED_FIELDS.forEach((field) => {\n if (row[field] === null || row[field] === undefined) {\n throw new Error(\n `Validation error: Missing required field '${field}' at row ${rowIndex + 1}`\n );\n }\n });\n\n // Type validation\n for (const [field, def] of Object.entries(schema.input_columns)) {\n if (!isValidType(row[field], def.type)) {\n throw new Error(\n `Validation error: Field '${field}' expected ${def.type} at row ${rowIndex + 1}`\n );\n }\n }\n});\n\n// ------------------\n// Pass through if valid\n// ------------------\nreturn [{\n json: $json\n}];\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1376,
-640
],
"id": "232ef567-f325-4f68-afef-2d1e4be5cbcd",
"name": "validate-normalized-data1"
},
{
"parameters": {
"jsCode": "// Input rows from Normalize step\nconst inputRows = items[0].json.rows;\n\n// === OUTPUT SCHEMA (Option A: hardcoded) ===\nconst fieldMappings = {\n CONTRACT_ID: { label: 'ID', visible: true },\n Col_B: { label: 'Process Type', visible: true },\n Col_C: { label: 'New OR Renewal', visible: true, default_value: 'New' },\n Col_D: { label: 'Previous Policy No', visible: true },\n CONTRACT_CODE: { label: 'UMR No.', visible: true },\n CEDANT: { label: 'Cedant Code', visible: true },\n CEDANT_NAME: { label: 'Cedant Name', visible: true },\n Col_H: { label: 'Billing Entity', visible: true },\n Col_I: { label: 'Original Insured', visible: true },\n BROKER_NAME: { label: 'Placing Co-Broker', visible: true },\n SUB_CLASS_NAME: { label: 'Insurance Class', visible: true },\n Col_L: { label: 'Insurance Product Name', visible: true },\n CONTRACT_NAME: { label: 'CONTRACT', visible: true },\n Col_N: { label: 'Issue Date', visible: true },\n EFFECTIVE_PERIOD_FROM: { label: 'Policy Effective Date', visible: true },\n EFFECTIVE_PERIOD_TO: { label: 'Policy Expiry Date', visible: true },\n PREM_WARR_DAYS: { label: 'Premium Warranty', visible: true },\n PREM_WARR_DATE: { label: 'PPW Date', visible: true },\n Col_S: { label: 'Type of Placement', visible: true },\n CONTRACT_TYPE: { label: 'Contract Type', visible: true },\n BROKER_IN_CHARGE_NAME: { label: 'Servicer Name', visible: true },\n BROKER_IN_CHARGE_CODE: { label: 'Servicer Short Name', visible: true },\n ACCEPTANCE_STATUS: { label: 'Status', visible: true },\n ORIG_CURR_EPI: { label: 'Min Deposit Premium', visible: true },\n SIGNED_SHARE: { label: 'RI Order(%)', visible: true },\n CURRENCY: { label: 'Currency', visible: true },\n Col_AA: { label: 'Premium Amount', visible: true },\n Col_AB: { label: 'RI Comm(%)', visible: true },\n Col_AC: { label: 'RI Comm Amt', visible: true },\n Col_AD: { label: 'Net RI Prem', visible: true },\n Col_AE: { label: 'Total Amt', visible: true },\n Col_AF: { label: 'Total', visible: true },\n Col_AG: { label: 'PremiumP', visible: true },\n REINSURER_NAME: { label: 'Re Insurer', visible: true },\n Col_AI: { label: 'LOL', visible: true },\n BRKG_CALC_METHOD: { label: 'Brokerage Basis', visible: true },\n EGNPI: { label: 'GNPI', visible: true },\n PREM_RATING_BASE: { label: 'Rate', visible: true },\n Col_AM: { label: 'Prem', visible: true },\n PREM_RATE_PCT: { label: 'Prem Rate %', visible: true },\n Col_AP: { label: 'Premium Amt', visible: true },\n RI_SIGNED_SHARE: { label: 'Pre%', visible: true },\n Col_AR: { label: 'Gross Prem', visible: true },\n GROSS_BRKG_PCT: { label: 'Brkg %', visible: true },\n Col_AT: { label: 'Brkg Amt', visible: true },\n RI_BROKER_NAME: { label: 'RI Placing Co-Broker', visible: true },\n Col_AV: { label: 'Quantity', visible: true },\n Col_AW: { label: 'Leader', visible: true },\n Col_AX: { label: 'Tax Type', visible: true },\n Col_AY: { label: 'Branch Details', visible: true },\n Col_AZ: { label: 'Assigned To', visible: true },\n UW_YEAR: { label: 'UW Year', visible: true },\n ENDORSEMENT_NO: { label: 'Endorsement No.', visible: true },\n BRANCH_NAME: { label: 'Branch Name', visible: true },\n DEPARTMENT_NAME: { label: 'Department Name', visible: true },\n OUR_REF: { label: 'ASF No.', visible: true },\n FUND_TYPE_NAME: { label: 'Fund Type', visible: true },\n PREM_ALERT: { label: 'Prem Alert', visible: true },\n PROCESS_STATUS: { label: 'Process Status', visible: true },\n BILL_TYPE: { label: 'Bill Type', visible: true },\n CLASS_NAME: { label: 'Class', visible: true },\n CLAIM_ALERT: { label: 'Claim Alert', visible: true },\n LAYER: { label: 'Layer', visible: true },\n BASIS_OF_COVER: { label: 'Basis of Cover', visible: true },\n PORTFOLIO: { label: 'Portfolio', visible: true },\n NOTICE_PERIOD: { label: 'Notice Period', visible: true },\n ACC_FREQ: { label: 'Acc Freq', visible: true },\n RENDER_DEADLINE: { label: 'Render Deadline', visible: true },\n SETTLEMENT_DEADLINE: { label: 'Statement Deadline', visible: true },\n PLA_LIMIT: { label: 'PLA Limit', visible: true },\n CASH_CALL_LIMIT: { label: 'Cash Call Limit', visible: true },\n ORIG_CURR_DEDUCTIBLE: { label: 'Original Currency Deductible', visible: true },\n RATE_ON_LINE: { label: 'Rate on Line', visible: true },\n QS_CEDED: { label: 'QS Ceded', visible: true },\n NO_OF_LINES: { label: 'No of Lines', visible: true },\n MAX_RETENTION: { label: 'Max Retention', visible: true },\n MAX_LIMIT: { label: 'Max Limit', visible: true },\n ORIGINAL_EPI: { label: 'Original EPI', visible: true },\n REVISED_EPI: { label: 'Revised EPI', visible: true },\n PREMIUM_RESERVE_PCT: { label: 'Premium Reserve %', visible: true },\n PREMIUM_RESERVE_DESC: { label: 'Premium Reserve Description', visible: true },\n LOSS_RESERVE_PCT: { label: 'Loss Reserve %', visible: true },\n INT_ON_RESERVE_PCT: { label: 'INT on Reserve %', visible: true },\n INT_ON_RESERVE_DESC: { label: 'INT on Reserve Description', visible: true },\n TAX_ON_INTEREST_PCT: { label: 'Tax on Interest %', visible: true },\n TAX_ON_INTEREST_DESC: { label: 'Tax on Interest Description', visible: true },\n COMMISSION_PCT: { label: 'Commission %', visible: true },\n COMMISSION_DESC: { label: 'Commission Description', visible: true },\n PROVISIONAL_COMM_PCT: { label: 'Provisional Commission %', visible: true },\n OVERRIDING_COMM: { label: 'Overriding Commission', visible: true },\n TAXES_AND_CHARGES: { label: 'Taxes and Charges', visible: true },\n PROFIT_COMM: { label: 'Profit Commission', visible: true },\n PROFIT_COMM_ME: { label: 'Profit Commission Me', visible: true },\n PROFIT_COMM_BASIS: { label: 'Profit Comm Basis', visible: true },\n PORTFOLIO_PREM_IN: { label: 'Portfolio Prem In', visible: true },\n PORTFOLIO_LOSS_IN: { label: 'Portfolio Loss In', visible: true },\n PORTFOLIO_LOSS_OUT: { label: 'Portfolio Loss Out', visible: true },\n SOURCE_BRKG_PCT: { label: 'Source Brkg%', visible: true },\n ORIG_CURR_AGG_LIMIT: { label: 'Original Currency Agg Limit', visible: true },\n ORIG_CURR_AGG_DEDUCTIBLE: { label: 'Original Currency Agg Deductible', visible: true },\n ORIG_CURR_AGG_INDEM_PER_EVENT: {\n label: 'Original Currency Agg Indem Per Event',\n visible: true\n },\n NO_OF_REINSTATEMENT: { label: 'No. of Reinstatement', visible: true },\n REINSTATEMENT_BASIS: { label: 'Reinstatement Basis', visible: true },\n REINSTATEMENT_AGG_LIMIT: { label: 'Reinstatement Agg Limit', visible: true },\n NO_OF_STATEMENTS: { label: 'No. of Statements', visible: true },\n FIRST_STATEMENT_DUE: { label: 'First Statement Due', visible: true },\n INFORMATION: { label: 'Information', visible: true }\n};\n\n\n// === SCHEMA APPLICATION ===\nconst outputRows = inputRows.map(row => {\n const out = {};\n\n for (const [sourceKey, config] of Object.entries(fieldMappings)) {\n if (config.visible === false) continue;\n\n let value = row[sourceKey];\n\n if (\n (value === undefined || value === null || value === '') &&\n config.default_value !== undefined\n ) {\n value = config.default_value;\n }\n\n out[config.label] = value ?? '';\n }\n\n return out;\n});\n\n// n8n expects array of items\nreturn outputRows.map(r => ({ json: r }));\n"
},
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
1600,
-640
],
"id": "fb656eac-7fbd-46f7-913d-aa33fae7507e",
"name": "mapping schema1"
},
{
"parameters": {
"operation": "xlsx",
"binaryPropertyName": "output",
"options": {}
},
"type": "n8n-nodes-base.convertToFile",
"typeVersion": 1.1,
"position": [
1808,
-640
],
"id": "b8465683-2117-4fd9-9c1d-fb41953e7916",
"name": "Convert to File1"
},
{
"parameters": {
"respondWith": "binary",
"options": {}
},
"type": "n8n-nodes-base.respondToWebhook",
"typeVersion": 1.5,
"position": [
2016,
-640
],
"id": "0abd2d3b-17fb-48a2-9d98-ebe5cabe504c",
"name": "Respond to Webhook2"
}
],
"connections": {
"Webhook": {
"main": [
[
{
"node": "Edit Fields",
"type": "main",
"index": 0
}
]
]
},
"Edit Fields": {
"main": [
[
{
"node": "Resolve document type",
"type": "main",
"index": 0
}
]
]
},
"If - .xlsx": {
"main": [
[
{
"node": "Extract from xlsx",
"type": "main",
"index": 0
}
],
[
{
"node": "If- .csv",
"type": "main",
"index": 0
}
]
]
},
"If- .csv": {
"main": [
[
{
"node": "Extract from csv",
"type": "main",
"index": 0
}
],
[
{
"node": "If- .docx",
"type": "main",
"index": 0
}
]
]
},
"If- .docx": {
"main": [
[],
[
{
"node": "If- .pdf",
"type": "main",
"index": 0
}
]
]
},
"If- .pdf": {
"main": [
[],
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
},
"Extract from xlsx": {
"main": [
[
{
"node": "Reattach Input Schema",
"type": "main",
"index": 0
}
]
]
},
"Extract from csv": {
"main": [
[
{
"node": "Reattach Input Schema1",
"type": "main",
"index": 0
}
]
]
},
"normalization- xlsx": {
"main": [
[
{
"node": "validate-normalized-data",
"type": "main",
"index": 0
}
]
]
},
"mapping schema": {
"main": [
[
{
"node": "Convert to File",
"type": "main",
"index": 0
}
]
]
},
"Convert to File": {
"main": [
[
{
"node": "Respond to Webhook1",
"type": "main",
"index": 0
}
]
]
},
"Resolve document type": {
"main": [
[
{
"node": "Select Input Schema",
"type": "main",
"index": 0
}
]
]
},
"Select Input Schema": {
"main": [
[
{
"node": "If - .xlsx",
"type": "main",
"index": 0
}
]
]
},
"validate-normalized-data": {
"main": [
[
{
"node": "mapping schema",
"type": "main",
"index": 0
}
]
]
},
"Reattach Input Schema": {
"main": [
[
{
"node": "normalization- xlsx",
"type": "main",
"index": 0
}
]
]
},
"Reattach Input Schema1": {
"main": [
[
{
"node": "normalization- xlsx1",
"type": "main",
"index": 0
}
]
]
},
"normalization- xlsx1": {
"main": [
[
{
"node": "validate-normalized-data1",
"type": "main",
"index": 0
}
]
]
},
"validate-normalized-data1": {
"main": [
[
{
"node": "mapping schema1",
"type": "main",
"index": 0
}
]
]
},
"mapping schema1": {
"main": [
[
{
"node": "Convert to File1",
"type": "main",
"index": 0
}
]
]
},
"Convert to File1": {
"main": [
[
{
"node": "Respond to Webhook2",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {
"executionOrder": "v1",
"binaryMode": "separate",
"availableInMCP": false
},
"versionId": "cb6c338b-db9b-4cf5-a71d-e094aec184d2",
"id": "kWCdgTDzC2xtw9OWMCRAE",
"tags": []
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
extraction-automation. Webhook trigger; 23 nodes.
Source: https://github.com/agtrisha94/n8n-Workflows/blob/main/extraction-automation.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.
A production-ready authentication workflow implementing secure user registration, login, token verification, and refresh token mechanisms. Perfect for adding authentication to any application without
Portfolio Orchestrator. Uses httpRequest. Webhook trigger; 59 nodes.
This n8n template demonstrates how a simple Multi-Layer Perceptron (MLP) neural network can predict housing prices. The prediction is based on four key features, processed through a three-layer model.
github code Try yourself
This workflow receives new consult bookings via webhook (Calendly v2 or a generic scheduling tool), generates timed confirmation and reminder messages, runs each SMS through a separate compliance work