MarTech and AdTech SaaS vendors sit at the intersection of the most litigated consumer privacy frameworks in the United States and the EU: TCPA class actions, CAN-SPAM FTC enforcement, GDPR Art.6 lawful basis requirements, CCPA private right of action, and IAB TCF 2.2 consent string management. The compliance automation problem is not theoretical -- it is active litigation risk.
The core infrastructure problem: consent records, opt-out logs, and CMP consent strings are your primary defense in every one of these enforcement actions. When that data flows through cloud iPaaS platforms like Zapier or Make, it exits your defined infrastructure boundary. In a TCPA class action, your consent records held in a third-party cloud automation vendor become directly subpoenable -- outside your litigation privilege boundary, without going through your counsel.
This article gives you five free n8n workflows designed for MarTech and AdTech SaaS vendors. Self-hosted n8n keeps consent data, opt-out logs, and CMP strings inside your defined infrastructure perimeter.
The Fastest Clock: TCPA Class Action Filed -- IMMEDIATE
When a TCPA class action is filed, your consent records are your primary defense -- and the litigation hold must be placed immediately. There is no grace period. The moment a complaint is filed, any deletion of consent records is potential spoliation.
The full compliance clock cascade in a TCPA enforcement scenario:
| Event | Deadline | Exposure | Regulation |
|---|---|---|---|
| TCPA class action filed | IMMEDIATE | $500-$1,500/violation | 47 U.S.C. §227(b) |
| GDPR personal data breach | 72 hours | SA notification + data subject notification | GDPR Art.33-34 |
| GDPR erasure request | 30 days | Art.17 processor propagation | GDPR Art.17 |
| CCPA data rights request | 45 days | AG enforcement $2,500-$7,500/intentional violation | Cal. Civil Code §1798.105 |
| CAN-SPAM unsubscribe | 10 business days | $46,517/email (FTC 2023) | 15 U.S.C. §7704(a)(4) |
Your incident pipeline workflow (Workflow 4 below) fires on detection and routes each incident type to the correct legal and compliance response.
Seven Customer Tiers for MarTech and AdTech SaaS
| Tier | Primary Compliance Obligations | Key Self-Hosting Argument |
|---|---|---|
| ENTERPRISE_MARTECH_PLATFORM | TCPA + GDPR Art.6 + CCPA + IAB TCF 2.2 + SOC2 | Consent strings in cloud iPaaS = consent data egress outside CMP boundary |
| EMAIL_MARKETING_SAAS | CAN-SPAM §7704 + GDPR Art.6(1)(a) + CCPA 1798.100 | Suppression list in cloud = FTC third-party subpoena target |
| CDP_CUSTOMER_DATA_PLATFORM | GDPR Art.28 DPA + CCPA service provider contract + CPRA | Cross-device identity graph in cloud = Art.44-46 transfer risk |
| ADVERTISING_TECH_DSP_SSP | IAB TCF 2.2 registered CMP + ePrivacy + GDPR Recital 47 | TCF consent string routing through cloud = GVL compliance gap |
| MARKETING_AUTOMATION_SAAS | TCPA ATDS prior express written consent + GDPR Art.7 | TCPA consent records in cloud = class action discovery outside privilege |
| INFLUENCER_MARKETING_SAAS | FTC 16 CFR §255 endorsement disclosure + COPPA 16 CFR §312 | FTC investigation: platform communications in cloud are discoverable |
| MARTECH_STARTUP | SOC2 Type II + CAN-SPAM baseline + CCPA if CA-facing | Investor due diligence: consent record architecture from day one |
Workflow 1: Consent Expiry and Opt-Out Processing Pipeline
Four opt-out paths -- TCPA revocation, CAN-SPAM unsubscribe, GDPR consent withdrawal, CCPA opt-out of sale/sharing -- each routed to the correct database record with the applicable regulation and retention requirements.
TCPA revocation records include a 4-year retention flag and a litigation note. GDPR withdrawal records include the 30-day erasure deadline. CCPA opt-out records include the 15-business-day downstream propagation deadline.
{
"name": "MarTech Consent Expiry and Opt-Out Processing Pipeline",
"nodes": [
{
"id": "w1-n1",
"name": "Opt-Out Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
240,
300
],
"parameters": {
"path": "martech-optout",
"responseMode": "onReceived",
"responseData": "firstEntryJson"
}
},
{
"id": "w1-n2",
"name": "Route by Opt-Out Type",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
460,
300
],
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.opt_out_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "TCPA_REVOCATION"
}
]
},
"renameOutput": true,
"outputKey": "TCPA"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.opt_out_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "CAN_SPAM_UNSUBSCRIBE"
}
]
},
"renameOutput": true,
"outputKey": "CAN_SPAM"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.opt_out_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "GDPR_CONSENT_WITHDRAWAL"
}
]
},
"renameOutput": true,
"outputKey": "GDPR"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.opt_out_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "CCPA_OPT_OUT_OF_SALE"
}
]
},
"renameOutput": true,
"outputKey": "CCPA"
}
]
}
}
},
{
"id": "w1-n3",
"name": "TCPA Revocation Record",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
100
],
"parameters": {
"language": "javaScript",
"jsCode": "const record = $input.first().json;\nreturn [{ json: {\n phone: record.phone,\n email: record.email,\n revocation_ts: new Date().toISOString(),\n channel_blocked: 'SMS_AND_VOICE',\n regulation: 'TCPA 47 USC 227(b)(1)(A) -- ATDS consent revocation. Effective immediately.',\n litigation_note: 'Record must be production-ready for class action discovery. Do not delete.',\n retention_until: new Date(Date.now() + 4 * 365 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]\n} }];\n"
}
},
{
"id": "w1-n4",
"name": "Log TCPA Revocation to DB",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
960,
100
],
"parameters": {
"method": "POST",
"url": "={{ $env.CONSENT_DB_URL }}/tcpa-revocations",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"body": {
"mode": "json",
"json": "={{ $json }}"
}
}
},
{
"id": "w1-n5",
"name": "CAN-SPAM Unsubscribe",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
220
],
"parameters": {
"language": "javaScript",
"jsCode": "const record = $input.first().json;\nreturn [{ json: {\n email: record.email,\n unsubscribe_ts: new Date().toISOString(),\n channel_blocked: 'COMMERCIAL_EMAIL',\n regulation: 'CAN-SPAM Act 15 USC 7704(a)(4) -- 10 business day processing deadline.',\n deadline_process_by: new Date(Date.now() + 10 * 24 * 60 * 60 * 1000).toISOString().split('T')[0]\n} }];\n"
}
},
{
"id": "w1-n6",
"name": "Log CAN-SPAM to Suppression List",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
960,
220
],
"parameters": {
"method": "POST",
"url": "={{ $env.SUPPRESSION_API_URL }}/canspam-unsubs",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"body": {
"mode": "json",
"json": "={{ $json }}"
}
}
},
{
"id": "w1-n7",
"name": "GDPR Consent Withdrawal",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
340
],
"parameters": {
"language": "javaScript",
"jsCode": "const record = $input.first().json;\nreturn [{ json: {\n user_id: record.user_id,\n email: record.email,\n withdrawal_ts: new Date().toISOString(),\n lawful_basis_removed: record.basis_type || 'CONSENT',\n regulation: 'GDPR Art.7(3) -- consent may be withdrawn at any time. Processing must stop immediately.',\n erasure_deadline: new Date(Date.now() + 30 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],\n tcf_string_revoke: true\n} }];\n"
}
},
{
"id": "w1-n8",
"name": "Log GDPR Withdrawal",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
960,
340
],
"parameters": {
"method": "POST",
"url": "={{ $env.CONSENT_DB_URL }}/gdpr-withdrawals",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"body": {
"mode": "json",
"json": "={{ $json }}"
}
}
},
{
"id": "w1-n9",
"name": "CCPA Opt-Out of Sale",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
720,
460
],
"parameters": {
"language": "javaScript",
"jsCode": "const record = $input.first().json;\nreturn [{ json: {\n consumer_id: record.consumer_id,\n email: record.email,\n optout_ts: new Date().toISOString(),\n optout_type: 'SALE_AND_SHARING',\n regulation: 'CCPA Cal. Civil Code 1798.120 -- opt-out of sale/sharing. 15 business days to downstream propagation.',\n propagation_deadline: new Date(Date.now() + 15 * 24 * 60 * 60 * 1000).toISOString().split('T')[0],\n retention_years: 2\n} }];\n"
}
},
{
"id": "w1-n10",
"name": "Log CCPA Opt-Out",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
960,
460
],
"parameters": {
"method": "POST",
"url": "={{ $env.CONSENT_DB_URL }}/ccpa-optouts",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth",
"body": {
"mode": "json",
"json": "={{ $json }}"
}
}
}
],
"connections": {
"Opt-Out Webhook": {
"main": [
[
{
"node": "Route by Opt-Out Type",
"type": "main",
"index": 0
}
]
]
},
"Route by Opt-Out Type": {
"main": [
[
{
"node": "TCPA Revocation Record",
"type": "main",
"index": 0
}
],
[
{
"node": "CAN-SPAM Unsubscribe",
"type": "main",
"index": 0
}
],
[
{
"node": "GDPR Consent Withdrawal",
"type": "main",
"index": 0
}
],
[
{
"node": "CCPA Opt-Out of Sale",
"type": "main",
"index": 0
}
]
]
},
"TCPA Revocation Record": {
"main": [
[
{
"node": "Log TCPA Revocation to DB",
"type": "main",
"index": 0
}
]
]
},
"CAN-SPAM Unsubscribe": {
"main": [
[
{
"node": "Log CAN-SPAM to Suppression List",
"type": "main",
"index": 0
}
]
]
},
"GDPR Consent Withdrawal": {
"main": [
[
{
"node": "Log GDPR Withdrawal",
"type": "main",
"index": 0
}
]
]
},
"CCPA Opt-Out of Sale": {
"main": [
[
{
"node": "Log CCPA Opt-Out",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
Workflow 2: TCPA / CAN-SPAM / GDPR / CCPA Deadline Tracker
Twelve deadline types across TCPA, CAN-SPAM, GDPR, and CCPA. Fastest clock is TCPA_CLASS_ACTION_FILED flagged IMMEDIATE -- no days-out window, because the litigation hold requirement has no grace period.
Deadline types: TCPA_CLASS_ACTION_FILED (IMMEDIATE, $500-$1500/violation), CCPA_DATA_RIGHTS_REQUEST (45d Cal. Civil Code §1798.105), GDPR_ERASURE_REQUEST (30d Art.17), CAN_SPAM_UNSUBSCRIBE_PROCESSING (10 business days), GDPR_DATA_BREACH_NOTIFICATION (72h Art.33), CCPA_OPT_OUT_PROPAGATION (15 business days), IAB_TCF_CMP_ANNUAL_AUDIT, GDPR_ROPA_ANNUAL_REVIEW (Art.30), FTC_ENDORSEMENT_DISCLOSURE_AUDIT (16 CFR §255), CCPA_PRIVACY_NOTICE_ANNUAL_REVIEW, SOC2_TYPE2_RENEWAL, ANNUAL_PENTEST.
{
"name": "TCPA / CAN-SPAM / GDPR / CCPA Compliance Deadline Tracker",
"nodes": [
{
"id": "w2-n1",
"name": "Daily 8am Check",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * *"
}
]
}
}
},
{
"id": "w2-n2",
"name": "Fetch All Customers",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
460,
300
],
"parameters": {
"method": "GET",
"url": "={{ $env.CRM_API_URL }}/customers?status=active",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
}
},
{
"id": "w2-n3",
"name": "Split Customers",
"type": "n8n-nodes-base.splitInBatches",
"typeVersion": 3,
"position": [
680,
300
],
"parameters": {
"batchSize": 1
}
},
{
"id": "w2-n4",
"name": "Check Compliance Deadlines",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
900,
300
],
"parameters": {
"language": "javaScript",
"jsCode": "const customer = $input.first().json;\nconst today = new Date();\nconst msPerDay = 86400000;\n\nconst deadlineTypes = [\n { type: 'TCPA_CLASS_ACTION_FILED', label: 'TCPA Class Action -- Consent Records Litigation Hold', daysWindow: 0, flag: 'TCPA_AUTODIALER_SUBJECT', urgency: 'IMMEDIATE', regulation: 'TCPA 47 USC 227(b) -- $500-$1500/violation. Consent records are primary defense. Must be production-ready NOW.' },\n { type: 'CCPA_DATA_RIGHTS_REQUEST', label: 'CCPA Consumer Data Rights Request', daysWindow: 45, flag: 'CCPA_COVERED_BUSINESS', urgency: 'HIGH', regulation: 'CCPA Cal. Civil Code 1798.105 -- 45-day response window for deletion requests.' },\n { type: 'GDPR_ERASURE_REQUEST', label: 'GDPR Art.17 Erasure Request (Right to be Forgotten)', daysWindow: 30, flag: 'GDPR_ART6_LAWFUL_BASIS_REQUIRED', urgency: 'HIGH', regulation: 'GDPR Art.17 -- 30-day erasure completion window. Downstream processor propagation required.' },\n { type: 'CAN_SPAM_UNSUBSCRIBE_PROCESSING', label: 'CAN-SPAM Unsubscribe Processing', daysWindow: 10, flag: 'CAN_SPAM_COVERED_COMMERCIAL_EMAIL', urgency: 'HIGH', regulation: 'CAN-SPAM Act 15 USC 7704(a)(4) -- opt-out must be honored within 10 business days.' },\n { type: 'GDPR_DATA_BREACH_NOTIFICATION', label: 'GDPR Personal Data Breach Notification', daysWindow: 3, flag: 'GDPR_ART6_LAWFUL_BASIS_REQUIRED', urgency: 'CRITICAL', regulation: 'GDPR Art.33 -- 72-hour SA notification window from discovery.' },\n { type: 'CCPA_OPT_OUT_PROPAGATION', label: 'CCPA Opt-Out Downstream Propagation', daysWindow: 15, flag: 'CCPA_COVERED_BUSINESS', urgency: 'HIGH', regulation: 'CCPA 1798.120 + CPRA -- 15 business days to notify all third parties of opt-out.' },\n { type: 'IAB_TCF_CMP_ANNUAL_AUDIT', label: 'IAB TCF 2.2 CMP Annual Compliance Audit', daysWindow: 365, flag: 'IAB_TCF_2_2_REGISTERED', urgency: 'MEDIUM', regulation: 'IAB Europe TCF Policy v2.2 -- registered CMPs subject to annual compliance review.' },\n { type: 'GDPR_ROPA_ANNUAL_REVIEW', label: 'GDPR Records of Processing Activities Annual Review', daysWindow: 365, flag: 'GDPR_ART6_LAWFUL_BASIS_REQUIRED', urgency: 'MEDIUM', regulation: 'GDPR Art.30 -- ROPA must be kept up to date and available to supervisory authority.' },\n { type: 'FTC_ENDORSEMENT_DISCLOSURE_AUDIT', label: 'FTC Endorsement Guides Annual Disclosure Audit', daysWindow: 365, flag: 'FTC_ENDORSEMENT_GUIDES', urgency: 'MEDIUM', regulation: 'FTC 16 CFR Part 255 -- material connections must be clearly disclosed in all influencer content.' },\n { type: 'CCPA_PRIVACY_NOTICE_ANNUAL_REVIEW', label: 'CCPA Privacy Notice Annual Review', daysWindow: 365, flag: 'CCPA_COVERED_BUSINESS', urgency: 'MEDIUM', regulation: 'CCPA Cal. Civil Code 1798.130 -- privacy policy must be updated annually or when practices change.' },\n { type: 'SOC2_TYPE2_RENEWAL', label: 'SOC 2 Type II Audit Renewal', daysWindow: 365, flag: 'SOC2_REQUIRED', urgency: 'MEDIUM', regulation: 'AICPA SOC 2 -- annual renewal for enterprise customer trust.' },\n { type: 'ANNUAL_PENTEST', label: 'Annual Penetration Test', daysWindow: 365, flag: None, urgency: 'MEDIUM', regulation: 'SOC 2 CC7.1 / GDPR Art.32 security measures -- annual pentest.' }\n];\n\nconst flags = customer.compliance_flags || {};\nconst lastDeadlines = customer.last_compliance_dates || {};\nconst alerts = [];\n\nfor (const d of deadlineTypes) {\n if (d.flag && !flags[d.flag]) continue;\n const lastDate = lastDeadlines[d.type] ? new Date(lastDeadlines[d.type]) : null;\n if (lastDate) {\n const nextDue = new Date(lastDate.getTime() + d.daysWindow * msPerDay);\n const daysUntil = Math.round((nextDue - today) / msPerDay);\n if (daysUntil <= 30 || d.urgency === 'IMMEDIATE' || d.urgency === 'CRITICAL') {\n alerts.push({ customer_id: customer.id, company: customer.company,\n contact: customer.compliance_contact, email: customer.compliance_email,\n deadline_type: d.type, label: d.label, days_until: daysUntil,\n urgency: d.urgency, regulation: d.regulation,\n due_date: nextDue.toISOString().split('T')[0] });\n }\n }\n}\n\nreturn alerts.map(a => ({json: a}));\n"
}
},
{
"id": "w2-n5",
"name": "Has Alerts",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
1120,
300
],
"parameters": {
"conditions": {
"number": [
{
"value1": "={{ $items().length }}",
"operation": "larger",
"value2": 0
}
]
}
}
},
{
"id": "w2-n6",
"name": "Send Deadline Alert",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
1340,
200
],
"parameters": {
"toEmail": "={{ $json.email }}",
"subject": "={{ '[' + $json.urgency + '] ' + $json.label + ' -- ' + $json.days_until + ' days' }}",
"message": "={{ 'Compliance Alert: ' + $json.label + '\\n\\nCompany: ' + $json.company + '\\nDue: ' + $json.due_date + ' (' + $json.days_until + ' days)\\nUrgency: ' + $json.urgency + '\\nRegulation: ' + $json.regulation }}"
}
}
],
"connections": {
"Daily 8am Check": {
"main": [
[
{
"node": "Fetch All Customers",
"type": "main",
"index": 0
}
]
]
},
"Fetch All Customers": {
"main": [
[
{
"node": "Split Customers",
"type": "main",
"index": 0
}
]
]
},
"Split Customers": {
"main": [
[
{
"node": "Check Compliance Deadlines",
"type": "main",
"index": 0
}
]
]
},
"Check Compliance Deadlines": {
"main": [
[
{
"node": "Has Alerts",
"type": "main",
"index": 0
}
]
]
},
"Has Alerts": {
"main": [
[
{
"node": "Send Deadline Alert",
"type": "main",
"index": 0
}
],
[]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
Workflow 3: MarTech Consent and Ad Platform API Health Monitor
Five endpoints checked every 15 minutes, each annotated with its specific compliance implication:
-
consent_management_api-- IAB TCF 2.2: CMP downtime = consent string generation failure; GDPR Art.7(1) consent record unavailability -
email_delivery_api-- CAN-SPAM §7704: suppression list must be honored within 10 business days; outage = processing delay = $46,517/email risk -
sms_gateway_api-- TCPA §227(b)(1)(A): ATDS queue backup during outage may deliver to revoked numbers = $500-1,500/violation -
cdp_sync_api-- GDPR Art.28 / CCPA §1798.140: stale consent signals in downstream systems = enforcement risk -
attribution_api-- GDPR Recital 47 / ePrivacy: outage may mask ongoing non-compliant tracking
{
"name": "MarTech Consent and Ad Platform API Health Monitor",
"nodes": [
{
"id": "w3-n1",
"name": "Every 15 Minutes",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 15
}
]
}
}
},
{
"id": "w3-n2",
"name": "Check Consent Management API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
460,
140
],
"parameters": {
"method": "GET",
"url": "={{ $env.CONSENT_MGMT_API_URL }}/health",
"timeout": 10000,
"options": {
"response": {
"response": {
"fullResponse": true
}
}
}
}
},
{
"id": "w3-n3",
"name": "Check Email Delivery API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
460,
240
],
"parameters": {
"method": "GET",
"url": "={{ $env.EMAIL_DELIVERY_API_URL }}/health",
"timeout": 10000,
"options": {
"response": {
"response": {
"fullResponse": true
}
}
}
}
},
{
"id": "w3-n4",
"name": "Check SMS Gateway API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
460,
340
],
"parameters": {
"method": "GET",
"url": "={{ $env.SMS_GATEWAY_API_URL }}/health",
"timeout": 10000,
"options": {
"response": {
"response": {
"fullResponse": true
}
}
}
}
},
{
"id": "w3-n5",
"name": "Check CDP Sync API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
460,
440
],
"parameters": {
"method": "GET",
"url": "={{ $env.CDP_SYNC_API_URL }}/health",
"timeout": 10000,
"options": {
"response": {
"response": {
"fullResponse": true
}
}
}
}
},
{
"id": "w3-n6",
"name": "Check Attribution API",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
460,
540
],
"parameters": {
"method": "GET",
"url": "={{ $env.ATTRIBUTION_API_URL }}/health",
"timeout": 10000,
"options": {
"response": {
"response": {
"fullResponse": true
}
}
}
}
},
{
"id": "w3-n7",
"name": "Aggregate Health Results",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
700,
340
],
"parameters": {
"language": "javaScript",
"jsCode": "const endpoints = [\n { name: 'consent_management_api', label: 'Consent Management Platform API',\n note: 'IAB TCF 2.2: CMP downtime = consent string generation failure = TCF Policy non-compliance. GDPR Art.7(1) consent record unavailability.',\n item: $('Check Consent Management API').first() },\n { name: 'email_delivery_api', label: 'Email Delivery API',\n note: 'CAN-SPAM Act 15 USC 7704: suppression list must be honored within 10 business days. Delivery API outage = unsubscribe processing delay = FTC $46,517/email violation risk.',\n item: $('Check Email Delivery API').first() },\n { name: 'sms_gateway_api', label: 'SMS Gateway API',\n note: 'TCPA 47 USC 227(b)(1)(A): ATDS messages require prior express written consent. Gateway outage may cause queue backup delivering to revoked numbers = $500-1500/violation.',\n item: $('Check SMS Gateway API').first() },\n { name: 'cdp_sync_api', label: 'Customer Data Platform Sync API',\n note: 'GDPR Art.28 / CCPA 1798.140: CDP sync outage = stale consent signals in downstream systems = GDPR Art.7(3) or CCPA 1798.120 enforcement risk.',\n item: $('Check CDP Sync API').first() },\n { name: 'attribution_api', label: 'Ad Attribution API',\n note: 'GDPR Recital 47 / ePrivacy: attribution tracking without valid consent basis = Art.6 violation. Outage may mask ongoing non-compliant tracking.',\n item: $('Check Attribution API').first() }\n];\n\nconst down = [];\nfor (const ep of endpoints) {\n const statusCode = ep.item?.json?.statusCode || ep.item?.json?.status || 0;\n const isDown = !statusCode || statusCode >= 400 || statusCode === 0;\n if (isDown) {\n down.push({ endpoint: ep.name, label: ep.label, note: ep.note,\n status_code: statusCode, detected_at: new Date().toISOString() });\n }\n}\nif (down.length === 0) return [{ json: { status: 'all_healthy', checked_at: new Date().toISOString() } }];\nreturn down.map(d => ({ json: d }));\n"
}
},
{
"id": "w3-n8",
"name": "Any Endpoint Down",
"type": "n8n-nodes-base.if",
"typeVersion": 1,
"position": [
920,
340
],
"parameters": {
"conditions": {
"string": [
{
"value1": "={{ $json.status }}",
"operation": "notEqual",
"value2": "all_healthy"
}
]
}
}
},
{
"id": "w3-n9",
"name": "Alert Engineering and Compliance",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
1140,
240
],
"parameters": {
"toEmail": "={{ $env.ENG_ALERT_EMAIL }}",
"ccEmail": "={{ $env.COMPLIANCE_EMAIL }}",
"subject": "=[MARTECH API DOWN] {{ $json.label }} -- Compliance Risk Active",
"message": "={{ '[MARTECH API DOWN] ' + $json.label + ' (' + $json.endpoint + ')\\nDetected: ' + $json.detected_at + '\\nHTTP Status: ' + $json.status_code + '\\n\\nCompliance note: ' + $json.note }}"
}
}
],
"connections": {
"Every 15 Minutes": {
"main": [
[
{
"node": "Check Consent Management API",
"type": "main",
"index": 0
},
{
"node": "Check Email Delivery API",
"type": "main",
"index": 0
},
{
"node": "Check SMS Gateway API",
"type": "main",
"index": 0
},
{
"node": "Check CDP Sync API",
"type": "main",
"index": 0
},
{
"node": "Check Attribution API",
"type": "main",
"index": 0
}
]
]
},
"Check Consent Management API": {
"main": [
[
{
"node": "Aggregate Health Results",
"type": "main",
"index": 0
}
]
]
},
"Check Email Delivery API": {
"main": [
[
{
"node": "Aggregate Health Results",
"type": "main",
"index": 0
}
]
]
},
"Check SMS Gateway API": {
"main": [
[
{
"node": "Aggregate Health Results",
"type": "main",
"index": 0
}
]
]
},
"Check CDP Sync API": {
"main": [
[
{
"node": "Aggregate Health Results",
"type": "main",
"index": 0
}
]
]
},
"Check Attribution API": {
"main": [
[
{
"node": "Aggregate Health Results",
"type": "main",
"index": 0
}
]
]
},
"Aggregate Health Results": {
"main": [
[
{
"node": "Any Endpoint Down",
"type": "main",
"index": 0
}
]
]
},
"Any Endpoint Down": {
"main": [
[
{
"node": "Alert Engineering and Compliance",
"type": "main",
"index": 0
}
],
[]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
Workflow 4: Compliance Incident Pipeline
Eight incident types routed to the correct response with pre-filled templates. TCPA class action is the fastest trigger -- IMMEDIATE with a litigation hold instruction. The pipeline runs inside your self-hosted n8n instance so consent records do not transit a third-party system during the incident response.
Incident types: TCPA_CLASS_ACTION_FILED (IMMEDIATE -- consent records litigation hold), CAN_SPAM_FTC_COMPLAINT ($46,517/email), GDPR_PERSONAL_DATA_BREACH (72h SA notification), CCPA_DATA_RIGHTS_REQUEST (45d), IAB_TCF_CONSENT_COMPLAINT, FTC_ENDORSEMENT_INVESTIGATION, CCPA_AG_ENFORCEMENT ($2,500-$7,500/violation), DATA_BREACH_MARKETING_PII (multi-regime 72h).
{
"name": "MarTech Compliance Incident Pipeline",
"nodes": [
{
"id": "w4-n1",
"name": "Incident Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 1,
"position": [
240,
300
],
"parameters": {
"path": "martech-compliance-incident",
"responseMode": "onReceived",
"responseData": "firstEntryJson"
}
},
{
"id": "w4-n2",
"name": "Route by Incident Type",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
460,
300
],
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "TCPA_CLASS_ACTION_FILED"
}
]
},
"renameOutput": true,
"outputKey": "TCPA_LITIGATION"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "CAN_SPAM_FTC_COMPLAINT"
}
]
},
"renameOutput": true,
"outputKey": "CAN_SPAM_FTC"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "GDPR_PERSONAL_DATA_BREACH"
}
]
},
"renameOutput": true,
"outputKey": "GDPR_BREACH"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "CCPA_DATA_RIGHTS_REQUEST"
}
]
},
"renameOutput": true,
"outputKey": "CCPA_RIGHTS"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "IAB_TCF_CONSENT_COMPLAINT"
}
]
},
"renameOutput": true,
"outputKey": "IAB_TCF"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "FTC_ENDORSEMENT_INVESTIGATION"
}
]
},
"renameOutput": true,
"outputKey": "FTC_ENDORSEMENT"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "CCPA_AG_ENFORCEMENT"
}
]
},
"renameOutput": true,
"outputKey": "CCPA_AG"
},
{
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"operator": {
"type": "string",
"operation": "equals"
},
"rightValue": "DATA_BREACH_MARKETING_PII"
}
]
},
"renameOutput": true,
"outputKey": "DATA_BREACH"
}
]
}
}
},
{
"id": "w4-n3",
"name": "TCPA Litigation IMMEDIATE",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
720,
80
],
"parameters": {
"toEmail": "={{ $env.LEGAL_EMAIL }}",
"ccEmail": "={{ $env.COMPLIANCE_EMAIL }}",
"subject": "[IMMEDIATE TCPA CLASS ACTION] {{ $json.incident_title }} -- Consent Records Litigation Hold NOW",
"message": "={{ '[TCPA CLASS ACTION FILED]\\nCase: ' + $json.incident_title + '\\nFiled: ' + $json.detected_at + '\\nEXPOSURE: $500-$1500 per violation. Class actions routinely cover millions of messages.\\n\\nIMMEDIATE ACTIONS:\\n1. Place litigation hold on ALL consent records (TCPA written consent log)\\n2. Suspend all ATDS SMS/voice campaigns pending consent record audit\\n3. Do NOT delete any opt-out or consent records\\n4. Consent records in cloud iPaaS vendor: notify vendor of litigation hold NOW\\n5. Contact outside litigation counsel within 24h.' }}"
}
},
{
"id": "w4-n4",
"name": "GDPR Breach 72H Alert",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
720,
200
],
"parameters": {
"toEmail": "={{ $env.DPO_EMAIL }}",
"ccEmail": "={{ $env.COMPLIANCE_EMAIL }}",
"subject": "[72H CLOCK GDPR BREACH] {{ $json.incident_title }} -- Supervisory Authority Notification",
"message": "={{ '[GDPR PERSONAL DATA BREACH]\\nIncident: ' + $json.incident_title + '\\nDiscovery: ' + $json.detected_at + '\\n72h SA notification deadline: ' + $json.sa_notification_deadline + '\\n\\nGDPR Art.33: notify supervisory authority within 72h unless unlikely to result in risk.\\nGDPR Art.34: notify data subjects if high risk.\\nRecord breach in ROPA even if no notification required.' }}"
}
},
{
"id": "w4-n5",
"name": "CCPA Rights Request 45D",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
720,
320
],
"parameters": {
"toEmail": "={{ $env.PRIVACY_OPS_EMAIL }}",
"subject": "[45D CCPA] {{ $json.incident_title }} -- Consumer Data Rights Request",
"message": "={{ '[CCPA DATA RIGHTS REQUEST]\\nConsumer: ' + $json.consumer_id + '\\nRequest type: ' + ($json.request_type || 'DELETION') + '\\nReceived: ' + $json.detected_at + '\\nDeadline: ' + $json.ccpa_deadline + '\\n\\nCal. Civil Code 1798.105: 45 days to respond (extendable 45 days with notice).\\nPropagate opt-out to all downstream data buyers within 15 business days.' }}"
}
},
{
"id": "w4-n6",
"name": "CAN-SPAM FTC Complaint",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
720,
440
],
"parameters": {
"toEmail": "={{ $env.LEGAL_EMAIL }}",
"ccEmail": "={{ $env.COMPLIANCE_EMAIL }}",
"subject": "[CAN-SPAM FTC] {{ $json.incident_title }} -- $46,517/email violation exposure",
"message": "={{ '[CAN-SPAM FTC COMPLAINT]\\nComplaint: ' + $json.incident_title + '\\nReceived: ' + $json.detected_at + '\\n\\nCAN-SPAM Act civil penalty: $46,517 per email (FTC 2023 adjustment 15 USC 45).\\nPriority audit: (1) suppression list processing within 10 business days (2) physical address in footer (3) non-deceptive subject lines (4) opt-out mechanism functional.' }}"
}
},
{
"id": "w4-n7",
"name": "Data Breach Marketing PII",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
720,
560
],
"parameters": {
"toEmail": "={{ $env.CISO_EMAIL }}",
"ccEmail": "={{ $env.LEGAL_EMAIL + ',' + $env.COMPLIANCE_EMAIL }}",
"subject": "[DATA BREACH MARKETING PII] {{ $json.incident_title }} -- Multi-Regime Notification",
"message": "={{ '[DATA BREACH -- MARKETING PII]\\nIncident: ' + $json.incident_title + '\\nDiscovery: ' + $json.detected_at + '\\n\\nNotification cascade:\\n- GDPR Art.33: 72h SA notification\\n- CCPA 1798.150: private right of action if unreasonable security\\n- State breach laws: 50-state patchwork (fastest: 30-72h depending on state)\\n- FTC Act 15 USC 45: unreasonable security = unfair practice\\n\\nConsent records and opt-out logs: separate litigation hold immediately.' }}"
}
}
],
"connections": {
"Incident Webhook": {
"main": [
[
{
"node": "Route by Incident Type",
"type": "main",
"index": 0
}
]
]
},
"Route by Incident Type": {
"main": [
[
{
"node": "TCPA Litigation IMMEDIATE",
"type": "main",
"index": 0
}
],
[
{
"node": "CAN-SPAM FTC Complaint",
"type": "main",
"index": 0
}
],
[
{
"node": "GDPR Breach 72H Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "CCPA Rights Request 45D",
"type": "main",
"index": 0
}
],
[
{
"node": "GDPR Breach 72H Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "CAN-SPAM FTC Complaint",
"type": "main",
"index": 0
}
],
[
{
"node": "CCPA Rights Request 45D",
"type": "main",
"index": 0
}
],
[
{
"node": "Data Breach Marketing PII",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
Workflow 5: Weekly MarTech Compliance KPI Dashboard
Monday 08:00 UTC pull of business metrics plus compliance status. Email to CEO with BCC to CCO and CPO. Subject line includes TCPA litigation open count and GDPR erasure request count so leadership sees consent compliance posture at a glance.
{
"name": "MarTech SaaS Weekly Compliance KPI Dashboard",
"nodes": [
{
"id": "w5-n1",
"name": "Monday 8am KPI Pull",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
}
},
{
"id": "w5-n2",
"name": "Fetch Business Metrics",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
460,
240
],
"parameters": {
"method": "GET",
"url": "={{ $env.METRICS_API_URL }}/weekly-kpi",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
}
},
{
"id": "w5-n3",
"name": "Fetch Compliance Status",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
460,
360
],
"parameters": {
"method": "GET",
"url": "={{ $env.COMPLIANCE_API_URL }}/open-items",
"authentication": "genericCredentialType",
"genericAuthType": "httpHeaderAuth"
}
},
{
"id": "w5-n4",
"name": "Build KPI Report",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
700,
300
],
"parameters": {
"language": "javaScript",
"jsCode": "const metrics = $('Fetch Business Metrics').first().json;\nconst compliance = $('Fetch Compliance Status').first().json;\nconst week = new Date().toISOString().split('T')[0];\n\nconst lines = [\n '=== MarTech/AdTech SaaS Weekly KPI -- ' + week + ' ===',\n '',\n 'BUSINESS METRICS',\n 'Active Customers: ' + (metrics.active_customers || 0),\n 'MRR: $' + (metrics.mrr || 0).toLocaleString(),\n 'MRR Growth WoW: ' + (metrics.mrr_growth_pct || 0) + '%',\n 'Emails Sent 7d: ' + (metrics.emails_sent_7d || 0).toLocaleString(),\n 'SMS Sent 7d: ' + (metrics.sms_sent_7d || 0).toLocaleString(),\n 'New Signups 7d: ' + (metrics.new_signups_7d || 0),\n '',\n 'COMPLIANCE DASHBOARD',\n 'TCPA Consent Records Audited: ' + (compliance.tcpa_records_audited || 0),\n 'CAN-SPAM Unsubs Pending (>10biz): ' + (compliance.canspam_unsubs_overdue || 0),\n 'GDPR Erasure Requests Open: ' + (compliance.gdpr_erasure_open || 0),\n 'CCPA Rights Requests Open: ' + (compliance.ccpa_requests_open || 0),\n 'TCPA Litigation Open: ' + (compliance.tcpa_litigation_open || 0),\n 'Overdue Compliance Items: ' + (compliance.overdue_items || 0),\n '',\n 'API HEALTH past 7 days',\n 'Consent CMP API uptime: ' + (metrics.cmp_api_uptime_pct || '--') + '%',\n 'Email Delivery API uptime: ' + (metrics.email_api_uptime_pct || '--') + '%',\n 'SMS Gateway API uptime: ' + (metrics.sms_api_uptime_pct || '--') + '%',\n '',\n '--- Sent by n8n compliance automation ---'\n];\n\nreturn [{ json: { report: lines.join('\\n'), week, metrics, compliance } }];\n"
}
},
{
"id": "w5-n5",
"name": "Send to CEO BCC CCO CPO",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
940,
300
],
"parameters": {
"toEmail": "={{ $env.CEO_EMAIL }}",
"bccEmail": "={{ $env.CCO_EMAIL + ',' + $env.CPO_EMAIL }}",
"subject": "=[MarTech KPI] Week of {{ $json.week }} -- MRR ${{ $json.metrics.mrr }} / TCPA {{ $json.compliance.tcpa_litigation_open }} open / GDPR {{ $json.compliance.gdpr_erasure_open }} open",
"message": "={{ $json.report }}"
}
}
],
"connections": {
"Monday 8am KPI Pull": {
"main": [
[
{
"node": "Fetch Business Metrics",
"type": "main",
"index": 0
},
{
"node": "Fetch Compliance Status",
"type": "main",
"index": 0
}
]
]
},
"Fetch Business Metrics": {
"main": [
[
{
"node": "Build KPI Report",
"type": "main",
"index": 0
}
]
]
},
"Fetch Compliance Status": {
"main": [
[
{
"node": "Build KPI Report",
"type": "main",
"index": 0
}
]
]
},
"Build KPI Report": {
"main": [
[
{
"node": "Send to CEO BCC CCO CPO",
"type": "main",
"index": 0
}
]
]
}
},
"settings": {
"executionOrder": "v1"
}
}
Five Self-Hosting Procurement Arguments for MarTech and AdTech SaaS
When your enterprise customer's legal or privacy team asks why they cannot use their existing Zapier or Make subscription:
1. TCPA Consent Records Are Litigation Hold Records
In a TCPA class action, the plaintiff's counsel can subpoena your cloud automation vendor directly for consent records and opt-out logs without going through your legal team. If consent records flow through a cloud iPaaS, that vendor holds copies outside your litigation privilege boundary. Self-hosted n8n keeps consent record processing inside your defined infrastructure -- one privilege boundary, your counsel controls discovery.
2. IAB TCF 2.2 Consent String Boundary
IAB Europe's Transparency & Consent Framework requires registered CMPs to demonstrate that consent signals are processed within their registered platform boundary. When consent strings transit cloud automation infrastructure, they cross from your registered CMP boundary into an unregistered third-party system. IAB Europe compliance auditors check CMP boundary integrity. Unregistered external processing is a GVL compliance gap.
3. GDPR Art.28 Data Processing Agreement Gap
Every cloud iPaaS that processes EU personal data -- including email addresses, device IDs, and advertising IDs in automation flows -- is a data processor under GDPR Art.28 requiring a signed DPA and an Art.46 transfer mechanism under Schrems II. Most cloud automation vendors provide a standard DPA, but the data transfer to US infrastructure still requires an adequacy decision or Standard Contractual Clauses. Self-hosted n8n deployed in EU infrastructure eliminates the transfer problem entirely.
4. CCPA Service Provider vs. Sale Distinction
Under CCPA Cal. Civil Code §1798.140(ag), sharing consumer data with a cloud automation vendor requires a written contract limiting that vendor to providing services on your behalf -- not using the data for its own purposes. If your cloud iPaaS collects aggregate analytics, uses data for product improvement, or processes consumer data for any purpose outside your service agreement, the transfer may qualify as a 'sale' or 'sharing' under CCPA §1798.140(ah). Self-hosted n8n processes consumer data under your control -- no third-party data use, no CCPA service provider contract required.
5. CAN-SPAM FTC Administrative Subpoena
The FTC has administrative subpoena authority under 15 U.S.C. §57b-1. Email delivery logs and suppression list records held in cloud automation infrastructure are directly subpoenable by the FTC without notice to your legal team. Self-hosted n8n keeps email compliance records inside your infrastructure, where your legal team controls production.
Get the Pre-Built Templates
All five workflows are in the FlowKit n8n Automation Templates store as part of the complete compliance automation bundle.
The full MarTech/AdTech SaaS compliance bundle includes:
- Consent expiry and opt-out pipeline (TCPA + CAN-SPAM + GDPR Art.7 + CCPA)
- TCPA / CAN-SPAM / GDPR / CCPA deadline tracker (12 deadline types)
- MarTech API health monitor with consent compliance annotations
- Incident pipeline (8 incident types, fastest: TCPA class action IMMEDIATE)
- Weekly KPI dashboard (CEO + BCC CCO + CPO)
- IAB TCF 2.2 CMP boundary audit checklist
- CCPA data map and service provider contract template
Free workflow JSON is in this article. The bundle includes pre-configured credentials templates and the MarTech compliance clock reference card.
MarTech and AdTech SaaS compliance automation built with n8n. Self-hosted. Your consent boundary.
Top comments (0)