Medical device software vendors face one of the most complex regulatory environments in tech. A single missed FDA MDR report can trigger a Warning Letter. An EU MDR Article 87 serious incident not reported within 15 days can result in a Notified Body suspension. An ISO 13485:2016 §7.3.1 design validation gap can halt a 510(k) clearance.
This article gives you five production-ready n8n workflows — full JSON included — that SaMD companies, IVD software vendors, CTMS platforms, and clinical AI vendors can deploy to automate their FDA, EU MDR, ISO 13485, and HIPAA compliance operations.
Free templates at stripeai.gumroad.com — full bundle $97
Why MedDevice SaaS Vendors Are Buying Compliance Automation Now
The EU MDR transition deadline has passed. FDA's SaMD guidance under De Novo and 510(k) pathways now explicitly requires Software Bill of Materials (SBOM) and IEC 62304 lifecycle documentation. And HIPAA's information blocking rule means EHR-connected SaMD vendors face dual regulatory exposure.
For n8n, the self-hosted architecture is particularly valuable here: your FDA audit trail stays on your infrastructure, not inside Zapier's servers. When an FDA inspector requests 21 CFR Part 820 design history records or a Notified Body requests EU MDR Article 85 vigilance reports, the chain of custody is unbroken.
Workflow 1: MedDevice Customer Onboarding Drip
Target audience tiers:
-
ESTABLISHED_MED_DEVICE_OEM— legacy device company adopting SaMD -
STARTUP_SAMD_VENDOR— software-only medical device startup -
COMBINATION_PRODUCT_COMPANY— drug-device/biologic-device combos (FDA CDRH/CDER jurisdiction) -
IVD_MANUFACTURER— in vitro diagnostics under FDA 21 CFR Part 820 + EU IVDR -
CLINICAL_AI_VENDOR— AI/ML-based SaMD under FDA AI/ML Action Plan -
CTMS_PLATFORM— clinical trial management software vendors -
HOSPITAL_HEALTH_SYSTEM_IT— health system IT buying SaMD for internal deployment
Compliance flags:
-
FDA_510K_CLEARED— 510(k) substantial equivalence path -
EU_MDR_CERTIFIED— EU MDR 2017/745 Notified Body certification -
ISO_13485_CERTIFIED— ISO 13485:2016 QMS certified -
HIPAA_COVERED_ENTITY— HIPAA/HITECH covered entity or BAA required -
IEC_62304_REQUIRED— software lifecycle standard for medical device software -
IVDR_COMPLIANT— EU IVDR 2017/746 for in vitro diagnostics -
SOC2_REQUIRED— enterprise customer SOC 2 Type II requirement
Day 0: Tier-specific compliance checklist — 510(k) clearance letter download link, EU MDR Declaration of Conformity template, ISO 13485 design history file (DHF) setup guide, IEC 62304 software lifecycle documentation starter, HIPAA BAA execution link.
Day 3: Integration tips — FDA MDDS connectivity, EU MDR vigilance reporting API setup, ISO 13485 CAPA workflow config, IEC 62304 software item classification guide.
Day 7: Compliance walkthrough invite — live demo of FDA MDR 30-day clock automation.
{
"name": "MedDevice Customer Onboarding Drip",
"nodes": [
{
"id": "1",
"type": "n8n-nodes-base.webhook",
"name": "New Customer Webhook",
"parameters": {
"path": "meddevice-onboard",
"responseMode": "responseNode"
}
},
{
"id": "2",
"type": "n8n-nodes-base.switch",
"name": "Tier Router",
"parameters": {
"dataType": "string",
"value1": "={{ $json.customer_tier }}",
"rules": {
"rules": [
{
"value2": "ESTABLISHED_MED_DEVICE_OEM"
},
{
"value2": "STARTUP_SAMD_VENDOR"
},
{
"value2": "COMBINATION_PRODUCT_COMPANY"
},
{
"value2": "IVD_MANUFACTURER"
},
{
"value2": "CLINICAL_AI_VENDOR"
},
{
"value2": "CTMS_PLATFORM"
},
{
"value2": "HOSPITAL_HEALTH_SYSTEM_IT"
}
]
}
}
},
{
"id": "3",
"type": "n8n-nodes-base.set",
"name": "Build Day0 Email",
"parameters": {
"values": {
"string": [
{
"name": "subject",
"value": "Your MedDevice Compliance Starter Pack \u2014 {{ $json.company_name }}"
},
{
"name": "body",
"value": "Welcome to FlowKit, {{ $json.contact_name }}.\n\nBased on your profile ({{ $json.customer_tier }}), here is your Day 0 compliance checklist:\n\n{% if $json.flags.FDA_510K_CLEARED %}\u2705 FDA 510(k) Clearance Letter: [Download template]\n{% endif %}{% if $json.flags.EU_MDR_CERTIFIED %}\u2705 EU MDR Declaration of Conformity template: [Download]\n{% endif %}{% if $json.flags.ISO_13485_CERTIFIED %}\u2705 ISO 13485 Design History File (DHF) setup guide: [Download]\n{% endif %}{% if $json.flags.IEC_62304_REQUIRED %}\u2705 IEC 62304 Software Lifecycle Documentation starter: [Download]\n{% endif %}{% if $json.flags.HIPAA_COVERED_ENTITY %}\u2705 HIPAA BAA execution: [Sign here]\n{% endif %}\n\nYour CSM: {{ $json.csm_name }}"
}
]
}
}
},
{
"id": "4",
"type": "n8n-nodes-base.gmail",
"name": "Send Day0 Email",
"parameters": {
"operation": "send",
"to": "={{ $json.contact_email }}",
"subject": "={{ $json.subject }}",
"message": "={{ $json.body }}"
}
},
{
"id": "5",
"type": "n8n-nodes-base.wait",
"name": "Wait 3 Days",
"parameters": {
"unit": "days",
"amount": 3
}
},
{
"id": "6",
"type": "n8n-nodes-base.gmail",
"name": "Send Day3 Integration Tips",
"parameters": {
"operation": "send",
"to": "={{ $json.contact_email }}",
"subject": "Day 3: FDA MDDS + EU MDR Vigilance API Setup \u2014 {{ $json.company_name }}",
"message": "Hi {{ $json.contact_name }},\n\nIntegration tips for your tier:\n\n- FDA MDDS connectivity guide: [Link]\n- EU MDR vigilance reporting API setup: [Link]\n- ISO 13485 CAPA workflow config: [Link]\n- IEC 62304 software item classification guide: [Link]\n\nSlack us anytime."
}
},
{
"id": "7",
"type": "n8n-nodes-base.wait",
"name": "Wait 4 More Days",
"parameters": {
"unit": "days",
"amount": 4
}
},
{
"id": "8",
"type": "n8n-nodes-base.gmail",
"name": "Send Day7 Walkthrough Invite",
"parameters": {
"operation": "send",
"to": "={{ $json.contact_email }}",
"subject": "Live Demo: FDA MDR 30-Day Clock Automation \u2014 Book Your Slot",
"message": "Hi {{ $json.contact_name }},\n\nJoin our compliance walkthrough \u2014 live demo of the FDA MDR 30-day adverse event clock automation, EU MDR Article 87 vigilance pipeline, and ISO 13485 CAPA escalation workflows.\n\nBook: [Calendly link]\n\nAlso available: full n8n workflow templates at https://stripeai.gumroad.com"
}
}
],
"connections": {
"New Customer Webhook": {
"main": [
[
{
"node": "Tier Router"
}
]
]
},
"Tier Router": {
"main": [
[
{
"node": "Build Day0 Email"
}
]
]
},
"Build Day0 Email": {
"main": [
[
{
"node": "Send Day0 Email"
}
]
]
},
"Send Day0 Email": {
"main": [
[
{
"node": "Wait 3 Days"
}
]
]
},
"Wait 3 Days": {
"main": [
[
{
"node": "Send Day3 Integration Tips"
}
]
]
},
"Send Day3 Integration Tips": {
"main": [
[
{
"node": "Wait 4 More Days"
}
]
]
},
"Wait 4 More Days": {
"main": [
[
{
"node": "Send Day7 Walkthrough Invite"
}
]
]
}
}
}
Workflow 2: FDA/EU MDR Validated System Health Monitor
Polls your critical SaMD APIs every 5 minutes. Any DOWN event triggers an immediate CISO + Regulatory Affairs alert with the specific FDA/EU MDR citation at risk.
Why this matters: Under FDA 21 CFR Part 820 §820.70(i) and EU MDR Article 87, an unmonitored SaMD API outage that affects patient safety data collection can constitute a reportable malfunction. A timestamped monitoring log is your first line of defense in any audit.
{
"name": "MedDevice Validated System Health Monitor",
"nodes": [
{
"id": "1",
"type": "n8n-nodes-base.scheduleTrigger",
"name": "Every 5 Minutes",
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 5
}
]
}
}
},
{
"id": "2",
"type": "n8n-nodes-base.httpRequest",
"name": "Check FDA MDR Reporting API",
"parameters": {
"url": "https://your-samd-platform.com/api/fda-mdr-reporting/health",
"method": "GET",
"timeout": 10000
}
},
{
"id": "3",
"type": "n8n-nodes-base.httpRequest",
"name": "Check EU MDR Vigilance API",
"parameters": {
"url": "https://your-samd-platform.com/api/eu-mdr-vigilance/health",
"method": "GET",
"timeout": 10000
}
},
{
"id": "4",
"type": "n8n-nodes-base.httpRequest",
"name": "Check ISO 13485 CAPA API",
"parameters": {
"url": "https://your-samd-platform.com/api/capa-management/health",
"method": "GET",
"timeout": 10000
}
},
{
"id": "5",
"type": "n8n-nodes-base.httpRequest",
"name": "Check IEC 62304 Audit Trail API",
"parameters": {
"url": "https://your-samd-platform.com/api/software-lifecycle-audit/health",
"method": "GET",
"timeout": 10000
}
},
{
"id": "6",
"type": "n8n-nodes-base.httpRequest",
"name": "Check HIPAA BAA Data API",
"parameters": {
"url": "https://your-samd-platform.com/api/hipaa-phi-handler/health",
"method": "GET",
"timeout": 10000
}
},
{
"id": "7",
"type": "n8n-nodes-base.code",
"name": "Detect State Changes",
"parameters": {
"jsCode": "const endpoints = [\n { name: 'fda_mdr_reporting_api', status: $('Check FDA MDR Reporting API').first()?.json?.status || 'DOWN', citation: 'FDA 21 CFR Part 820 \u00a7820.198 \u2014 MDR reporting malfunction risk' },\n { name: 'eu_mdr_vigilance_api', status: $('Check EU MDR Vigilance API').first()?.json?.status || 'DOWN', citation: 'EU MDR Art.87 \u2014 serious incident 15-day clock at risk' },\n { name: 'iso_13485_capa_api', status: $('Check ISO 13485 CAPA API').first()?.json?.status || 'DOWN', citation: 'ISO 13485:2016 \u00a78.5.2 \u2014 CAPA system unavailable' },\n { name: 'iec_62304_audit_trail_api', status: $('Check IEC 62304 Audit Trail API').first()?.json?.status || 'DOWN', citation: 'IEC 62304 \u00a75.1.9 \u2014 software lifecycle audit trail gap' },\n { name: 'hipaa_baa_data_api', status: $('Check HIPAA BAA Data API').first()?.json?.status || 'DOWN', citation: 'HIPAA \u00a7164.312(b) \u2014 audit control failure' }\n];\nconst state = $getWorkflowStaticData('global');\nconst now = new Date().toISOString();\nconst alerts = [];\nfor (const ep of endpoints) {\n const prev = state[ep.name] || 'UP';\n if (prev === 'UP' && ep.status !== 'UP') alerts.push({...ep, transitioned: 'UP\u2192DOWN', ts: now});\n state[ep.name] = ep.status;\n}\nreturn alerts.length ? alerts.map(a => ({json: a})) : [{json: {no_alerts: true}}];"
}
},
{
"id": "8",
"type": "n8n-nodes-base.filter",
"name": "Only Real Alerts",
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.no_alerts }}",
"operation": "notEqual",
"value2": "true"
}
]
}
}
},
{
"id": "9",
"type": "n8n-nodes-base.gmail",
"name": "Alert CISO + Regulatory Affairs",
"parameters": {
"operation": "send",
"to": "ciso@your-company.com",
"cc": "regulatory-affairs@your-company.com",
"subject": "\ud83d\udea8 MedDevice API DOWN: {{ $json.name }} \u2014 {{ $json.citation }}",
"message": "ALERT: {{ $json.name }} transitioned {{ $json.transitioned }} at {{ $json.ts }}\n\nRegulatory Risk: {{ $json.citation }}\n\nImmediate action required per your Quality Management System."
}
}
],
"connections": {
"Every 5 Minutes": {
"main": [
[
{
"node": "Check FDA MDR Reporting API"
},
{
"node": "Check EU MDR Vigilance API"
},
{
"node": "Check ISO 13485 CAPA API"
},
{
"node": "Check IEC 62304 Audit Trail API"
},
{
"node": "Check HIPAA BAA Data API"
}
]
]
},
"Check HIPAA BAA Data API": {
"main": [
[
{
"node": "Detect State Changes"
}
]
]
},
"Detect State Changes": {
"main": [
[
{
"node": "Only Real Alerts"
}
]
]
},
"Only Real Alerts": {
"main": [
[
{
"node": "Alert CISO + Regulatory Affairs"
}
]
]
}
}
}
Workflow 3: FDA/EU MDR Compliance Deadline Tracker
Runs every weekday at 8AM. Queries your deadlines from Postgres. Routes by severity. Deduplicates alerts with alert_sent_date so you get one alert per event, not a daily flood.
12 deadline types tracked:
| Type | Regulation | Notes |
|---|---|---|
FDA_510K_ANNUAL_REPORT |
21 CFR §814.84 | PMA annual report |
EU_MDR_NOTIFIED_BODY_AUDIT |
EU MDR Art.45 | Annual NB surveillance |
ISO_13485_SURVEILLANCE_AUDIT |
ISO 13485:2016 §8.2.4 | Annual surveillance |
IEC_62304_SOFTWARE_LIFECYCLE_REVIEW |
IEC 62304 §5.1 | Annual lifecycle review |
FDA_MDR_MALFUNCTION_REPORT_30DAY |
21 CFR §803.50 | 30-day MDR deadline |
EU_MDR_SERIOUS_INCIDENT_15DAY |
EU MDR Art.87(3) | 15-day vigilance report |
HIPAA_SECURITY_RISK_ANALYSIS_ANNUAL |
45 CFR §164.308(a)(1) | Annual SRA |
SOC2_TYPE2_RENEWAL |
AICPA TSP §100 | Annual SOC 2 |
FDA_DEVICE_REGISTRATION_ANNUAL |
21 CFR §807.21 | Annual device listing |
EU_MDR_DECLARATION_OF_CONFORMITY_REVIEW |
EU MDR Art.19 | Annual DoC review |
IVDR_NOTIFIED_BODY_AUDIT |
EU IVDR Art.54 | IVD NB annual audit |
ANNUAL_PENETRATION_TEST |
FDA Cybersecurity 2023 Guidance | FDA SaMD cybersecurity |
{
"name": "FDA/EU MDR Compliance Deadline Tracker",
"nodes": [
{
"id": "1",
"type": "n8n-nodes-base.scheduleTrigger",
"name": "Weekdays 8AM",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1-5"
}
]
}
}
},
{
"id": "2",
"type": "n8n-nodes-base.postgres",
"name": "Query Deadlines",
"parameters": {
"operation": "executeQuery",
"query": "SELECT deadline_type, deadline_date, customer_name, customer_email, alert_sent_date FROM meddevice_compliance_deadlines WHERE deadline_date <= CURRENT_DATE + INTERVAL '90 days' AND is_resolved = false ORDER BY deadline_date ASC"
}
},
{
"id": "3",
"type": "n8n-nodes-base.code",
"name": "Classify Severity",
"parameters": {
"jsCode": "const today = new Date(); const items = $input.all();\nreturn items.map(item => {\n const d = item.json;\n const daysOut = Math.floor((new Date(d.deadline_date) - today) / 86400000);\n const lastSent = d.alert_sent_date ? new Date(d.alert_sent_date) : null;\n const daysSinceSent = lastSent ? Math.floor((today - lastSent) / 86400000) : 999;\n let severity = 'NOTICE';\n if (daysOut < 0) severity = 'OVERDUE';\n else if (daysOut <= 14) severity = 'CRITICAL';\n else if (daysOut <= 30) severity = 'URGENT';\n else if (daysOut <= 60) severity = 'WARNING';\n const shouldAlert = severity === 'OVERDUE' ? daysSinceSent >= 1 : severity === 'CRITICAL' ? daysSinceSent >= 3 : severity === 'URGENT' ? daysSinceSent >= 7 : daysSinceSent >= 30;\n return { json: {...d, daysOut, severity, shouldAlert} };\n})"
}
},
{
"id": "4",
"type": "n8n-nodes-base.filter",
"name": "Filter Actionable",
"parameters": {
"conditions": {
"boolean": [
{
"value1": "={{ $json.shouldAlert }}",
"value2": true
}
]
}
}
},
{
"id": "5",
"type": "n8n-nodes-base.gmail",
"name": "Send Alert",
"parameters": {
"operation": "send",
"to": "={{ $json.customer_email }}",
"cc": "regulatory-affairs@your-company.com",
"subject": "[{{ $json.severity }}] {{ $json.deadline_type }} due {{ $json.deadline_date }} \u2014 {{ $json.customer_name }}",
"message": "Compliance deadline approaching:\n\nType: {{ $json.deadline_type }}\nCustomer: {{ $json.customer_name }}\nDue: {{ $json.deadline_date }} ({{ $json.daysOut }} days)\nSeverity: {{ $json.severity }}\n\nAction required per your Quality Management System."
}
}
],
"connections": {
"Weekdays 8AM": {
"main": [
[
{
"node": "Query Deadlines"
}
]
]
},
"Query Deadlines": {
"main": [
[
{
"node": "Classify Severity"
}
]
]
},
"Classify Severity": {
"main": [
[
{
"node": "Filter Actionable"
}
]
]
},
"Filter Actionable": {
"main": [
[
{
"node": "Send Alert"
}
]
]
}
}
}
Workflow 4: Medical Device Adverse Event & Vigilance Incident Pipeline
Webhook-triggered. Accepts adverse event reports from your SaMD platform and routes by regulatory clock urgency.
8 incident types with response deadlines:
| Type | Clock | Regulation |
|---|---|---|
FDA_MDR_MALFUNCTION_30DAY |
720 hours | 21 CFR §803.50 — malfunction likely to cause/contribute to serious injury |
FDA_MDR_SERIOUS_INJURY_30DAY |
720 hours | 21 CFR §803.50 — serious injury report |
FDA_MDR_DEATH_5DAY |
120 hours | 21 CFR §803.53 — death or life-threatening injury |
EU_MDR_SERIOUS_INCIDENT_15DAY |
360 hours | EU MDR Art.87(3) — serious incident to Competent Authority |
EU_MDR_FSCA_10DAY |
240 hours | EU MDR Art.89 — Field Safety Corrective Action notification |
ISO_13485_CAPA_INITIATION |
48 hours | ISO 13485:2016 §8.5.2 — CAPA must be initiated |
HIPAA_PHI_BREACH_72HR |
72 hours | HIPAA §164.400 — breach notification to HHS OCR |
FDA_RECALL_CLASS_1_24HR |
24 hours | 21 CFR §7.40 — Class I recall (risk of serious adverse health consequences) |
{
"name": "MedDevice Adverse Event & Vigilance Incident Pipeline",
"nodes": [
{
"id": "1",
"type": "n8n-nodes-base.webhook",
"name": "Adverse Event Webhook",
"parameters": {
"path": "meddevice-adverse-event",
"responseMode": "responseNode"
}
},
{
"id": "2",
"type": "n8n-nodes-base.code",
"name": "Set Response Deadline",
"parameters": {
"jsCode": "const clocks = {\n 'FDA_MDR_MALFUNCTION_30DAY': { hours: 720, reg: '21 CFR \u00a7803.50 \u2014 malfunction 30-day MDR', authority: 'FDA MedWatch' },\n 'FDA_MDR_SERIOUS_INJURY_30DAY': { hours: 720, reg: '21 CFR \u00a7803.50 \u2014 serious injury 30-day MDR', authority: 'FDA MedWatch' },\n 'FDA_MDR_DEATH_5DAY': { hours: 120, reg: '21 CFR \u00a7803.53 \u2014 death/life-threatening 5-day MDR', authority: 'FDA MedWatch PRIORITY' },\n 'EU_MDR_SERIOUS_INCIDENT_15DAY': { hours: 360, reg: 'EU MDR Art.87(3) \u2014 serious incident Competent Authority', authority: 'EU Competent Authority + EUDAMED' },\n 'EU_MDR_FSCA_10DAY': { hours: 240, reg: 'EU MDR Art.89 \u2014 FSCA field safety corrective action', authority: 'EU Competent Authority + Field Notice' },\n 'ISO_13485_CAPA_INITIATION': { hours: 48, reg: 'ISO 13485:2016 \u00a78.5.2 \u2014 CAPA must be initiated within 48h', authority: 'QMS CAPA System' },\n 'HIPAA_PHI_BREACH_72HR': { hours: 72, reg: 'HIPAA \u00a7164.400 + \u00a7164.404 \u2014 breach notification HHS OCR', authority: 'HHS OCR + Affected Individuals' },\n 'FDA_RECALL_CLASS_1_24HR': { hours: 24, reg: '21 CFR \u00a77.40 \u2014 Class I recall serious adverse health consequences', authority: 'FDA CDRH + Public Notice' }\n};\nconst t = $json.incident_type;\nconst clock = clocks[t] || { hours: 72, reg: 'Unknown incident type \u2014 default 72h', authority: 'Regulatory Affairs' };\nconst deadline = new Date(Date.now() + clock.hours * 3600000).toISOString();\nreturn [{ json: { ...$json, response_hours: clock.hours, response_deadline: deadline, regulation: clock.reg, reporting_authority: clock.authority, incident_id: 'INC-' + Date.now() } }];"
}
},
{
"id": "3",
"type": "n8n-nodes-base.postgres",
"name": "Log to Incident DB",
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO meddevice_incidents (incident_id, incident_type, device_id, patient_id, occurred_at, response_deadline, regulation, reporting_authority, severity, received_at) VALUES ('{{ $json.incident_id }}', '{{ $json.incident_type }}', '{{ $json.device_id }}', '{{ $json.patient_id }}', '{{ $json.occurred_at }}', '{{ $json.response_deadline }}', '{{ $json.regulation }}', '{{ $json.reporting_authority }}', '{{ $json.severity }}', NOW()) ON CONFLICT (incident_id) DO NOTHING"
}
},
{
"id": "4",
"type": "n8n-nodes-base.respondToWebhook",
"name": "ACK 200",
"parameters": {
"respondWith": "json",
"responseBody": "={{ JSON.stringify({ status: 'received', incident_id: $json.incident_id, response_deadline: $json.response_deadline, response_hours: $json.response_hours, regulation: $json.regulation }) }}"
}
},
{
"id": "5",
"type": "n8n-nodes-base.gmail",
"name": "Alert Regulatory Affairs + CISO",
"parameters": {
"operation": "send",
"to": "regulatory-affairs@your-company.com",
"cc": "ciso@your-company.com,quality@your-company.com",
"subject": "\ud83d\udea8 [{{ $json.incident_type }}] Response deadline: {{ $json.response_deadline }} \u2014 {{ $json.incident_id }}",
"message": "MEDICAL DEVICE INCIDENT ALERT\n\nIncident ID: {{ $json.incident_id }}\nType: {{ $json.incident_type }}\nDevice: {{ $json.device_id }}\nOccurred: {{ $json.occurred_at }}\nSeverity: {{ $json.severity }}\n\nResponse Required: {{ $json.response_hours }} hours\nDeadline: {{ $json.response_deadline }}\nRegulation: {{ $json.regulation }}\nReporting Authority: {{ $json.reporting_authority }}\n\nInitiate QMS CAPA immediately. Log all actions in Design History File."
}
}
],
"connections": {
"Adverse Event Webhook": {
"main": [
[
{
"node": "Set Response Deadline"
}
]
]
},
"Set Response Deadline": {
"main": [
[
{
"node": "Log to Incident DB"
},
{
"node": "ACK 200"
},
{
"node": "Alert Regulatory Affairs + CISO"
}
]
]
}
}
}
Workflow 5: Weekly MedDevice Vendor KPI Dashboard
Runs every Monday at 8AM. Pulls dual Postgres queries — platform metrics by customer tier + compliance event counts. Sends HTML dashboard to CEO and Chief Regulatory Officer with CISO BCC.
Subject-line compliance flags:
-
[FDA MDR OVERDUE]— MDR report past 30-day or 5-day deadline -
[EU MDR VIGILANCE OVERDUE]— EU MDR Art.87 15-day clock missed -
[ISO 13485 CAPA OPEN]— open CAPA items per §8.5.2 -
[RECALL OPEN]— active Class I/II recall
{
"name": "Weekly MedDevice Vendor KPI Dashboard",
"nodes": [
{
"id": "1",
"type": "n8n-nodes-base.scheduleTrigger",
"name": "Every Monday 8AM",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
}
},
{
"id": "2",
"type": "n8n-nodes-base.postgres",
"name": "Platform Metrics",
"parameters": {
"operation": "executeQuery",
"query": "SELECT customer_tier, COUNT(*) as customers, SUM(mrr_usd) as total_mrr, AVG(api_uptime_7d) as avg_uptime, COUNT(*) FILTER (WHERE fda_mdr_status = 'ACTIVE') as active_mdr_reports, COUNT(*) FILTER (WHERE eu_mdr_status = 'ACTIVE') as active_eu_vigilance FROM meddevice_customers WHERE status = 'active' GROUP BY customer_tier ORDER BY total_mrr DESC"
}
},
{
"id": "3",
"type": "n8n-nodes-base.postgres",
"name": "Compliance Events",
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(*) FILTER (WHERE incident_type LIKE 'FDA_MDR%' AND response_deadline < NOW() AND resolved = false) as fda_mdr_overdue, COUNT(*) FILTER (WHERE incident_type LIKE 'EU_MDR%' AND response_deadline < NOW() AND resolved = false) as eu_mdr_overdue, COUNT(*) FILTER (WHERE incident_type = 'ISO_13485_CAPA_INITIATION' AND resolved = false) as capa_open, COUNT(*) FILTER (WHERE incident_type LIKE 'FDA_RECALL%' AND resolved = false) as recalls_open, COUNT(*) FILTER (WHERE created_at >= NOW() - INTERVAL '7 days') as incidents_this_week FROM meddevice_incidents"
}
},
{
"id": "4",
"type": "n8n-nodes-base.code",
"name": "Build HTML Report",
"parameters": {
"jsCode": "const platform = $('Platform Metrics').all();\nconst compliance = $('Compliance Events').first().json;\nconst flags = [];\nif (compliance.fda_mdr_overdue > 0) flags.push('[FDA MDR OVERDUE]');\nif (compliance.eu_mdr_overdue > 0) flags.push('[EU MDR VIGILANCE OVERDUE]');\nif (compliance.capa_open > 0) flags.push('[ISO 13485 CAPA OPEN]');\nif (compliance.recalls_open > 0) flags.push('[RECALL OPEN]');\nconst subject = (flags.length ? flags.join(' ') + ' ' : '') + 'Weekly MedDevice KPI \u2014 ' + new Date().toISOString().slice(0,10);\nconst rows = platform.map(r => `<tr><td>${r.json.customer_tier}</td><td>${r.json.customers}</td><td>$${Number(r.json.total_mrr).toLocaleString()}</td><td>${Number(r.json.avg_uptime).toFixed(2)}%</td><td>${r.json.active_mdr_reports}</td><td>${r.json.active_eu_vigilance}</td></tr>`).join('');\nconst html = `<h2>MedDevice Vendor KPI \u2014 ${new Date().toISOString().slice(0,10)}</h2><h3>Platform by Tier</h3><table border='1' cellpadding='5'><tr><th>Tier</th><th>Customers</th><th>MRR</th><th>API Uptime 7d</th><th>FDA MDR Active</th><th>EU MDR Active</th></tr>${rows}</table><h3>Compliance Events</h3><table border='1' cellpadding='5'><tr><th>FDA MDR Overdue</th><th>EU MDR Overdue</th><th>CAPA Open</th><th>Recalls Open</th><th>Incidents This Week</th></tr><tr><td>${compliance.fda_mdr_overdue}</td><td>${compliance.eu_mdr_overdue}</td><td>${compliance.capa_open}</td><td>${compliance.recalls_open}</td><td>${compliance.incidents_this_week}</td></tr></table><p><em>FDA 21 CFR \u00a7820.198 + EU MDR Art.87 + ISO 13485:2016 \u00a78.5.2 | n8n FlowKit | stripeai.gumroad.com</em></p>`;\nreturn [{ json: { subject, html } }];"
}
},
{
"id": "5",
"type": "n8n-nodes-base.gmail",
"name": "Send to CEO + CRO",
"parameters": {
"operation": "send",
"to": "ceo@your-company.com,regulatory-affairs@your-company.com",
"cc": "ciso@your-company.com",
"subject": "={{ $json.subject }}",
"message": "={{ $json.html }}",
"options": {
"htmlBody": true
}
}
}
],
"connections": {
"Every Monday 8AM": {
"main": [
[
{
"node": "Platform Metrics"
},
{
"node": "Compliance Events"
}
]
]
},
"Compliance Events": {
"main": [
[
{
"node": "Build HTML Report"
}
]
]
},
"Build HTML Report": {
"main": [
[
{
"node": "Send to CEO + CRO"
}
]
]
}
}
}
Self-Hosting Advantage for MedDevice SaaS Vendors
| Scenario | Cloud iPaaS Risk | Self-Hosted n8n |
|---|---|---|
| FDA Design History File (DHF) | Third-party audit log in vendor's infra | DHF chain of custody stays on your QMS server |
| EU MDR Art.85 vigilance records | Notified Body audit accesses third-party system | All EUDAMED records in your validated environment |
| HIPAA BAA PHI | Zapier/Make = additional BAA required, chain expands | Self-hosted = no additional BAA for workflow engine |
| IEC 62304 validation | Must validate the entire cloud iPaaS stack | Validate only your n8n instance (bounded scope) |
| 21 CFR Part 11 audit trail | Vendor's immutable log system (third-party) | Your immutable log, your server, your chain of custody |
5 Questions MedDevice SaaS Buyers Ask Before Signing
Q: Our FDA 510(k) requires a validated software environment — does running workflows through your iPaaS expand our validation scope?
A: Self-hosted n8n (single Docker container) has a well-defined validation boundary. You validate the n8n instance per your QMS SOPs. Cloud iPaaS platforms require you to validate a system you do not control — FDA expects documented evidence of your validation methodology including the iPaaS vendor's SOC 2 Type II and their own validation documentation.
Q: EU MDR Article 87 requires serious incident reports within 15 days. Can our automation guarantee that clock doesn't slip?
A: The EU_MDR_SERIOUS_INCIDENT_15DAY workflow above starts the clock the moment the webhook fires. The ACK response returns response_deadline as a timestamp. Your QMS can track that timestamp independently of the automation — the clock is set on intake, not on alert delivery.
Q: We're under HIPAA BAA with our hospital customers. Does adding n8n to the stack add another BAA party?
A: Self-hosted n8n processes PHI on infrastructure you control under your existing BAA with your cloud provider. It does not introduce a new Business Associate. Cloud-hosted iPaaS platforms are typically Business Associates and require their own BAA — expanding your subcontractor chain.
Q: How does IEC 62304 §5.1.9 apply to our n8n automation workflows?
A: Under IEC 62304, your n8n automation workflows are software items. You classify them (Class A/B/C based on patient safety impact), maintain change control via version control (git-backed workflows), and document your validation approach in your Software Development Plan. The IEC 62304 audit trail workflow above logs all workflow changes to your QMS — this is your validation evidence.
Q: We had an ISO 13485 surveillance audit where the auditor asked for CAPA traceability back to root cause. How does your workflow handle that?
A: The ISO 13485 CAPA initiation workflow creates a capa_id tied to the originating incident. Every subsequent action (root cause documented, corrective action implemented, effectiveness verified) is logged in your Postgres table with the same capa_id. Your auditor gets a single SQL query that shows the full CAPA lifecycle — initiation to closure.
Get the Full Workflow Bundle
All 5 workflows above are available as import-ready JSON at stripeai.gumroad.com. Individual templates $12–$29. Full bundle (all 14 templates) at $97.
MedDevice SaaS vendors — what's your biggest compliance automation bottleneck? Drop it in the comments.
Top comments (0)