If you're building SaaS for pharma, biotech, CROs, or clinical trial management, your customers live inside some of the most regulated software environments on the planet.
FDA 21 CFR Part 11. EU GMP Annex 11. ICH E6(R2) GCP. GDPR Art.9 for genetic and health data. 21 CFR Part 820 QSR.
The problem with cloud automation platforms (Zapier, Make) in GxP environments isn't just security — it's audit trail architecture.
FDA 21 CFR §11.10(e) requires an audit trail for every electronic record your validated system creates, modifies, or deletes. When you route that data through a cloud iPaaS, every webhook handler, every HTTP request, every filter step generates execution logs on the vendor's servers — outside your validated system boundary.
FDA inspectors can request audit trail records on the day of inspection. 'We don't have those logs — they're on Zapier's servers' is not an acceptable Part 11 response.
Self-hosted n8n keeps the entire automation execution log inside your GxP environment — behind your audit trail boundary, inside your validated system.
Here are 5 production-ready workflow templates for BioTech/LifeSciences SaaS vendors. Full JSON included.
The BioTech/LifeSciences SaaS Vendor Tier Matrix
| Tier | Example Products | Primary Regulations |
|---|---|---|
| PHARMA_SAAS_VENDOR | Drug development platforms, submission management | FDA 21 CFR Part 11, Part 312 IND, EU CTR |
| CONTRACT_RESEARCH_ORG_SAAS | CRO data platforms, EDC systems | ICH E6(R2) GCP, 21 CFR §312, EU GMP Annex 11 |
| CLINICAL_TRIAL_MANAGEMENT_SAAS | CTMS, randomization systems | FDA §312.32 IND safety reporting, ICH E8 |
| BIOTECH_LAB_SAAS | LIMS, ELN, laboratory data management | FDA 21 CFR Part 11, ISO 17025, 21 CFR Part 58 |
| MEDICAL_DEVICE_SAAS | QMS, MDM, post-market surveillance | FDA 21 CFR §820 QSR, EU MDR 2017/745 |
| GENOMICS_BIOINFORMATICS_SAAS | Genomics platforms, variant analysis | GDPR Art.9 genetic data, HIPAA §164.312 |
| LIFESCIENCES_STARTUP | Pre-IND, early clinical, Series A/B | Foundation: 21 CFR Part 11 architecture |
7 Compliance Flags:
-
FDA_21_CFR_PART_11_SUBJECT— electronic records and signatures -
EU_GMP_ANNEX_11_APPLICABLE— computerized systems managing GxP data -
ICH_E6_GCP_CLINICAL_TRIAL— Good Clinical Practice, trial master file -
HIPAA_PHI_PROCESSOR— protected health information in automation layer -
GDPR_ART9_SPECIAL_CATEGORY— health and genetic data, highest protection tier -
FDA_820_QSR_DEVICE— automated quality management system -
ISO_17025_ACCREDITED_LAB— laboratory measurement traceability
Workflow 1: Tier-Segmented Customer Onboarding Drip
Triggers hourly, reads pending customers from Google Sheets, routes each to a tier-specific onboarding email with the correct FDA/ICH/GDPR compliance note.
{
"name": "BioTech/LifeSciences SaaS \u2014 Tier-Segmented Customer Onboarding Drip",
"nodes": [
{
"id": "n1",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 1
}
]
}
}
},
{
"id": "n2",
"name": "Read New Customers",
"type": "n8n-nodes-base.googleSheets",
"position": [
460,
300
],
"parameters": {
"operation": "readRows",
"sheetId": "YOUR_SHEET_ID",
"range": "customers!A:L",
"filters": {
"conditions": [
{
"leftValue": "={{$json.onboarding_status}}",
"condition": "equals",
"rightValue": "pending"
}
]
}
}
},
{
"id": "n3",
"name": "Set Tier Context",
"type": "n8n-nodes-base.code",
"position": [
680,
300
],
"parameters": {
"jsCode": "const tier=item.json.tier_code||'LIFESCIENCES_STARTUP';\nconst flags=(item.json.compliance_flags||'').split(',').map(f=>f.trim());\nconst tierNotes={\n PHARMA_SAAS_VENDOR:'FDA 21 CFR Part 11 \u00a711.10(e) audit trail applies to all electronic records your platform creates. Zapier/Make task logs = undiscovered audit trail entries in your validated system boundary.',\n CONTRACT_RESEARCH_ORG_SAAS:'ICH E6(R2) \u00a75.5 essential documents + \u00a78.3 trial master file \u2014 automation platform logs that touch trial data must be inside your TMF audit trail boundary.',\n CLINICAL_TRIAL_MANAGEMENT_SAAS:'FDA 21 CFR \u00a7312.32 IND safety reporting: fatal/life-threatening SUSAR = 7 calendar days; serious unexpected = 15 calendar days. Protocol deviation management must preserve audit trail.',\n BIOTECH_LAB_SAAS:'FDA 21 CFR Part 11 + ISO 17025 \u00a77.11 metrological traceability \u2014 LIMS/ELN data integrity chain must remain unbroken through any automation layer.',\n MEDICAL_DEVICE_SAAS:'FDA 21 CFR \u00a7820.70(i) automated data processing requires documented quality assurance. \u00a7820.30 design control applies to software embedded in QMS workflow.',\n GENOMICS_BIOINFORMATICS_SAAS:'GDPR Art.9 genetic data + Art.46 international transfer safeguards. US cloud iPaaS processing EU patient genomic data = transfer without adequacy decision post-Schrems II.',\n LIFESCIENCES_STARTUP:'Pre-IND teams: establish 21 CFR Part 11 audit trail architecture before first IND submission. Retroactive validation is significantly more expensive.'\n};\nreturn [{json:{...item.json,tier_code:tier,compliance_note:tierNotes[tier]||tierNotes['LIFESCIENCES_STARTUP'],has_phi:flags.includes('HIPAA_PHI_PROCESSOR'),is_gcp:flags.includes('ICH_E6_GCP_CLINICAL_TRIAL'),is_part11:flags.includes('FDA_21_CFR_PART_11_SUBJECT')}}];\n"
}
},
{
"id": "n4",
"name": "Switch on Tier",
"type": "n8n-nodes-base.switch",
"position": [
900,
300
],
"parameters": {
"dataType": "string",
"value": "={{$json.tier_code}}",
"rules": {
"rules": [
{
"value": "PHARMA_SAAS_VENDOR",
"output": 0
},
{
"value": "CONTRACT_RESEARCH_ORG_SAAS",
"output": 1
},
{
"value": "CLINICAL_TRIAL_MANAGEMENT_SAAS",
"output": 2
},
{
"value": "BIOTECH_LAB_SAAS",
"output": 3
},
{
"value": "MEDICAL_DEVICE_SAAS",
"output": 4
},
{
"value": "GENOMICS_BIOINFORMATICS_SAAS",
"output": 5
}
]
},
"fallbackOutput": 6
}
},
{
"id": "n5",
"name": "Pharma Welcome Email",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
100
],
"parameters": {
"operation": "send",
"to": "={{$json.contact_email}}",
"subject": "Welcome to FlowKit \u2014 Your FDA 21 CFR Part 11 Onboarding Guide",
"message": "<p>Hi {{$json.company_name}},</p><p>Welcome to FlowKit. Your platform tier ({{$json.tier_code}}) activates our FDA 21 CFR Part 11 onboarding track.</p><p><strong>Your compliance note:</strong> {{$json.compliance_note}}</p><p>Your FlowKit templates are pre-configured to keep automation execution logs inside your validated system boundary \u2014 no audit trail gap.</p><p>Book your technical onboarding call: <a href='https://cal.com/flowkithq'>cal.com/flowkithq</a></p>"
}
},
{
"id": "n6",
"name": "CRO Welcome Email",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
200
],
"parameters": {
"operation": "send",
"to": "={{$json.contact_email}}",
"subject": "Welcome to FlowKit \u2014 ICH E6(R2) GCP Onboarding Track",
"message": "<p>Hi {{$json.company_name}},</p><p>Your CRO platform tier activates the ICH E6(R2) GCP track. {{$json.compliance_note}}</p><p>Book onboarding: <a href='https://cal.com/flowkithq'>cal.com/flowkithq</a></p>"
}
},
{
"id": "n7",
"name": "CTMS Welcome Email",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
300
],
"parameters": {
"operation": "send",
"to": "={{$json.contact_email}}",
"subject": "Welcome to FlowKit \u2014 Clinical Trial IND Safety Reporting Track",
"message": "<p>Hi {{$json.company_name}},</p><p>{{$json.compliance_note}}</p><p>Book onboarding: <a href='https://cal.com/flowkithq'>cal.com/flowkithq</a></p>"
}
},
{
"id": "n8",
"name": "LIMS Welcome Email",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
400
],
"parameters": {
"operation": "send",
"to": "={{$json.contact_email}}",
"subject": "Welcome to FlowKit \u2014 21 CFR Part 11 + ISO 17025 Lab Onboarding",
"message": "<p>Hi {{$json.company_name}},</p><p>{{$json.compliance_note}}</p><p>Book onboarding: <a href='https://cal.com/flowkithq'>cal.com/flowkithq</a></p>"
}
},
{
"id": "n9",
"name": "MDM Welcome Email",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
500
],
"parameters": {
"operation": "send",
"to": "={{$json.contact_email}}",
"subject": "Welcome to FlowKit \u2014 FDA 820 QSR Device Quality Track",
"message": "<p>Hi {{$json.company_name}},</p><p>{{$json.compliance_note}}</p><p>Book onboarding: <a href='https://cal.com/flowkithq'>cal.com/flowkithq</a></p>"
}
},
{
"id": "n10",
"name": "Genomics Welcome Email",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
600
],
"parameters": {
"operation": "send",
"to": "={{$json.contact_email}}",
"subject": "Welcome to FlowKit \u2014 GDPR Art.9 Genomic Data Onboarding Track",
"message": "<p>Hi {{$json.company_name}},</p><p>{{$json.compliance_note}}</p><p>Book onboarding: <a href='https://cal.com/flowkithq'>cal.com/flowkithq</a></p>"
}
},
{
"id": "n11",
"name": "Startup Welcome Email",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
700
],
"parameters": {
"operation": "send",
"to": "={{$json.contact_email}}",
"subject": "Welcome to FlowKit \u2014 LifeSciences Startup Track",
"message": "<p>Hi {{$json.company_name}},</p><p>{{$json.compliance_note}}</p><p>Book onboarding: <a href='https://cal.com/flowkithq'>cal.com/flowkithq</a></p>"
}
},
{
"id": "n12",
"name": "Mark Onboarded",
"type": "n8n-nodes-base.googleSheets",
"position": [
1340,
400
],
"parameters": {
"operation": "updateRow",
"sheetId": "YOUR_SHEET_ID",
"range": "customers",
"rowNumberToUpdate": "={{$json.row_number}}",
"data": {
"onboarding_status": "sent",
"onboarding_ts": "={{new Date().toISOString()}}"
}
}
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Read New Customers",
"type": "main",
"index": 0
}
]
]
},
"Read New Customers": {
"main": [
[
{
"node": "Set Tier Context",
"type": "main",
"index": 0
}
]
]
},
"Set Tier Context": {
"main": [
[
{
"node": "Switch on Tier",
"type": "main",
"index": 0
}
]
]
},
"Switch on Tier": {
"main": [
[
{
"node": "Pharma Welcome Email",
"type": "main",
"index": 0
}
],
[
{
"node": "CRO Welcome Email",
"type": "main",
"index": 0
}
],
[
{
"node": "CTMS Welcome Email",
"type": "main",
"index": 0
}
],
[
{
"node": "LIMS Welcome Email",
"type": "main",
"index": 0
}
],
[
{
"node": "MDM Welcome Email",
"type": "main",
"index": 0
}
],
[
{
"node": "Genomics Welcome Email",
"type": "main",
"index": 0
}
],
[
{
"node": "Startup Welcome Email",
"type": "main",
"index": 0
}
]
]
},
"Pharma Welcome Email": {
"main": [
[
{
"node": "Mark Onboarded",
"type": "main",
"index": 0
}
]
]
},
"CRO Welcome Email": {
"main": [
[
{
"node": "Mark Onboarded",
"type": "main",
"index": 0
}
]
]
},
"CTMS Welcome Email": {
"main": [
[
{
"node": "Mark Onboarded",
"type": "main",
"index": 0
}
]
]
},
"LIMS Welcome Email": {
"main": [
[
{
"node": "Mark Onboarded",
"type": "main",
"index": 0
}
]
]
},
"MDM Welcome Email": {
"main": [
[
{
"node": "Mark Onboarded",
"type": "main",
"index": 0
}
]
]
},
"Genomics Welcome Email": {
"main": [
[
{
"node": "Mark Onboarded",
"type": "main",
"index": 0
}
]
]
},
"Startup Welcome Email": {
"main": [
[
{
"node": "Mark Onboarded",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"id": "biotech-onboarding-v1"
}
Workflow 2: FDA / EU GMP / ICH / HIPAA / GDPR Compliance Deadline Tracker
Runs daily at 8 AM. Reads your compliance calendar from Google Sheets. Classifies each deadline as OVERDUE / CRITICAL / URGENT / WARNING / NOTICE. Alerts Slack #compliance and emails the deadline owner for anything URGENT or above.
12 Deadline Types Tracked:
| Type | Regulation | Window |
|---|---|---|
| FDA_21_CFR_PART11_VALIDATION_ANNUAL | §11.10(k) periodic review | Annual |
| FDA_IND_ANNUAL_REPORT | §312.33 progress report | 60d of IND anniversary |
| FDA_SUSAR_FATAL_7DAY | §312.32(c)(1)(i) | 7 calendar days ← FASTEST |
| FDA_SUSAR_SERIOUS_15DAY | §312.32(c)(1)(ii) | 15 calendar days |
| FDA_MDR_DEVICE_MALFUNCTION_30DAY | §803.50 | 30 calendar days |
| EU_GMP_ANNEX11_AUDIT_ANNUAL | Annex 11 §4.3 | Annual |
| ICH_E6_GCP_TMF_AUDIT | E6(R2) §8.1 | Ongoing |
| HIPAA_RISK_ANALYSIS_ANNUAL | §164.308(a)(1) | Annual |
| GDPR_ART9_DPIA_ANNUAL | Art.35 | Annual |
| FDA_820_QSR_DESIGN_REVIEW | §820.30(d) | Per design stage |
| SOC2_TYPE2_ANNUAL | SOC2 | Annual |
| EU_MDR_PMS_ANNUAL | MDR Art.83 | Annual |
{
"name": "FDA / EU GMP / ICH / HIPAA / GDPR Compliance Deadline Tracker",
"nodes": [
{
"id": "n1",
"name": "Daily 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * *"
}
]
}
}
},
{
"id": "n2",
"name": "Read Compliance Deadlines",
"type": "n8n-nodes-base.googleSheets",
"position": [
460,
300
],
"parameters": {
"operation": "readRows",
"sheetId": "YOUR_SHEET_ID",
"range": "compliance_deadlines!A:F"
}
},
{
"id": "n3",
"name": "Classify Urgency",
"type": "n8n-nodes-base.code",
"position": [
680,
300
],
"parameters": {
"jsCode": "\nconst deadlineTypes = {\n FDA_21_CFR_PART11_VALIDATION_ANNUAL: 'FDA 21 CFR \u00a711.10(k) periodic validation review \u2014 re-validate after any system change affecting electronic records',\n FDA_IND_ANNUAL_REPORT: 'FDA 21 CFR \u00a7312.33 \u2014 IND annual progress report due within 60 days of anniversary of IND effective date',\n FDA_SUSAR_FATAL_7DAY: 'FDA \u00a7312.32(c)(1)(i) \u2014 fatal/life-threatening SUSAR: 7 calendar days to FDA. FASTEST CLOCK.',\n FDA_SUSAR_SERIOUS_15DAY: 'FDA \u00a7312.32(c)(1)(ii) \u2014 serious unexpected SUSAR: 15 calendar days to FDA',\n FDA_MDR_MALFUNCTION_30DAY: 'FDA 21 CFR \u00a7803.50 \u2014 device malfunction reportable: 30 calendar days',\n EU_GMP_ANNEX11_AUDIT_ANNUAL: 'EU GMP Annex 11 \u00a74.3 \u2014 annual audit of computerized systems managing regulated data',\n ICH_E6_GCP_TMF_AUDIT: 'ICH E6(R2) \u00a78.1 \u2014 trial master file audit readiness; sponsor must maintain TMF throughout trial',\n HIPAA_RISK_ANALYSIS_ANNUAL: 'HIPAA \u00a7164.308(a)(1)(ii)(A) \u2014 annual risk analysis; required before and after any major system change',\n GDPR_ART9_DPIA_ANNUAL: 'GDPR Art.35 \u2014 DPIA for systematic processing of special category (health/genetic) data; annual review recommended',\n FDA_820_QSR_DESIGN_REVIEW: 'FDA \u00a7820.30(d) \u2014 design review at each design stage; automated QMS pipeline changes = design change requiring review',\n SOC2_TYPE2_ANNUAL: 'SOC2 Type II annual audit \u2014 required for enterprise BioTech/LifeSciences contracts',\n EU_MDR_PMS_ANNUAL: 'EU MDR 2017/745 Art.83 \u2014 post-market surveillance annual report for Class IIa/IIb/III devices'\n};\nconst today = new Date();\nreturn items.map(item => {\n const due = new Date(item.json.due_date);\n const days = Math.round((due - today) / 86400000);\n let urgency = 'NOTICE';\n if (days < 0) urgency = 'OVERDUE';\n else if (days <= 7) urgency = 'CRITICAL';\n else if (days <= 14) urgency = 'URGENT';\n else if (days <= 30) urgency = 'WARNING';\n return {json:{...item.json, days_until: days, urgency, description: deadlineTypes[item.json.deadline_type] || item.json.deadline_type}};\n});\n"
}
},
{
"id": "n4",
"name": "Filter Actionable",
"type": "n8n-nodes-base.filter",
"position": [
900,
300
],
"parameters": {
"conditions": {
"conditions": [
{
"leftValue": "={{$json.urgency}}",
"condition": "notEquals",
"rightValue": "NOTICE"
}
]
}
}
},
{
"id": "n5",
"name": "Slack #compliance",
"type": "n8n-nodes-base.slack",
"position": [
1120,
200
],
"parameters": {
"operation": "post",
"channel": "compliance",
"text": "={{$json.urgency}} \u2014 {{$json.deadline_type}} for {{$json.company_name}}: {{$json.days_until}} days. {{$json.description}}"
}
},
{
"id": "n6",
"name": "Gmail Compliance Owner",
"type": "n8n-nodes-base.gmail",
"position": [
1120,
400
],
"parameters": {
"operation": "send",
"to": "={{$json.owner_email}}",
"subject": "[{{$json.urgency}}] {{$json.deadline_type}} \u2014 {{$json.days_until}} days",
"message": "<p><strong>{{$json.description}}</strong></p><p>Due: {{$json.due_date}} ({{$json.days_until}} days)</p><p>Owner: {{$json.owner_name}}</p>"
}
}
],
"connections": {
"Daily 8AM": {
"main": [
[
{
"node": "Read Compliance Deadlines",
"type": "main",
"index": 0
}
]
]
},
"Read Compliance Deadlines": {
"main": [
[
{
"node": "Classify Urgency",
"type": "main",
"index": 0
}
]
]
},
"Classify Urgency": {
"main": [
[
{
"node": "Filter Actionable",
"type": "main",
"index": 0
}
]
]
},
"Filter Actionable": {
"main": [
[
{
"node": "Slack #compliance",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail Compliance Owner",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"id": "biotech-deadline-tracker-v1"
}
Workflow 3: Regulated System API Health Monitor (15-min GxP Watchdog)
Polls 5 regulated system endpoints every 15 minutes — tighter than the SUSAR 7-day FDA reporting clock, but designed to catch upstream failures before they cascade into reportable events.
| Endpoint | Regulation | Why It Matters |
|---|---|---|
| LIMS/ELN API | FDA 21 CFR Part 11 §11.10(e) | Audit trail continuity depends on system uptime |
| Clinical Trial DB API | ICH E6(R2) §8.3 | TMF integrity — downtime = undocumented data gap |
| FDA eSub Gateway | FDA §312.32 | Outage can delay SUSAR 7d/15d submission |
| PHI/Genomics API | HIPAA §164.312 + GDPR Art.9 | Health data access controls must be continuously validated |
| QMS/CAPA API | FDA §820.100 | Outage blocks CAPA closure — §820.100 requires timely corrective action |
{
"name": "Regulated System API Health Monitor (15-min GxP Watchdog)",
"nodes": [
{
"id": "n1",
"name": "Every 15 Minutes",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 15
}
]
}
}
},
{
"id": "n2",
"name": "Check LIMS/ELN API",
"type": "n8n-nodes-base.httpRequest",
"position": [
460,
160
],
"parameters": {
"url": "{{$env.LIMS_API_URL}}/health",
"method": "GET",
"timeout": 5000
}
},
{
"id": "n3",
"name": "Check Clinical Trial DB API",
"type": "n8n-nodes-base.httpRequest",
"position": [
460,
280
],
"parameters": {
"url": "{{$env.CLINICAL_TRIAL_DB_URL}}/health",
"method": "GET",
"timeout": 5000
}
},
{
"id": "n4",
"name": "Check FDA eSub Gateway",
"type": "n8n-nodes-base.httpRequest",
"position": [
460,
400
],
"parameters": {
"url": "{{$env.FDA_ESUB_GATEWAY_URL}}/status",
"method": "GET",
"timeout": 5000
}
},
{
"id": "n5",
"name": "Check PHI/Genomics API",
"type": "n8n-nodes-base.httpRequest",
"position": [
460,
520
],
"parameters": {
"url": "{{$env.PHI_GENOMICS_API_URL}}/health",
"method": "GET",
"timeout": 5000
}
},
{
"id": "n6",
"name": "Check QMS/CAPA API",
"type": "n8n-nodes-base.httpRequest",
"position": [
460,
640
],
"parameters": {
"url": "{{$env.QMS_CAPA_API_URL}}/health",
"method": "GET",
"timeout": 5000
}
},
{
"id": "n7",
"name": "Evaluate System Status",
"type": "n8n-nodes-base.code",
"position": [
700,
400
],
"parameters": {
"jsCode": "\nconst systemMap = {\n lims_eln: {name:'LIMS/ELN API', regulation:'FDA 21 CFR Part 11 \u00a711.10(e) audit trail continuity', priority:'CRITICAL'},\n clinical_trial_db: {name:'Clinical Trial DB API', regulation:'ICH E6(R2) \u00a78.3 trial master file integrity', priority:'CRITICAL'},\n fda_esub: {name:'FDA eSub Gateway', regulation:'FDA \u00a7312.32 IND safety reporting \u2014 outage may delay SUSAR 7/15d submission', priority:'HIGH'},\n phi_genomics: {name:'PHI/Genomics API', regulation:'HIPAA \u00a7164.312 + GDPR Art.9 health data access controls', priority:'HIGH'},\n qms_capa: {name:'QMS/CAPA API', regulation:'FDA \u00a7820.100 CAPA system \u2014 outage blocks deviation closure', priority:'MEDIUM'}\n};\nconst results = items.map((item, idx) => {\n const keys = Object.keys(systemMap);\n const sys = systemMap[keys[idx]];\n const status = item.json.status || (item.json.statusCode === 200 ? 'ok' : 'degraded');\n return {json:{system_key: keys[idx], system_name: sys.name, status, regulation: sys.regulation, priority: sys.priority, checked_at: new Date().toISOString()}};\n});\nreturn results.filter(r => r.json.status !== 'ok');\n"
}
},
{
"id": "n8",
"name": "Alert Slack #regulated-systems",
"type": "n8n-nodes-base.slack",
"position": [
920,
300
],
"parameters": {
"operation": "post",
"channel": "regulated-systems-ops",
"text": "={{$json.priority}} OUTAGE: {{$json.system_name}} \u2014 {{$json.regulation}}. Status: {{$json.status}}. Checked: {{$json.checked_at}}"
}
},
{
"id": "n9",
"name": "Log to SLA Sheet",
"type": "n8n-nodes-base.googleSheets",
"position": [
920,
500
],
"parameters": {
"operation": "appendRow",
"sheetId": "YOUR_SHEET_ID",
"range": "sla_log",
"data": {
"system": "={{$json.system_name}}",
"status": "={{$json.status}}",
"regulation": "={{$json.regulation}}",
"ts": "={{$json.checked_at}}"
}
}
}
],
"connections": {
"Every 15 Minutes": {
"main": [
[
{
"node": "Check LIMS/ELN API",
"type": "main",
"index": 0
},
{
"node": "Check Clinical Trial DB API",
"type": "main",
"index": 0
},
{
"node": "Check FDA eSub Gateway",
"type": "main",
"index": 0
},
{
"node": "Check PHI/Genomics API",
"type": "main",
"index": 0
},
{
"node": "Check QMS/CAPA API",
"type": "main",
"index": 0
}
]
]
},
"Check LIMS/ELN API": {
"main": [
[
{
"node": "Evaluate System Status",
"type": "main",
"index": 0
}
]
]
},
"Check Clinical Trial DB API": {
"main": [
[
{
"node": "Evaluate System Status",
"type": "main",
"index": 1
}
]
]
},
"Check FDA eSub Gateway": {
"main": [
[
{
"node": "Evaluate System Status",
"type": "main",
"index": 2
}
]
]
},
"Check PHI/Genomics API": {
"main": [
[
{
"node": "Evaluate System Status",
"type": "main",
"index": 3
}
]
]
},
"Check QMS/CAPA API": {
"main": [
[
{
"node": "Evaluate System Status",
"type": "main",
"index": 4
}
]
]
},
"Evaluate System Status": {
"main": [
[
{
"node": "Alert Slack #regulated-systems",
"type": "main",
"index": 0
},
{
"node": "Log to SLA Sheet",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"id": "biotech-api-monitor-v1"
}
Workflow 4: Incident & Deviation Pipeline
POST to /incident with incident_type. Returns 200 ACK immediately, then classifies and routes based on the regulatory clock.
Fastest clock: FDA_SUSAR_FATAL → 7 calendar days to FDA (§312.32)
EU fastest clock: GDPR_ART9_DATA_BREACH → 72 hours to supervisory authority (Art.33)
| Incident Type | Regulation | Deadline |
|---|---|---|
| FDA_SUSAR_FATAL | §312.32(c)(1)(i) | 7 calendar days |
| FDA_SUSAR_SERIOUS | §312.32(c)(1)(ii) | 15 calendar days |
| FDA_MDR_DEVICE_MALFUNCTION | §803.50 | 30 calendar days |
| ICH_E6_GCP_PROTOCOL_DEVIATION | E6(R2) §4.5.2 | IMMEDIATE sponsor notify |
| HIPAA_PHI_BREACH_DISCOVERED | §164.402 | IMMEDIATE risk assessment |
| GDPR_ART9_DATA_BREACH | Art.33 + Art.9 | 72 hours |
| FDA_21_CFR_PART11_AUDIT_TRAIL_GAP | §11.10(e) | IMMEDIATE — inspection readiness |
| EU_GMP_ANNEX11_SYSTEM_FAILURE | Annex 11 §16 | IMMEDIATE |
{
"name": "BioTech/LifeSciences Incident & Deviation Pipeline",
"nodes": [
{
"id": "n1",
"name": "Incident Webhook",
"type": "n8n-nodes-base.webhook",
"position": [
240,
300
],
"parameters": {
"path": "biotech-incident",
"method": "POST",
"responseMode": "responseNode"
}
},
{
"id": "n2",
"name": "Immediate 200 ACK",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
460,
200
],
"parameters": {
"respondWith": "json",
"responseBody": "{\"received\":true,\"ts\":\"={{new Date().toISOString()}}\"}"
}
},
{
"id": "n3",
"name": "Classify Incident",
"type": "n8n-nodes-base.code",
"position": [
460,
400
],
"parameters": {
"jsCode": "\nconst incidentMatrix = {\n FDA_SUSAR_FATAL: {deadline:'7 calendar days', regulation:'FDA 21 CFR \u00a7312.32(c)(1)(i)', severity:'CRITICAL', action:'Immediate Slack #safety + FDA eSub gateway notification + Gmail Safety Officer. 7-day clock starts at sponsor awareness.', fastest_clock: true},\n FDA_SUSAR_SERIOUS: {deadline:'15 calendar days', regulation:'FDA 21 CFR \u00a7312.32(c)(1)(ii)', severity:'CRITICAL', action:'IND Safety Report to FDA within 15 calendar days. Document in TMF.'},\n FDA_MDR_DEVICE_MALFUNCTION: {deadline:'30 calendar days', regulation:'FDA 21 CFR \u00a7803.50', severity:'HIGH', action:'Medical Device Report (MDR) to FDA MAUDE within 30 days. Preserve device and manufacturing records.'},\n ICH_E6_GCP_PROTOCOL_DEVIATION: {deadline:'IMMEDIATE sponsor notification', regulation:'ICH E6(R2) \u00a74.5.2', severity:'HIGH', action:'Sponsor notification required immediately. Document in TMF. Assess impact on trial data integrity.'},\n HIPAA_PHI_BREACH_DISCOVERED: {deadline:'IMMEDIATE risk assessment \u00a7164.402', regulation:'HIPAA 45 CFR \u00a7164.402', severity:'CRITICAL', action:'Perform risk assessment immediately. If breach confirmed: notify HHS OCR within 60d; media if 500+ affected; individuals within 60d.'},\n GDPR_ART9_DATA_BREACH: {deadline:'72 hours Art.33', regulation:'GDPR Art.33 + Art.9', severity:'CRITICAL', action:'72h supervisory authority notification. Special category health/genetic data = highest risk. Document containment within 72h.'},\n FDA_21_CFR_PART11_AUDIT_TRAIL_GAP: {deadline:'IMMEDIATE \u2014 inspection readiness', regulation:'FDA 21 CFR \u00a711.10(e)', severity:'HIGH', action:'Document gap immediately. FDA inspector may request audit trail logs on arrival. Unexplained gaps = Part 11 finding.'},\n EU_GMP_ANNEX11_SYSTEM_FAILURE: {deadline:'IMMEDIATE', regulation:'EU GMP Annex 11 \u00a716', severity:'HIGH', action:'Incident report required. Assess impact on data integrity. Restore validation status before resuming GxP operations.'}\n};\nconst type = item.json.incident_type || 'UNKNOWN';\nconst meta = incidentMatrix[type] || {deadline:'Review required', regulation:'Unknown', severity:'MEDIUM', action:'Escalate to QA/RA team immediately.'};\nreturn [{json:{...item.json, incident_meta: meta, classified_at: new Date().toISOString()}}];\n"
}
},
{
"id": "n4",
"name": "Switch on Severity",
"type": "n8n-nodes-base.switch",
"position": [
680,
400
],
"parameters": {
"dataType": "string",
"value": "={{$json.incident_meta.severity}}",
"rules": {
"rules": [
{
"value": "CRITICAL",
"output": 0
},
{
"value": "HIGH",
"output": 1
}
]
},
"fallbackOutput": 2
}
},
{
"id": "n5",
"name": "CRITICAL \u2014 Slack #safety-regulatory",
"type": "n8n-nodes-base.slack",
"position": [
900,
200
],
"parameters": {
"operation": "post",
"channel": "safety-regulatory",
"text": "CRITICAL INCIDENT: {{$json.incident_type}} \u2014 {{$json.incident_meta.regulation}}. Deadline: {{$json.incident_meta.deadline}}. Action: {{$json.incident_meta.action}}. Reported: {{$json.classified_at}}"
}
},
{
"id": "n6",
"name": "CRITICAL \u2014 Gmail Safety Officer",
"type": "n8n-nodes-base.gmail",
"position": [
900,
320
],
"parameters": {
"operation": "send",
"to": "={{$env.SAFETY_OFFICER_EMAIL}}",
"subject": "[CRITICAL] {{$json.incident_type}} \u2014 {{$json.incident_meta.deadline}} deadline",
"message": "<p><strong>Incident Type:</strong> {{$json.incident_type}}<br><strong>Regulation:</strong> {{$json.incident_meta.regulation}}<br><strong>Deadline:</strong> {{$json.incident_meta.deadline}}<br><strong>Required Action:</strong> {{$json.incident_meta.action}}</p>"
}
},
{
"id": "n7",
"name": "HIGH \u2014 Slack #qa-operations",
"type": "n8n-nodes-base.slack",
"position": [
900,
460
],
"parameters": {
"operation": "post",
"channel": "qa-operations",
"text": "HIGH PRIORITY: {{$json.incident_type}} \u2014 {{$json.incident_meta.regulation}}. Deadline: {{$json.incident_meta.deadline}}. Action required: {{$json.incident_meta.action}}"
}
},
{
"id": "n8",
"name": "Log All Incidents",
"type": "n8n-nodes-base.googleSheets",
"position": [
900,
600
],
"parameters": {
"operation": "appendRow",
"sheetId": "YOUR_SHEET_ID",
"range": "incident_log",
"data": {
"ts": "={{$json.classified_at}}",
"type": "={{$json.incident_type}}",
"severity": "={{$json.incident_meta.severity}}",
"regulation": "={{$json.incident_meta.regulation}}",
"deadline": "={{$json.incident_meta.deadline}}",
"reporter": "={{$json.reporter}}"
}
}
}
],
"connections": {
"Incident Webhook": {
"main": [
[
{
"node": "Immediate 200 ACK",
"type": "main",
"index": 0
},
{
"node": "Classify Incident",
"type": "main",
"index": 0
}
]
]
},
"Classify Incident": {
"main": [
[
{
"node": "Switch on Severity",
"type": "main",
"index": 0
}
]
]
},
"Switch on Severity": {
"main": [
[
{
"node": "CRITICAL \u2014 Slack #safety-regulatory",
"type": "main",
"index": 0
},
{
"node": "CRITICAL \u2014 Gmail Safety Officer",
"type": "main",
"index": 0
}
],
[
{
"node": "HIGH \u2014 Slack #qa-operations",
"type": "main",
"index": 0
}
],
[
{
"node": "Log All Incidents",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"id": "biotech-incident-pipeline-v1"
}
Workflow 5: Weekly QA & Regulatory KPI Dashboard
Every Monday at 8 AM: pulls regulated metrics from Postgres, computes WoW trends using $getWorkflowStaticData, sends HTML report to CEO + BCC CISO and QA Director.
{
"name": "Weekly BioTech/LifeSciences QA & Regulatory KPI Dashboard",
"nodes": [
{
"id": "n1",
"name": "Monday 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
}
},
{
"id": "n2",
"name": "Pull Regulatory Metrics",
"type": "n8n-nodes-base.postgres",
"position": [
460,
300
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT (SELECT COUNT(*) FROM customers WHERE status='active') as active_customers, (SELECT SUM(mrr_usd) FROM customers WHERE status='active') as mrr_usd, (SELECT COUNT(*) FROM incidents WHERE type='FDA_SUSAR_FATAL' AND created_at >= NOW() - INTERVAL '7 days') as susar_fatal_7d, (SELECT COUNT(*) FROM incidents WHERE type LIKE 'FDA%' AND status='open') as fda_open, (SELECT COUNT(*) FROM incidents WHERE type LIKE 'GDPR%' AND status='open') as gdpr_art9_open, (SELECT COUNT(*) FROM incidents WHERE type LIKE 'HIPAA%' AND status='open') as hipaa_open, (SELECT COUNT(*) FROM capa_items WHERE status='open') as capa_open, (SELECT COUNT(*) FROM clinical_trials WHERE status='active') as trials_active, (SELECT COUNT(*) FROM api_calls WHERE ts >= NOW() - INTERVAL '7 days') as api_calls_week"
}
},
{
"id": "n3",
"name": "Build KPI Report",
"type": "n8n-nodes-base.code",
"position": [
680,
300
],
"parameters": {
"jsCode": "\nconst d = item.json;\nconst prev = $getWorkflowStaticData('global');\nconst mrrWoW = prev.mrr ? ((d.mrr_usd - prev.mrr) / prev.mrr * 100).toFixed(1) : 'N/A';\nprev.mrr = d.mrr_usd;\nprev.customers = d.active_customers;\nconst html = `<h2>FlowKit BioTech/LifeSciences Weekly Report</h2>\n<table border='1' cellpadding='6'>\n<tr><th>Metric</th><th>Value</th><th>Note</th></tr>\n<tr><td>Active Customers</td><td>${d.active_customers}</td><td></td></tr>\n<tr><td>MRR</td><td>$${Number(d.mrr_usd).toLocaleString()}</td><td>WoW: ${mrrWoW}%</td></tr>\n<tr><td>SUSAR Fatal Reports (7d)</td><td>${d.susar_fatal_7d}</td><td>FDA \u00a7312.32 7-day clock</td></tr>\n<tr><td>Open FDA Incidents</td><td>${d.fda_open}</td><td></td></tr>\n<tr><td>Open GDPR Art.9 Incidents</td><td>${d.gdpr_art9_open}</td><td>72h clock</td></tr>\n<tr><td>Open HIPAA Incidents</td><td>${d.hipaa_open}</td><td></td></tr>\n<tr><td>Open CAPA Items</td><td>${d.capa_open}</td><td>\u00a7820.100</td></tr>\n<tr><td>Active Clinical Trials</td><td>${d.trials_active}</td><td>ICH E6(R2)</td></tr>\n<tr><td>API Calls (7d)</td><td>${Number(d.api_calls_week).toLocaleString()}</td><td></td></tr>\n</table>`;\nconst slack = `Weekly KPI: ${d.active_customers} customers | MRR $${Number(d.mrr_usd).toLocaleString()} (${mrrWoW}% WoW) | SUSAR 7d: ${d.susar_fatal_7d} | CAPA open: ${d.capa_open}`;\nreturn [{json:{html, slack, ...d}}];\n"
}
},
{
"id": "n4",
"name": "Email KPI Report",
"type": "n8n-nodes-base.gmail",
"position": [
900,
200
],
"parameters": {
"operation": "send",
"to": "={{$env.CEO_EMAIL}}",
"bcc": "={{$env.CISO_EMAIL}},={{$env.QA_DIRECTOR_EMAIL}}",
"subject": "Weekly BioTech/LifeSciences KPI \u2014 {{new Date().toLocaleDateString()}}",
"message": "={{$json.html}}"
}
},
{
"id": "n5",
"name": "Slack #go-to-market",
"type": "n8n-nodes-base.slack",
"position": [
900,
420
],
"parameters": {
"operation": "post",
"channel": "go-to-market",
"text": "={{$json.slack}}"
}
}
],
"connections": {
"Monday 8AM": {
"main": [
[
{
"node": "Pull Regulatory Metrics",
"type": "main",
"index": 0
}
]
]
},
"Pull Regulatory Metrics": {
"main": [
[
{
"node": "Build KPI Report",
"type": "main",
"index": 0
}
]
]
},
"Build KPI Report": {
"main": [
[
{
"node": "Email KPI Report",
"type": "main",
"index": 0
},
{
"node": "Slack #go-to-market",
"type": "main",
"index": 0
}
]
]
}
},
"active": false,
"settings": {},
"id": "biotech-kpi-dashboard-v1"
}
Why Self-Hosted n8n in GxP Environments
| Regulation | Cloud iPaaS Problem | Self-Hosted n8n Solution |
|---|---|---|
| FDA 21 CFR §11.10(e) | Vendor task logs = uncontrolled audit trail entries in your validated system boundary | Execution logs stay inside your GxP environment, inside your audit trail boundary |
| ICH E6(R2) §8.1 TMF | Automation vendor logs touching trial data = TMF gap — sponsor loses audit trail control | All workflow execution inside your TMF boundary; no vendor-controlled logs |
| GDPR Art.9 + Art.46 | Health/genetic data transfer to US cloud vendor without adequacy decision = Art.46 violation | n8n in AWS/Azure with EU region = data never leaves adequacy-covered zone |
| FDA §820.70(i) | Cloud automation in QMS pipeline = undocumented software in design control boundary | Documented, validated n8n instance within §820.30 design control scope |
| HIPAA §164.312(b) | Audit controls: vendor execution logs = external records outside your audit control | All PHI processing logs in your HIPAA-compliant infrastructure |
The 7 templates above are available individually or as a complete bundle at stripeai.gumroad.com.
The FlowKit BioTech/LifeSciences Template Bundle
Each template includes:
- Full import-ready workflow JSON
- Credentials configuration guide
- Regulatory reference sheet (specific CFR/ICH/GDPR citations per node)
- Tier-specific customization notes
Self-hosted n8n keeps your audit trail inside your validated system boundary. Templates at stripeai.gumroad.com.
Top comments (0)