This workflow corresponds to n8n.io template #12583 — we link there as the canonical source.
This workflow follows the Agent → Emailsend 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 →
{
"meta": {
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "97fb4a8a-a776-4281-96d1-4852183fb3e0",
"name": "Sticky_Intake",
"type": "n8n-nodes-base.stickyNote",
"position": [
5952,
3584
],
"parameters": {
"color": 7,
"width": 450,
"height": 550,
"content": "## \ud83d\udee1\ufe0f PHASE 1: Intake & Atomic Splitting\nIngests raw EMR PDF. **Split Node** explodes the chart into atomic pages for isolated processing to prevent PII leakage across document sections."
},
"typeVersion": 1
},
{
"id": "eb8a7d69-ffa8-472c-b739-3279636b0d00",
"name": "Sticky_Triage",
"type": "n8n-nodes-base.stickyNote",
"position": [
6432,
3584
],
"parameters": {
"color": 7,
"width": 550,
"height": 550,
"content": "## \ud83d\udd2c PHASE 2: Clinical Classification\n**Code Node** identifies page types. **Switch Node** routes to specific redaction paths. This ensures Labs are treated differently than Imaging reports."
},
"typeVersion": 1
},
{
"id": "8b18a2de-adaf-45a6-ab47-ba80c0436f10",
"name": "Sticky_Assembly",
"type": "n8n-nodes-base.stickyNote",
"position": [
6992,
3568
],
"parameters": {
"color": 7,
"width": 550,
"height": 550,
"content": "## \ud83d\ude80 PHASE 3: Sanitization & Re-Assembly\nRedacts PII. AI generates layman summaries. **Merge Node** compiles the final patient-ready PDF for the portal."
},
"typeVersion": 1
},
{
"id": "dfac86c9-504e-4988-b9f1-f9956a45e84f",
"name": "Sticky_AI_Intelligence",
"type": "n8n-nodes-base.stickyNote",
"position": [
7568,
3568
],
"parameters": {
"color": 7,
"width": 550,
"height": 550,
"content": "## \ud83e\udd16 PHASE 4: AI Intelligence Layer\nLeverages Claude AI for medical terminology translation, anomaly detection, and patient-friendly summaries."
},
"typeVersion": 1
},
{
"id": "48d85b20-9e32-464e-877b-1e859f82263d",
"name": "HTTP: EMR PDF Intake",
"type": "n8n-nodes-base.httpRequest",
"position": [
6016,
3888
],
"parameters": {
"url": "={{ $json.emrSourceUrl }}",
"options": {
"response": {
"response": {
"responseFormat": "file"
}
}
}
},
"typeVersion": 4.2
},
{
"id": "5644643c-20b3-4a12-a084-b6c1045c2fbf",
"name": "Code: Clinical Classifier",
"type": "n8n-nodes-base.code",
"position": [
6464,
3888
],
"parameters": {
"jsCode": "// Code Node: Medical Classification with OCR Enhancement\nconst items = $input.all();\nreturn items.map((item, index) => {\n const text = item.json.text || ''; \n \n // Advanced classification logic\n let pageType = 'Note';\n if (text.match(/\\b(CBC|BMP|CMP|Lipid Panel|HbA1c)\\b/i)) {\n pageType = 'Lab';\n } else if (text.match(/\\b(Prescription|Medication|Rx|Dosage)\\b/i)) {\n pageType = 'Rx';\n } else if (text.match(/\\b(X-Ray|MRI|CT Scan|Ultrasound|Radiology)\\b/i)) {\n pageType = 'Imaging';\n } else if (text.match(/\\b(Progress Note|SOAP|Assessment|Plan)\\b/i)) {\n pageType = 'Clinical Note';\n }\n \n item.json.pageType = pageType;\n item.json.pageHash = 'SHA256-' + Buffer.from(text).toString('base64').substring(0, 16);\n item.json.processedAt = new Date().toISOString();\n item.json.pageNumber = index + 1;\n \n // Flag sensitive sections\n item.json.hasPII = text.match(/\\b(SSN|DOB|Phone|Address)\\b/i) ? true : false;\n \n return item;\n});"
},
"typeVersion": 2
},
{
"id": "3906de09-eb18-4b10-8e55-419c8b933bb3",
"name": "Switch: Redaction Path",
"type": "n8n-nodes-base.switch",
"position": [
6656,
3888
],
"parameters": {
"rules": {
"rules": [
{
"value2": "Lab"
},
{
"output": 1,
"value2": "Rx"
},
{
"output": 2,
"value2": "Imaging"
},
{
"output": 3,
"value2": "Clinical Note"
}
]
},
"value1": "={{ $json.pageType }}",
"dataType": "string"
},
"typeVersion": 1
},
{
"id": "0c989606-d169-420f-bf0a-eb46ca889de9",
"name": "Code: HIPAA Redactor",
"type": "n8n-nodes-base.code",
"position": [
6912,
3888
],
"parameters": {
"jsCode": "// Code Node: Advanced PII Scrubbing (HIPAA-compliant)\nconst item = $input.first().json;\n\n// Comprehensive redaction patterns\nconst redactionPatterns = [\n { pattern: /\\b\\d{3}-\\d{2}-\\d{4}\\b/g, label: '[SSN-REDACTED]' },\n { pattern: /\\b\\d{10}\\b/g, label: '[PHONE-REDACTED]' },\n { pattern: /\\b[A-Z][a-z]+ [A-Z][a-z]+\\b/g, label: '[NAME-REDACTED]' },\n { pattern: /Technician: [A-Za-z ]+/g, label: '[TECH-REDACTED]' },\n { pattern: /\\b\\d{1,5}\\s\\w+\\s(Street|St|Avenue|Ave|Road|Rd|Boulevard|Blvd)\\b/gi, label: '[ADDRESS-REDACTED]' },\n { pattern: /\\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,}\\b/gi, label: '[EMAIL-REDACTED]' },\n { pattern: /\\b(\\d{2}\\/\\d{2}\\/\\d{4})\\b/g, label: '[DOB-REDACTED]' }\n];\n\nlet sanitizedText = item.text || '';\nlet redactionCount = 0;\n\nredactionPatterns.forEach(({ pattern, label }) => {\n const matches = sanitizedText.match(pattern);\n if (matches) {\n redactionCount += matches.length;\n sanitizedText = sanitizedText.replace(pattern, label);\n }\n});\n\nitem.sanitizedText = sanitizedText;\nitem.redactionCount = redactionCount;\nitem.sanitizedAt = new Date().toISOString();\nitem.complianceStatus = redactionCount > 0 ? 'PII_REMOVED' : 'CLEAN';\n\nreturn { json: item };"
},
"typeVersion": 2
},
{
"id": "14ae5214-ddd8-484c-b6dc-b0405b67d8e2",
"name": "Code: Anomaly Detector",
"type": "n8n-nodes-base.code",
"position": [
7392,
3888
],
"parameters": {
"jsCode": "// Code Node: Anomaly Detection\nconst item = $input.first().json;\nconst text = item.sanitizedText || '';\n\n// Flag critical values or concerning patterns\nconst anomalies = [];\n\n// Lab value checks\nif (text.match(/glucose.*?(\\d{3,})/i)) {\n anomalies.push({ type: 'HIGH_GLUCOSE', severity: 'HIGH' });\n}\nif (text.match(/blood pressure.*?(\\d{3}\\/\\d{3})/i)) {\n anomalies.push({ type: 'HYPERTENSION', severity: 'MEDIUM' });\n}\nif (text.match(/\\b(critical|urgent|stat|emergency)\\b/i)) {\n anomalies.push({ type: 'URGENT_FLAG', severity: 'CRITICAL' });\n}\n\nitem.anomalies = anomalies;\nitem.requiresReview = anomalies.some(a => a.severity === 'CRITICAL');\nitem.anomalyCount = anomalies.length;\n\nreturn { json: item };"
},
"typeVersion": 2
},
{
"id": "d356af35-fdcf-4de9-bdd6-b41af3fcf881",
"name": "Merge: Combine Processed Pages",
"type": "n8n-nodes-base.merge",
"position": [
7584,
3888
],
"parameters": {
"mode": "combine",
"options": {},
"combinationMode": "mergeByPosition"
},
"typeVersion": 2.1
},
{
"id": "4402005a-b431-42fc-b008-3b35cf6045db",
"name": "IF: Compliance Validator",
"type": "n8n-nodes-base.if",
"position": [
7968,
3920
],
"parameters": {
"options": {},
"conditions": {
"options": {
"combineOperation": "all"
},
"combinator": "and",
"conditions": [
{
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.complianceStatus }}",
"rightValue": "PII_REMOVED"
},
{
"operator": {
"type": "number",
"operation": "gt"
},
"leftValue": "={{ $json.redactionCount }}",
"rightValue": 0
}
]
}
},
"typeVersion": 2
},
{
"id": "f518d72d-11a5-4ffc-bdfc-3f59a7bd3e40",
"name": "Postgres: Audit Trail",
"type": "n8n-nodes-base.postgres",
"position": [
8256,
3824
],
"parameters": {
"query": "INSERT INTO compliance_audit (event, hash, redaction_count, anomaly_count, status, timestamp) VALUES ('PDF_PROCESSED', '{{ $json.pageHash }}', {{ $json.redactionCount }}, {{ $json.anomalyCount }}, '{{ $json.complianceStatus }}', NOW())",
"options": {},
"operation": "executeQuery"
},
"typeVersion": 2.4
},
{
"id": "01c8013c-e50f-4b3f-a7e0-fdcf0cf20f28",
"name": "Google Drive: Secure Storage",
"type": "n8n-nodes-base.googleDrive",
"position": [
8256,
3984
],
"parameters": {
"driveId": {
"__rl": true,
"mode": "list",
"value": "My Drive"
},
"options": {},
"folderId": {
"__rl": true,
"mode": "list",
"value": "root",
"cachedResultName": "/ (Root folder)"
}
},
"credentials": {
"googleDriveOAuth2Api": {
"name": "<your credential>"
}
},
"typeVersion": 3
},
{
"id": "3754eb7c-0a09-4910-b607-7a72744034d4",
"name": "Twilio: Patient Alert",
"type": "n8n-nodes-base.twilio",
"position": [
8480,
3888
],
"parameters": {
"message": "=\ud83c\udfe5 Your secure medical summary is ready!\n\n\ud83d\udccb Document: {{ $json.pageType }}\n\u2705 Redactions: {{ $json.redactionCount }} items protected\n{{ $json.requiresReview ? '\u26a0\ufe0f Contains items requiring provider review' : '\u2713 No critical findings' }}\n\nView in portal: https://portal.example.com/records/{{ $json.pageHash }}",
"options": {}
},
"typeVersion": 1
},
{
"id": "c2460a2d-a300-4383-b139-743d18d7eafb",
"name": "Email: Provider Alert (Urgent)",
"type": "n8n-nodes-base.emailSend",
"position": [
8256,
3696
],
"parameters": {
"operation": "sendEmail"
},
"credentials": {
"smtp": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "f43fb3b0-0dfd-4c34-8824-74a84bde993e",
"name": "Stop and Error: Failed Validation",
"type": "n8n-nodes-base.stopAndError",
"position": [
7952,
3712
],
"parameters": {
"errorMessage": "=Compliance validation failed for record {{ $json.pageHash }}. Redaction count: {{ $json.redactionCount }}. Manual review required."
},
"typeVersion": 1
},
{
"id": "b8c7620f-a61f-4e2b-b20b-bfa36ad6aa3b",
"name": "Sticky_QA1",
"type": "n8n-nodes-base.stickyNote",
"position": [
8128,
3568
],
"parameters": {
"color": 7,
"width": 450,
"height": 550,
"content": "## \u26a0\ufe0f PHASE 5: Quality Assurance\nError handling, validation checks, and compliance verification before final delivery."
},
"typeVersion": 1
},
{
"id": "2b80ecb3-2ac0-49e3-9c17-3bb3d5f392fd",
"name": "Split PDF",
"type": "n8n-nodes-htmlcsstopdf.htmlcsstopdf",
"position": [
6224,
3888
],
"parameters": {
"resource": "pdfManipulation",
"operation": "splitPdf"
},
"credentials": {
"htmlcsstopdfApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "d50b7f21-3e9b-4352-90bc-95d63fe143eb",
"name": "AI Agent",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
7120,
3888
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "e35627ed-0896-470d-9972-94736b36fea8",
"name": "OpenAI Chat Model",
"type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
"position": [
7120,
4016
],
"parameters": {
"model": {
"__rl": true,
"mode": "list",
"value": "gpt-4.1-mini"
},
"options": {},
"builtInTools": {}
},
"credentials": {
"openAiApi": {
"name": "<your credential>"
}
},
"typeVersion": 1.3
},
{
"id": "292b1f35-9ccc-462b-928d-3ebe306b431b",
"name": "Merge multiple PDFS into one",
"type": "n8n-nodes-htmlcsstopdf.htmlcsstopdf",
"position": [
7776,
3872
],
"parameters": {
"resource": "pdfManipulation"
},
"credentials": {
"htmlcsstopdfApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "f900d4fb-a754-43cd-a78e-9814dcd52bae",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
5424,
2880
],
"parameters": {
"width": 528,
"height": 672,
"content": "## \ud83c\udfe5Clinical Data Orchestrator: Multi-Stage Redaction & AI Summary Hub\n\nAn enterprise-grade engine for secure clinical document orchestration: Intake \u2192 Atomization \u2192 AI Triage \u2192 Secure Archival.\n\n### \u2699\ufe0f Core Sovereign Logic\n* **PHASE 1: Atomic Atomization:** Explodes monolithic EMR exports into isolated pages via **Split PDF** to prevent cross-sectional PII leakage.\n* **PHASE 2: Clinical Triage:** Custom Code Node identifies page DNA (Labs, Rx, Imaging, Notes) to drive specialized redaction tracks.\n* **PHASE 3: HIPAA Sanitization:** Applies a multi-pattern regex engine to scrub SSNs, names, and technician PII.\n* **PHASE 4: AI Intelligence Layer:** GPT-4 identifies medical anomalies and translates complex jargon into layman-friendly summaries.\n* **PHASE 5: Compliance Archival:** Re-assembles sanitized pages via **Merge PDF** and logs SHA-256 fingerprints to PostgreSQL for non-repudiation.\n\n### \ud83d\udccb Setup & Prerequisites\n1. **Security:** Ensure PostgreSQL uses AES-256 encryption for the audit vault.\n2. **Credentials:** OpenAI (AI Agent), Twilio (Alerts), Google Drive (Storage), and PostgreSQL.\n3. **Storage:** Set the Root Folder ID to a HIPAA-compliant restricted drive.\n\n**Metrics:** `Redaction_Count`, `Anomaly_Severity`, `HIPAA_Audit_Hash`."
},
"typeVersion": 1
}
],
"connections": {
"AI Agent": {
"main": [
[
{
"node": "Code: Anomaly Detector",
"type": "main",
"index": 0
}
]
]
},
"Split PDF": {
"main": [
[
{
"node": "Code: Clinical Classifier",
"type": "main",
"index": 0
}
]
]
},
"OpenAI Chat Model": {
"ai_languageModel": [
[
{
"node": "AI Agent",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"Code: HIPAA Redactor": {
"main": [
[
{
"node": "AI Agent",
"type": "main",
"index": 0
}
]
]
},
"HTTP: EMR PDF Intake": {
"main": [
[
{
"node": "Split PDF",
"type": "main",
"index": 0
}
]
]
},
"Postgres: Audit Trail": {
"main": [
[
{
"node": "Twilio: Patient Alert",
"type": "main",
"index": 0
}
]
]
},
"Code: Anomaly Detector": {
"main": [
[
{
"node": "Merge: Combine Processed Pages",
"type": "main",
"index": 0
}
]
]
},
"Switch: Redaction Path": {
"main": [
[
{
"node": "Code: HIPAA Redactor",
"type": "main",
"index": 0
}
],
[
{
"node": "Code: HIPAA Redactor",
"type": "main",
"index": 0
}
],
[
{
"node": "Code: HIPAA Redactor",
"type": "main",
"index": 0
}
],
[
{
"node": "Code: HIPAA Redactor",
"type": "main",
"index": 0
}
]
]
},
"IF: Compliance Validator": {
"main": [
[
{
"node": "Postgres: Audit Trail",
"type": "main",
"index": 0
},
{
"node": "Google Drive: Secure Storage",
"type": "main",
"index": 0
},
{
"node": "Email: Provider Alert (Urgent)",
"type": "main",
"index": 0
}
],
[
{
"node": "Stop and Error: Failed Validation",
"type": "main",
"index": 0
}
]
]
},
"Code: Clinical Classifier": {
"main": [
[
{
"node": "Switch: Redaction Path",
"type": "main",
"index": 0
}
]
]
},
"Google Drive: Secure Storage": {
"main": [
[
{
"node": "Twilio: Patient Alert",
"type": "main",
"index": 0
}
]
]
},
"Merge multiple PDFS into one": {
"main": [
[
{
"node": "IF: Compliance Validator",
"type": "main",
"index": 0
}
]
]
},
"Email: Provider Alert (Urgent)": {
"main": [
[
{
"node": "Twilio: Patient Alert",
"type": "main",
"index": 0
}
]
]
},
"Merge: Combine Processed Pages": {
"main": [
[
{
"node": "Merge multiple PDFS into one",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
googleDriveOAuth2ApihtmlcsstopdfApiopenAiApismtp
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This is an elite-tier HealthTech solution designed for the secure processing of high-volume medical records. Monolithic EMR exports (often 200+ pages) are atomized into individual pages, allowing for granular, clinical-grade redaction and AI-driven summarization before being…
Source: https://n8n.io/workflows/12583/ — 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 workflow automates end-to-end patient care coordination by monitoring appointment schedules, clinical events, and care milestones while orchestrating personalized communications across multiple c
The system collects real-time wearable health data, normalizes it, and uses AI to analyze trends and risk scores. It detects anomalies by comparing with historical patterns and automatically triggers
This n8n workflow orchestrates a powerful suite of AI Agents and automations to manage and optimize various aspects of an e-commerce operation, particularly for platforms like Shopify. It leverages La
f1_bot_zoom. Uses stopAndError, httpRequest, emailSend, agent. Webhook trigger; 39 nodes.
This workflow automates veterinary clinic operations and client communications for animal hospitals and veterinary practices managing appointments, inventory, and patient care. It solves the dual chal