If your SaaS platform processes adverse event data, clinical trial records, or pharmacovigilance case reports for an IND holder, you are operating inside some of the most unforgiving regulatory clocks in the world.
The FDA 21 CFR §312.32 7-day expedited IND safety report clock starts from initial receipt of information by the sponsor. Not when your batch job runs. Not when your compliance team reviews the case. The moment the data enters your system.
Cloud automation platforms that process safety data create a structural problem: batch polling cycles (15 minutes, 30 minutes, sometimes hours) introduce a detection lag. If your cloud iPaaS platform polls for adverse events once an hour and a fatal unexpected ADR comes in at 11:59 PM, the sponsor doesn't see it until 12:59 AM — and the 7-day clock has been running since 11:59 PM.
This article covers 5 n8n workflows (with full JSON) for the 7 core customer tiers in BioTech/PharmaTech SaaS, focusing on the regulatory clocks that bite hardest: FDA 21 CFR §312.32, EU EMA CTR Art.42, FDA 21 CFR Part 11, DEA 21 CFR Part 1304, and FDA REMS.
The 7 BioTech/PharmaTech SaaS Customer Tiers
| Tier | Primary Regulatory Exposure | Fastest Clock |
|---|---|---|
| CLINICAL_TRIAL_SAAS | FDA §312.32 IND safety reporting + ICH E6 R2 GCP audit trail | 7 calendar days (fatal/unexpected ADR) |
| PHARMACOVIGILANCE_SAAS | FDA §312.32 + EU EMA CTR Art.42 SUSAR + FDA Part 11 | 7 calendar days (IND) / IMMEDIATE (Part 11) |
| LABORATORY_SAAS | ICH E6 R2 GCP + DEA 21 CFR Part 1304 + FDA Part 58 GLP | DEA: 2-year retention from transaction date |
| REGULATORY_SUBMISSION_SAAS | FDA §314.81 NDA annual report 60-day + eCTD Technical Conformance | 60 days from NDA anniversary |
| CONTRACT_RESEARCH_ORG_SAAS | GCP §4.9 audit trail + FDA §312.32 sponsor obligations + SUSAR | 7 calendar days (inherited sponsor obligation) |
| BIOTECH_STARTUP_SAAS | FDA IND/Pre-IND + EMA Scientific Advice + DEA registration | Variable by IND stage |
| MEDTECH_COMBO_PRODUCT_SAAS | FDA 21 CFR Part 820 QSR + IEC 62304 + §312.32 combination products | IMMEDIATE (MDR) + 7/15 days (ADE) |
The 3 Regulatory Clocks That Most Cloud Platforms Get Wrong
1. FDA 21 CFR §312.32 — The Receipt Date Trap
FDA 21 CFR §312.32(c)(1) requires sponsors to submit an expedited IND safety report within 7 calendar days for fatal or life-threatening unexpected adverse drug reactions (ADRs).
The clock starts from "initial receipt" — not from the sponsor's review, not from the PV team's assessment, not from your cloud platform's processing cycle.
The cloud automation problem: if your PV SaaS platform batch-processes incoming case reports on a 4-hour cycle, a fatal ADR received at 11 PM starts the 7-day clock at 11 PM. Your platform doesn't flag it until 3 AM. The sponsor's regulatory team doesn't see it until 8 AM. You've burned 9 hours of a 7-day (168-hour) window before the case is reviewed.
FDA has issued Warning Letters for 7-day IND safety report delays. Self-hosted n8n processes webhook-delivered adverse event data in real-time — no polling delay.
2. EU EMA CTR Art.42 — SUSAR 15-Day Clock
EU EMA Clinical Trial Regulation Art.42 requires sponsors to submit Suspected Unexpected Serious Adverse Reactions (SUSARs) to EudraVigilance within 15 calendar days of sponsor awareness.
"Sponsor awareness" is defined as the date the sponsor (or any party acting on behalf of the sponsor) first receives information about the SUSAR. If your CRO SaaS platform receives the case on Day 0 and your batch processing cycle runs every 24 hours, the sponsor isn't "aware" through your platform until Day 1. The 15-day clock has been running for 24 hours.
3. FDA 21 CFR Part 11 — The Cloud Audit Trail Problem
FDA 21 CFR Part 11 governs electronic records used to support IND/NDA submissions. It requires audit trails that capture who accessed, created, modified, or deleted records — with timestamps.
If your SaaS platform processes IND safety data, clinical trial records, or NDA submission data, your platform's audit trail is FDA Part 11 subject matter. FDA inspections of sponsors include review of third-party system audit logs. Cloud SaaS vendors' own logs — including support access, infrastructure access, and debugging sessions — are potentially discoverable under a Form 483.
Self-hosted n8n keeps all audit trail data within your infrastructure, with no cloud vendor access to inspect or subpoena.
Workflow 1: Tier-Segmented Customer Onboarding Drip
Sends compliance-specific onboarding emails based on the customer's tier. Clinical trial SaaS customers get the IND 7-day receipt date trap explanation. PV SaaS customers get the Part 11 cloud audit trail problem. Laboratory customers get GCP + DEA retention requirements.
{
"name": "BioTech/PharmaTech Onboarding Drip (Tier-Segmented)",
"nodes": [
{
"id": "1",
"name": "Webhook New Customer",
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "biotech-pharmatech-onboard",
"responseMode": "responseNode"
},
"position": [
250,
300
]
},
{
"id": "2",
"name": "Switch Route by Tier",
"type": "n8n-nodes-base.switch",
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"conditions": {
"string": [
{
"value1": "={{ $json.tier }}",
"operation": "equals",
"value2": "CLINICAL_TRIAL_SAAS"
}
]
}
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.tier }}",
"operation": "equals",
"value2": "PHARMACOVIGILANCE_SAAS"
}
]
}
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.tier }}",
"operation": "equals",
"value2": "LABORATORY_SAAS"
}
]
}
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.tier }}",
"operation": "equals",
"value2": "REGULATORY_SUBMISSION_SAAS"
}
]
}
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.tier }}",
"operation": "equals",
"value2": "CONTRACT_RESEARCH_ORG_SAAS"
}
]
}
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.tier }}",
"operation": "equals",
"value2": "BIOTECH_STARTUP_SAAS"
}
]
}
}
]
}
},
"position": [
500,
300
]
},
{
"id": "3",
"name": "Gmail Clinical Trial Welcome IND Safety",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "={{ $('Webhook New Customer').item.json.email }}",
"subject": "FDA 21 CFR \u00a7312.32 7-Day IND Safety Clock + EU EMA CTR SUSAR \u2014 Your Clinical Trial SaaS Onboarding Checklist",
"message": "Welcome to FlowKit. As a clinical trial SaaS vendor: (1) FDA 21 CFR \u00a7312.32(c)(1): if your platform processes adverse event data for an IND holder, the 7-calendar-day expedited IND safety report clock for fatal/life-threatening unexpected ADRs starts from initial receipt \u2014 not when your batch job runs. A 24-hour polling cycle burns one day before the sponsor sees the event. (2) EU EMA CTR Art.42: 15-day SUSAR submission clock starts from sponsor awareness \u2014 cloud latency = clock already ticking. (3) ICH E6 R2 GCP: outsourcing clinical data management to a SaaS platform does not transfer GCP sponsor responsibilities. Your audit trail is an FDA inspection artifact."
},
"position": [
800,
50
]
},
{
"id": "4",
"name": "Gmail PV Welcome FDA Part 11 SUSAR",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "={{ $('Webhook New Customer').item.json.email }}",
"subject": "FDA 21 CFR Part 11 Electronic Records + FinCEN SAR Confidentiality \u2014 Your Pharmacovigilance SaaS Onboarding Checklist",
"message": "As a pharmacovigilance SaaS vendor: (1) FDA 21 CFR Part 11: your platform's electronic records and audit trails are FDA-inspectable. If your cloud vendor processes IND/NDA safety data, their system audit trail (who accessed, modified, or deleted records) is Part 11 subject. SaaS vendor audit logs become sponsor's Part 11 compliance obligation. (2) FDA 21 CFR \u00a7312.32(c)(2): 15-calendar-day IND safety report for serious unexpected ADRs \u2014 cloud batch aggregation of case reports extends the detection window. (3) FDA ICH E2B(R3) MedDRA coding: if your PV SaaS generates E2B XML submissions to FDA Adverse Reporting System (FAERS), incorrect MedDRA codes can trigger a Complete Response Letter."
},
"position": [
800,
200
]
},
{
"id": "5",
"name": "Gmail Lab Welcome GCP DEA Records",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "={{ $('Webhook New Customer').item.json.email }}",
"subject": "ICH E6 R2 GCP Audit Trail + DEA 21 CFR Part 1304 Schedule II Records \u2014 Your Laboratory SaaS Onboarding Checklist",
"message": "As a laboratory (LIMS/ELN) SaaS vendor: (1) ICH E6 R2 GCP \u00a74.9: all laboratory data supporting IND/NDA filings must have audit trail showing original values, changes, and who changed them. SaaS-based LIMS with soft-deletes or overwrites is a GCP audit finding. (2) DEA 21 CFR Part 1304: Schedule II-V controlled substance records must be maintained 2 full years from date of transaction. If your LIMS processes dispensing records for clinical trial sites with DEA Schedule II materials (morphine, oxycodone, methylphenidate in trials), your retention policy is a DEA registration obligation. (3) FDA 21 CFR Part 58 GLP: if your LIMS stores non-clinical safety study data, Good Laboratory Practice requires traceable audit records for FDA preclinical submissions."
},
"position": [
800,
350
]
},
{
"id": "6",
"name": "Gmail RegSub Welcome eCTD NDA Annual",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "={{ $('Webhook New Customer').item.json.email }}",
"subject": "FDA NDA Annual Report 60-Day Window + eCTD Submission Sequence \u2014 Your Regulatory Submission SaaS Onboarding Checklist",
"message": "As a regulatory submission SaaS vendor: (1) FDA 21 CFR \u00a7314.81: NDA annual report must be submitted within 60 days of the NDA anniversary date. If your platform manages NDA annual report assembly, the 60-day clock starts on the anniversary \u2014 missing it is a reportable failure. (2) FDA eCTD Technical Conformance Guide: eCTD submissions require valid XML backbone, correct regional module structure, and no broken hyperlinks. Your validation logic must match the FDA Electronic Submissions Gateway requirements for each submission type (IND, NDA, BLA, ANDA, DMF). (3) EU CTD/eCTD: EMA requires submissions through CESP (Common European Submission Portal) using the EU regional module. Both FDA and EMA simultaneous submissions have different technical requirements \u2014 your platform must handle both."
},
"position": [
800,
500
]
},
{
"id": "7",
"name": "Wait 3 Days",
"type": "n8n-nodes-base.wait",
"parameters": {
"resume": "timeInterval",
"unit": "days",
"value": 3
},
"position": [
1050,
300
]
},
{
"id": "8",
"name": "Gmail Day 4 Compliance Checkpoint",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "={{ $('Webhook New Customer').item.json.email }}",
"subject": "Day 4: Your FDA/EMA Compliance Deadline Calendar",
"message": "Your 4-day check-in. The n8n compliance workflow tracks: FDA IND 7-day expedited (fatal/unexpected), FDA IND 15-day (serious unexpected), EU EMA CTR SUSAR 15-day, NDA annual report 60-day, DEA Schedule II-V 2-year retention, FDA REMS assessment annual, ICH E6 R2 GCP audit trail windows."
},
"position": [
1300,
300
]
},
{
"id": "9",
"name": "Wait 4 More Days",
"type": "n8n-nodes-base.wait",
"parameters": {
"resume": "timeInterval",
"unit": "days",
"value": 4
},
"position": [
1550,
300
]
},
{
"id": "10",
"name": "Gmail Day 8 Advanced CTA",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "={{ $('Webhook New Customer').item.json.email }}",
"subject": "Day 8: Advanced BioTech/PharmaTech Compliance Workflows Available",
"message": "Next: the FDA IND Safety Report / EU EMA SUSAR incident pipeline (8 event types) and the FDA Part 11 electronic records monitor. Available in the FlowKit bundle: https://stripeai.gumroad.com"
},
"position": [
1800,
300
]
}
],
"connections": {
"Webhook New Customer": {
"main": [
[
{
"node": "Switch Route by Tier",
"type": "main",
"index": 0
}
]
]
},
"Switch Route by Tier": {
"main": [
[
{
"node": "Gmail Clinical Trial Welcome IND Safety",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail PV Welcome FDA Part 11 SUSAR",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail Lab Welcome GCP DEA Records",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail RegSub Welcome eCTD NDA Annual",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail Clinical Trial Welcome IND Safety",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail PV Welcome FDA Part 11 SUSAR",
"type": "main",
"index": 0
}
]
]
},
"Gmail Clinical Trial Welcome IND Safety": {
"main": [
[
{
"node": "Wait 3 Days",
"type": "main",
"index": 0
}
]
]
},
"Gmail PV Welcome FDA Part 11 SUSAR": {
"main": [
[
{
"node": "Wait 3 Days",
"type": "main",
"index": 0
}
]
]
},
"Gmail Lab Welcome GCP DEA Records": {
"main": [
[
{
"node": "Wait 3 Days",
"type": "main",
"index": 0
}
]
]
},
"Gmail RegSub Welcome eCTD NDA Annual": {
"main": [
[
{
"node": "Wait 3 Days",
"type": "main",
"index": 0
}
]
]
},
"Wait 3 Days": {
"main": [
[
{
"node": "Gmail Day 4 Compliance Checkpoint",
"type": "main",
"index": 0
}
]
]
},
"Gmail Day 4 Compliance Checkpoint": {
"main": [
[
{
"node": "Wait 4 More Days",
"type": "main",
"index": 0
}
]
]
},
"Wait 4 More Days": {
"main": [
[
{
"node": "Gmail Day 8 Advanced CTA",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 2: FDA IND/NDA/EMA Compliance Deadline Tracker
Daily schedule (6 AM) reads a Google Sheet of compliance deadlines. Calculates days remaining for each clock type: FDA IND 7-day expedited, FDA IND 15-day serious, EU EMA CTR SUSAR 15-day, NDA annual report 60-day, DEA Schedule II 2-year retention, FDA REMS annual assessment, ICH GCP audit trail windows. Routes to #regulatory-critical Slack channel with escalating severity.
{
"name": "FDA IND/NDA/EMA Compliance Deadline Tracker",
"nodes": [
{
"id": "1",
"name": "Schedule Daily 6AM",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"triggerAtHour": 6
}
]
}
},
"position": [
250,
300
]
},
{
"id": "2",
"name": "Google Sheets Read Compliance Deadlines",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "getAll",
"sheetId": "YOUR_SHEET_ID",
"range": "Deadlines!A2:L1000"
},
"position": [
500,
300
]
},
{
"id": "3",
"name": "Code Calculate Regulatory Clocks",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "const now = new Date(); const results = []; for (const item of $input.all()) { const d = item.json; const deadline = new Date(d.deadline_date); const daysRemaining = Math.ceil((deadline - now) / (1000 * 60 * 60 * 24)); let severity; if (d.clock_type === 'FDA_IND_7DAY_EXPEDITED' && daysRemaining <= 0) { severity = 'FDA_BREACH_REPORTABLE'; } else if (d.clock_type === 'FDA_IND_7DAY_EXPEDITED' && daysRemaining <= 1) { severity = 'CRITICAL'; } else if (d.clock_type === 'EU_EMA_CTR_SUSAR_15DAY' && daysRemaining <= 2) { severity = 'CRITICAL'; } else if (d.clock_type === 'FDA_IND_15DAY_SERIOUS' && daysRemaining <= 3) { severity = 'CRITICAL'; } else if (d.clock_type === 'NDA_ANNUAL_REPORT_60DAY' && daysRemaining <= 7) { severity = 'HIGH'; } else if (d.clock_type === 'FDA_REMS_ANNUAL_ASSESSMENT' && daysRemaining <= 30) { severity = 'HIGH'; } else if (d.clock_type === 'DEA_SCHEDULE_II_RETENTION' && daysRemaining <= 30) { severity = 'MEDIUM'; } else if (d.clock_type === 'ICH_GCP_AUDIT_TRAIL' && daysRemaining <= 7) { severity = 'HIGH'; } else if (daysRemaining <= 2) { severity = 'CRITICAL'; } else if (daysRemaining <= 7) { severity = 'HIGH'; } else if (daysRemaining <= 30) { severity = 'MEDIUM'; } else { severity = 'OK'; } if (severity !== 'OK') { results.push({ json: { ...d, daysRemaining, severity, calculatedAt: now.toISOString() } }); } } return results;"
},
"position": [
750,
300
]
},
{
"id": "4",
"name": "Switch Route by Severity",
"type": "n8n-nodes-base.switch",
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"conditions": {
"string": [
{
"value1": "={{ $json.severity }}",
"operation": "equals",
"value2": "FDA_BREACH_REPORTABLE"
}
]
}
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.severity }}",
"operation": "equals",
"value2": "CRITICAL"
}
]
}
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.severity }}",
"operation": "equals",
"value2": "HIGH"
}
]
}
}
]
}
},
"position": [
1000,
300
]
},
{
"id": "5",
"name": "Slack FDA BREACH Alert",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#regulatory-critical",
"text": "FDA IND BREACH: {{ $json.customer_name }} \u2014 FDA 21 CFR \u00a7312.32 7-day expedited IND safety report OVERDUE. Event: {{ $json.event_description }} | IND Number: {{ $json.ind_number }} | Receipt Date: {{ $json.event_receipt_date }}. Sponsor must submit expedited IND safety report IMMEDIATELY. Contact: {{ $json.sponsor_contact }}."
},
"position": [
1250,
50
]
},
{
"id": "6",
"name": "Slack Critical Regulatory Alert",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#regulatory-alerts",
"text": "CRITICAL [{{ $json.clock_type }}] Customer: {{ $json.customer_name }} | IND/NDA: {{ $json.ind_nda_number }} | Deadline: {{ $json.deadline_date }} | {{ $json.daysRemaining }} days remaining | Regulation: {{ $json.regulation_cite }}"
},
"position": [
1250,
250
]
},
{
"id": "7",
"name": "Slack High Priority Alert",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#regulatory-alerts",
"text": "HIGH [{{ $json.clock_type }}] Customer: {{ $json.customer_name }} | {{ $json.daysRemaining }} days to regulatory deadline {{ $json.deadline_date }}."
},
"position": [
1250,
450
]
},
{
"id": "8",
"name": "Gmail Daily Regulatory Summary",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "cmo@yourcompany.com",
"subject": "BioTech/Pharma Compliance Deadline Summary {{ $now.format('YYYY-MM-DD') }}",
"message": "Daily regulatory scan complete. Review Slack #regulatory-critical for FDA IND 7-day, SUSAR 15-day, and NDA annual report items."
},
"position": [
1250,
650
]
}
],
"connections": {
"Schedule Daily 6AM": {
"main": [
[
{
"node": "Google Sheets Read Compliance Deadlines",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets Read Compliance Deadlines": {
"main": [
[
{
"node": "Code Calculate Regulatory Clocks",
"type": "main",
"index": 0
}
]
]
},
"Code Calculate Regulatory Clocks": {
"main": [
[
{
"node": "Switch Route by Severity",
"type": "main",
"index": 0
}
]
]
},
"Switch Route by Severity": {
"main": [
[
{
"node": "Slack FDA BREACH Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack Critical Regulatory Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack High Priority Alert",
"type": "main",
"index": 0
}
]
]
},
"Slack FDA BREACH Alert": {
"main": [
[
{
"node": "Gmail Daily Regulatory Summary",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 3: FDA Part 11 Electronic Records API Health Monitor
Runs every 5 minutes. Checks your clinical trial database, pharmacovigilance API, eCTD submission portal, and DEA records API. Each API downtime has a specific FDA/DEA regulatory exposure documented in the alert — Part 11 audit trail gap, IND 7-day clock delay, eCTD submission queue blockage, DEA 2-year retention records inaccessibility.
{
"name": "FDA Part 11 Electronic Records API Health Monitor (5-Minute)",
"nodes": [
{
"id": "1",
"name": "Schedule Every 5 Min",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"value": 5
}
]
}
},
"position": [
250,
300
]
},
{
"id": "2",
"name": "HTTP Check Clinical Trial DB API",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.your-ctms.com/v1/health",
"method": "GET",
"continueOnFail": true
},
"position": [
500,
100
]
},
{
"id": "3",
"name": "HTTP Check Pharmacovigilance API",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.your-pv-system.com/health",
"method": "GET",
"continueOnFail": true
},
"position": [
500,
250
]
},
{
"id": "4",
"name": "HTTP Check eCTD Submission Portal",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.your-ectd.com/v1/status",
"method": "GET",
"continueOnFail": true
},
"position": [
500,
400
]
},
{
"id": "5",
"name": "HTTP Check DEA ARCOS API",
"type": "n8n-nodes-base.httpRequest",
"parameters": {
"url": "https://api.your-dea-records.com/health",
"method": "GET",
"continueOnFail": true
},
"position": [
500,
550
]
},
{
"id": "6",
"name": "Code Evaluate API Health",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "const checks = [\n { name: 'Clinical Trial DB (FDA Part 11 audit trail)', node: 'HTTP Check Clinical Trial DB API', regulation: 'FDA 21 CFR Part 11 \u2014 audit trail gap if down during active trial data entry' },\n { name: 'Pharmacovigilance API (IND Safety 7-day clock)', node: 'HTTP Check Pharmacovigilance API', regulation: 'FDA \u00a7312.32 \u2014 PV downtime during active AE = 7-day clock continues, detection delayed' },\n { name: 'eCTD Submission Portal (NDA filing pipeline)', node: 'HTTP Check eCTD Submission Portal', regulation: 'FDA eCTD Technical Conformance \u2014 submission queue blocked if portal down near deadline' },\n { name: 'DEA ARCOS API (Schedule II retention records)', node: 'HTTP Check DEA ARCOS API', regulation: 'DEA 21 CFR Part 1304 \u2014 2-year retention; records inaccessible during outage = DEA audit risk' }\n];\nconst results = [];\nfor (const check of checks) {\n const resp = $node[check.node].json;\n const isDown = resp.error || resp.statusCode >= 500 || !resp.statusCode;\n if (isDown) {\n results.push({ json: { api: check.name, regulation: check.regulation, status: 'DOWN', timestamp: new Date().toISOString() } });\n }\n}\nreturn results.length > 0 ? results : [{ json: { status: 'ALL_OK', timestamp: new Date().toISOString() } }];"
},
"position": [
800,
300
]
},
{
"id": "7",
"name": "IF Any APIs Down",
"type": "n8n-nodes-base.if",
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.status }}",
"operation": "notEquals",
"value2": "ALL_OK"
}
]
}
},
"position": [
1050,
300
]
},
{
"id": "8",
"name": "Slack FDA API Down Alert",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#regulatory-critical",
"text": "FDA COMPLIANCE API DOWN: {{ $json.api }}\nRegulation exposure: {{ $json.regulation }}\nTimestamp: {{ $json.timestamp }}\nAction: Notify Regulatory Affairs immediately. Document outage start time for FDA Part 11 audit trail records."
},
"position": [
1300,
200
]
}
],
"connections": {
"Schedule Every 5 Min": {
"main": [
[
{
"node": "HTTP Check Clinical Trial DB API",
"type": "main",
"index": 0
},
{
"node": "HTTP Check Pharmacovigilance API",
"type": "main",
"index": 0
},
{
"node": "HTTP Check eCTD Submission Portal",
"type": "main",
"index": 0
},
{
"node": "HTTP Check DEA ARCOS API",
"type": "main",
"index": 0
}
]
]
},
"HTTP Check Clinical Trial DB API": {
"main": [
[
{
"node": "Code Evaluate API Health",
"type": "main",
"index": 0
}
]
]
},
"HTTP Check Pharmacovigilance API": {
"main": [
[
{
"node": "Code Evaluate API Health",
"type": "main",
"index": 0
}
]
]
},
"HTTP Check eCTD Submission Portal": {
"main": [
[
{
"node": "Code Evaluate API Health",
"type": "main",
"index": 0
}
]
]
},
"HTTP Check DEA ARCOS API": {
"main": [
[
{
"node": "Code Evaluate API Health",
"type": "main",
"index": 0
}
]
]
},
"Code Evaluate API Health": {
"main": [
[
{
"node": "IF Any APIs Down",
"type": "main",
"index": 0
}
]
]
},
"IF Any APIs Down": {
"main": [
[
{
"node": "Slack FDA API Down Alert",
"type": "main",
"index": 0
}
],
[]
]
}
}
}
Workflow 4: FDA IND Safety Report / EU EMA SUSAR Incident Pipeline
Webhook receives adverse event data. Classifies the regulatory clock based on event type: FATAL/LIFE-THREATENING (7-day IND), SERIOUS_UNEXPECTED (15-day IND), EU_SUSAR (15-day EMA CTR Art.42), FDA_PART11_BREACH (IMMEDIATE). Routes to Slack with regulation cite and receipt date. Logs to Google Sheets with audit trail. Responds to webhook with clock type, deadline, and regulation cite.
{
"name": "FDA IND Safety Report / EU EMA SUSAR Incident Pipeline",
"nodes": [
{
"id": "1",
"name": "Webhook Adverse Event Received",
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "pharma-adverse-event",
"responseMode": "responseNode"
},
"position": [
250,
300
]
},
{
"id": "2",
"name": "Code Classify Regulatory Clock",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "const event = $input.first().json;\nconst now = new Date();\nconst receiptDate = new Date(event.receipt_date || now);\nlet clockType, deadlineDays, regulationCite, alertChannel, severity;\n\nif (event.event_type === 'FATAL_UNEXPECTED_ADR' || event.event_type === 'LIFE_THREATENING_UNEXPECTED_ADR') {\n clockType = 'FDA_IND_7DAY_EXPEDITED';\n deadlineDays = 7;\n regulationCite = 'FDA 21 CFR \u00a7312.32(c)(1) \u2014 7 calendar days from initial receipt';\n alertChannel = '#regulatory-critical';\n severity = 'CRITICAL';\n} else if (event.event_type === 'SERIOUS_UNEXPECTED_ADR') {\n clockType = 'FDA_IND_15DAY_SERIOUS';\n deadlineDays = 15;\n regulationCite = 'FDA 21 CFR \u00a7312.32(c)(2) \u2014 15 calendar days from initial receipt';\n alertChannel = '#regulatory-critical';\n severity = 'HIGH';\n} else if (event.event_type === 'EU_SUSAR') {\n clockType = 'EU_EMA_CTR_SUSAR_15DAY';\n deadlineDays = 15;\n regulationCite = 'EU EMA CTR Art.42 \u2014 15 calendar days from sponsor awareness';\n alertChannel = '#regulatory-eu';\n severity = 'HIGH';\n} else if (event.event_type === 'FDA_PART11_AUDIT_BREACH') {\n clockType = 'FDA_PART11_IMMEDIATE';\n deadlineDays = 0;\n regulationCite = 'FDA 21 CFR Part 11 \u2014 IMMEDIATE audit trail preservation required';\n alertChannel = '#regulatory-critical';\n severity = 'CRITICAL';\n} else if (event.event_type === 'REMS_SERIOUS_OUTCOME') {\n clockType = 'FDA_REMS_REPORT';\n deadlineDays = 15;\n regulationCite = 'FDA REMS program requirements \u2014 15-day expedited safety reporting';\n alertChannel = '#regulatory-alerts';\n severity = 'HIGH';\n} else {\n clockType = 'FDA_IND_15DAY_SERIOUS';\n deadlineDays = 15;\n regulationCite = 'FDA 21 CFR \u00a7312.32(c)(2) \u2014 default 15-day serious AE clock';\n alertChannel = '#regulatory-alerts';\n severity = 'MEDIUM';\n}\n\nconst deadlineDate = new Date(receiptDate);\ndeadlineDate.setDate(deadlineDate.getDate() + deadlineDays);\n\nreturn [{ json: { ...event, clockType, deadlineDays, deadlineDate: deadlineDate.toISOString(), regulationCite, alertChannel, severity, receiptDate: receiptDate.toISOString(), classifiedAt: now.toISOString() } }];"
},
"position": [
500,
300
]
},
{
"id": "3",
"name": "Switch Route by Clock Type",
"type": "n8n-nodes-base.switch",
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"conditions": {
"string": [
{
"value1": "={{ $json.severity }}",
"operation": "equals",
"value2": "CRITICAL"
}
]
}
},
{
"conditions": {
"string": [
{
"value1": "={{ $json.severity }}",
"operation": "equals",
"value2": "HIGH"
}
]
}
}
]
}
},
"position": [
750,
300
]
},
{
"id": "4",
"name": "Slack CRITICAL Safety Event",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "={{ $json.alertChannel }}",
"text": "CRITICAL SAFETY EVENT\nType: {{ $json.clockType }}\nRegulation: {{ $json.regulationCite }}\nDeadline: {{ $json.deadlineDate }} ({{ $json.deadlineDays }} calendar days from receipt)\nCustomer: {{ $json.customer_name }} | IND: {{ $json.ind_number }}\nEvent: {{ $json.event_description }}\nIMPORTIAT: Clock started {{ $json.receiptDate }} \u2014 self-hosted n8n audit trail preserved."
},
"position": [
1000,
100
]
},
{
"id": "5",
"name": "Gmail Regulatory Affairs Alert",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "regulatory@yourcompany.com",
"subject": "URGENT: {{ $json.clockType }} \u2014 {{ $json.deadlineDays }}-Day Clock Started {{ $json.receiptDate }}",
"message": "Regulatory action required.\n\nClock type: {{ $json.clockType }}\nRegulation: {{ $json.regulationCite }}\nReceipt date: {{ $json.receiptDate }}\nDeadline: {{ $json.deadlineDate }}\nCustomer: {{ $json.customer_name }}\nIND/NDA: {{ $json.ind_number }}\nEvent: {{ $json.event_description }}\n\nThis record has been logged in the audit trail per FDA 21 CFR Part 11 requirements. Self-hosted n8n instance ensures no third-party vendor has access to this safety data."
},
"position": [
1000,
300
]
},
{
"id": "6",
"name": "Google Sheets Log Safety Event",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "append",
"sheetId": "YOUR_SHEET_ID",
"range": "SafetyEvents!A:M",
"data": {
"values": [
[
"={{ $json.customer_name }}",
"={{ $json.ind_number }}",
"={{ $json.event_type }}",
"={{ $json.clockType }}",
"={{ $json.receiptDate }}",
"={{ $json.deadlineDate }}",
"={{ $json.regulationCite }}",
"={{ $json.severity }}",
"OPEN",
"={{ $json.classifiedAt }}",
"",
"",
""
]
]
}
},
"position": [
1000,
500
]
},
{
"id": "7",
"name": "Respond to Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"parameters": {
"responseCode": 200,
"responseData": "{\"status\":\"logged\",\"clockType\":\"{{ $json.clockType }}\",\"deadline\":\"{{ $json.deadlineDate }}\",\"regulationCite\":\"{{ $json.regulationCite }}\",\"auditTrail\":\"preserved\"}"
},
"position": [
1000,
700
]
}
],
"connections": {
"Webhook Adverse Event Received": {
"main": [
[
{
"node": "Code Classify Regulatory Clock",
"type": "main",
"index": 0
}
]
]
},
"Code Classify Regulatory Clock": {
"main": [
[
{
"node": "Switch Route by Clock Type",
"type": "main",
"index": 0
}
]
]
},
"Switch Route by Clock Type": {
"main": [
[
{
"node": "Slack CRITICAL Safety Event",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail Regulatory Affairs Alert",
"type": "main",
"index": 0
}
]
]
},
"Slack CRITICAL Safety Event": {
"main": [
[
{
"node": "Google Sheets Log Safety Event",
"type": "main",
"index": 0
}
]
]
},
"Gmail Regulatory Affairs Alert": {
"main": [
[
{
"node": "Google Sheets Log Safety Event",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets Log Safety Event": {
"main": [
[
{
"node": "Respond to Webhook",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 5: Weekly BioTech Regulatory KPI Dashboard
Runs Monday 8 AM. Pulls all open safety events and compliance deadlines from Google Sheets. Generates a color-coded HTML table with 7 KPIs: IND 7-day expedited reports open, IND 15-day serious reports open, EU SUSAR submissions open, NDA annual reports due ≤30 days, DEA Schedule II records at risk, REMS annual assessments due, GCP audit trail gaps. Emails to CMO + CEO BCC with CRO.
{
"name": "Weekly BioTech Regulatory KPI Dashboard",
"nodes": [
{
"id": "1",
"name": "Schedule Monday 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
},
"position": [
250,
300
]
},
{
"id": "2",
"name": "Google Sheets Read Safety Events",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "getAll",
"sheetId": "YOUR_SHEET_ID",
"range": "SafetyEvents!A2:M1000"
},
"position": [
500,
200
]
},
{
"id": "3",
"name": "Google Sheets Read Compliance Deadlines",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "getAll",
"sheetId": "YOUR_SHEET_ID",
"range": "Deadlines!A2:L1000"
},
"position": [
500,
400
]
},
{
"id": "4",
"name": "Code Build KPI Report",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "const events = $('Google Sheets Read Safety Events').all().map(i => i.json);\nconst deadlines = $('Google Sheets Read Compliance Deadlines').all().map(i => i.json);\nconst now = new Date();\n\nconst ind7DayOpen = events.filter(e => e.clock_type === 'FDA_IND_7DAY_EXPEDITED' && e.status === 'OPEN').length;\nconst ind15DayOpen = events.filter(e => e.clock_type === 'FDA_IND_15DAY_SERIOUS' && e.status === 'OPEN').length;\nconst susarOpen = events.filter(e => e.clock_type === 'EU_EMA_CTR_SUSAR_15DAY' && e.status === 'OPEN').length;\nconst ndaApproaching = deadlines.filter(d => d.clock_type === 'NDA_ANNUAL_REPORT_60DAY' && Math.ceil((new Date(d.deadline_date) - now) / 864e5) <= 30).length;\nconst deaRecordsAtRisk = deadlines.filter(d => d.clock_type === 'DEA_SCHEDULE_II_RETENTION' && Math.ceil((new Date(d.deadline_date) - now) / 864e5) <= 60).length;\nconst remsReviewDue = deadlines.filter(d => d.clock_type === 'FDA_REMS_ANNUAL_ASSESSMENT' && Math.ceil((new Date(d.deadline_date) - now) / 864e5) <= 60).length;\nconst gcpAuditGaps = events.filter(e => e.clock_type === 'ICH_GCP_AUDIT_TRAIL' && e.status === 'OPEN').length;\n\nconst html = `<h2>Weekly BioTech/Pharma Compliance KPI Dashboard</h2><p>Week ending: ${now.toISOString().split('T')[0]}</p><table border='1'><tr><th>Metric</th><th>Count</th><th>Regulation</th></tr><tr><td>IND 7-Day Expedited Reports Open</td><td style='color:${ind7DayOpen>0?'red':'green'}'>${ind7DayOpen}</td><td>FDA 21 CFR \u00a7312.32(c)(1)</td></tr><tr><td>IND 15-Day Serious Reports Open</td><td style='color:${ind15DayOpen>0?'orange':'green'}'>${ind15DayOpen}</td><td>FDA 21 CFR \u00a7312.32(c)(2)</td></tr><tr><td>EU SUSAR Submissions Open</td><td style='color:${susarOpen>0?'orange':'green'}'>${susarOpen}</td><td>EU EMA CTR Art.42</td></tr><tr><td>NDA Annual Reports Due \u226430 Days</td><td style='color:${ndaApproaching>0?'orange':'green'}'>${ndaApproaching}</td><td>FDA 21 CFR \u00a7314.81</td></tr><tr><td>DEA Schedule II Records At Risk (\u226460 Days)</td><td style='color:${deaRecordsAtRisk>0?'orange':'green'}'>${deaRecordsAtRisk}</td><td>DEA 21 CFR Part 1304</td></tr><tr><td>REMS Annual Assessments Due \u226460 Days</td><td style='color:${remsReviewDue>0?'orange':'green'}'>${remsReviewDue}</td><td>FDA REMS Program</td></tr><tr><td>GCP Audit Trail Gaps Open</td><td style='color:${gcpAuditGaps>0?'red':'green'}'>${gcpAuditGaps}</td><td>ICH E6 R2 GCP</td></tr></table><p>Self-hosted n8n ensures all safety data, audit trails, and regulatory records remain within your infrastructure \u2014 not in a cloud automation vendor's logs discoverable under FDA inspection or EU EMA data requests.</p>`;\n\nreturn [{ json: { html, ind7DayOpen, ind15DayOpen, susarOpen, ndaApproaching, deaRecordsAtRisk, remsReviewDue, gcpAuditGaps } }];"
},
"position": [
800,
300
]
},
{
"id": "5",
"name": "Gmail Weekly KPI to CMO and CEO",
"type": "n8n-nodes-base.gmail",
"parameters": {
"to": "cmo@yourcompany.com",
"bcc": "ceo@yourcompany.com,cro@yourcompany.com",
"subject": "Weekly BioTech/Pharma Regulatory KPI Dashboard \u2014 {{ $now.format('YYYY-MM-DD') }}",
"message": "={{ $json.html }}",
"messageType": "html"
},
"position": [
1100,
300
]
}
],
"connections": {
"Schedule Monday 8AM": {
"main": [
[
{
"node": "Google Sheets Read Safety Events",
"type": "main",
"index": 0
},
{
"node": "Google Sheets Read Compliance Deadlines",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets Read Safety Events": {
"main": [
[
{
"node": "Code Build KPI Report",
"type": "main",
"index": 0
}
]
]
},
"Google Sheets Read Compliance Deadlines": {
"main": [
[
{
"node": "Code Build KPI Report",
"type": "main",
"index": 0
}
]
]
},
"Code Build KPI Report": {
"main": [
[
{
"node": "Gmail Weekly KPI to CMO and CEO",
"type": "main",
"index": 0
}
]
]
}
}
}
The Self-Hosting Argument for BioTech/Pharma SaaS
When your platform processes IND safety data, clinical trial records, or NDA submission data, the choice between cloud iPaaS and self-hosted n8n has direct regulatory consequences:
| Risk | Cloud iPaaS | Self-Hosted n8n |
|---|---|---|
| FDA Part 11 audit trail | Vendor logs FDA-inspectable | Logs within your infrastructure |
| IND 7-day receipt date | Batch polling burns hours of the clock | Webhook triggers in real-time |
| EU SUSAR 15-day awareness | Batch sync = delayed sponsor awareness | Immediate event receipt |
| DEA Part 1304 records | Vendor data retention policy applies | You control retention |
| GCP §4.9 audit trail | Vendor access logs discoverable | No third-party access |
| FDA inspection discovery | Cloud vendor logs subpoenable | Self-hosted = no vendor to subpoena |
The operational argument for self-hosted n8n in BioTech/Pharma SaaS is not primarily about cost. It is about the difference between a 7-day IND safety report submitted on time and one submitted after a batch polling cycle burned 4 hours of a 168-hour window.
These workflows and 10+ more are available at FlowKit on Gumroad — ready-to-import n8n JSON for BioTech/PharmaTech SaaS compliance automation.
Top comments (0)