AutomationFlowsAI & RAG › Generate Hipaa-safe Patient-friendly Emr Summaries with Gpt-4, PDF Tools and…

Generate Hipaa-safe Patient-friendly Emr Summaries with Gpt-4, PDF Tools and…

Original n8n title: Generate Hipaa-safe Patient-friendly Emr Summaries with Gpt-4, PDF Tools and Google Drive

ByJitesh Dugar @jiteshdugar on n8n.io

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…

Manual trigger★★★★☆ complexityAI-powered22 nodesHTTP RequestPostgresGoogle DriveTwilioEmail SendStop And ErrorN8N Nodes HtmlcsstopdfAgent
AI & RAG Trigger: Manual Nodes: 22 Complexity: ★★★★☆ AI nodes: yes Added:

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 →

Download .json
{
  "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.

Pro

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 →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

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

HTTP Request, Agent, OpenAI Chat +5
AI & RAG

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

Postgres, Agent, OpenAI Chat +7
AI & RAG

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

Google Sheets, HTTP Request, Slack +10
AI & RAG

f1_bot_zoom. Uses stopAndError, httpRequest, emailSend, agent. Webhook trigger; 39 nodes.

Stop And Error, HTTP Request, Email Send +3
AI & RAG

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

HTTP Request, Agent, OpenAI Chat +4