/ data / compliance / requirements.json
requirements.json
  1  {
  2    "_comment": "Country+channel compliance requirements. Booleans unless noted. 'warn' = log warning only, do not block. optOutSpintax is appended to SMS templates at generation time by create-locale-templates.js. optOutFallback is used by sms.js safety net at send time (US/CA only).",
  3    "_flags": {
  4      "requiresPhysicalAddress": "Email must include sender's street address in footer (CAN-SPAM / Spam Act)",
  5      "requiresUnsubscribeLink": "Email must include functional unsubscribe link",
  6      "requiresOptOutInBody": "SMS body must contain opt-out instructions. Twilio processes STOP case-insensitively. Use lowercase 'stop' for optional markets (less spammy); keep 'STOP' uppercase for US/CA where CTIA Best Practices explicitly recommend the visible keyword.",
  7      "requiresSenderIdInBody": "SMS body must identify the sender by name/company",
  8      "requiresBusinessHours": "SMS only sent 8am-9pm recipient's local time",
  9      "requiresExpressConsent": "Prior written consent required — 'warn' because we send informational-only cold outreach",
 10      "requiresGdprVerification": "Company email must be verified before sending (EU/GDPR countries)",
 11      "requiresImpressum": "German legal disclosure (Impressum) required — 'warn' only, complex to automate",
 12      "optOutSpintax": "Spintax appended to SMS body_spintax by create-locale-templates.js at generation time. STOP/stop must appear in Latin characters (Twilio keyword). Non-English countries: keep STOP in caps (recognisable loan word).",
 13      "optOutFallback": "Plain text appended by sms.js safety net if STOP absent from body at send time (US/CA/KR only)"
 14    },
 15    "AU": {
 16      "email": {
 17        "requiresPhysicalAddress": true,
 18        "requiresUnsubscribeLink": true
 19      },
 20      "sms": {
 21        "requiresOptOutInBody": false,
 22        "requiresSenderIdInBody": false,
 23        "requiresBusinessHours": false,
 24        "optOutSpintax": "{Not interested? Just reply 'stop'.|Happy to remove you — just text STOP.|No problem — text 'stop' to unsubscribe.|Rather not hear from me? Just reply STOP.}"
 25      }
 26    },
 27    "NZ": {
 28      "email": {
 29        "requiresPhysicalAddress": true,
 30        "requiresUnsubscribeLink": true
 31      },
 32      "sms": {
 33        "requiresOptOutInBody": false,
 34        "requiresSenderIdInBody": false,
 35        "requiresBusinessHours": false,
 36        "optOutSpintax": "{Not for you? Just reply 'stop'.|No worries — just text STOP.|Want out? Reply 'stop' anytime.|Rather not? Just text STOP.}"
 37      }
 38    },
 39    "GB": {
 40      "email": {
 41        "requiresPhysicalAddress": true,
 42        "requiresUnsubscribeLink": true
 43      },
 44      "sms": {
 45        "requiresOptOutInBody": false,
 46        "requiresSenderIdInBody": false,
 47        "requiresBusinessHours": false,
 48        "optOutSpintax": "{Not for you? Text 'stop' anytime.|Reply STOP if you'd rather not hear from us.|No problem — just reply 'stop'.|Prefer not to receive these? Text STOP.}"
 49      }
 50    },
 51    "IE": {
 52      "email": {
 53        "requiresPhysicalAddress": true,
 54        "requiresUnsubscribeLink": true
 55      },
 56      "sms": {
 57        "requiresOptOutInBody": false,
 58        "requiresSenderIdInBody": false,
 59        "requiresBusinessHours": false,
 60        "optOutSpintax": "{Not for you? Text 'stop' anytime.|Reply STOP if you'd rather not hear from us.|No bother — just reply 'stop'.|Prefer not to receive these? Text STOP.}"
 61      }
 62    },
 63    "CA": {
 64      "email": {
 65        "requiresPhysicalAddress": true,
 66        "requiresUnsubscribeLink": true
 67      },
 68      "sms": {
 69        "requiresOptOutInBody": true,
 70        "requiresSenderIdInBody": true,
 71        "requiresBusinessHours": true,
 72        "requiresExpressConsent": "warn",
 73        "optOutSpintax": "{Reply STOP to opt out.|Text STOP anytime to unsubscribe.|Want to stop? Reply STOP.|No longer interested? Reply STOP.}",
 74        "optOutFallback": "Reply STOP to opt out."
 75      }
 76    },
 77    "US": {
 78      "email": {
 79        "requiresPhysicalAddress": true,
 80        "requiresUnsubscribeLink": true
 81      },
 82      "sms": {
 83        "requiresOptOutInBody": true,
 84        "requiresSenderIdInBody": true,
 85        "requiresBusinessHours": true,
 86        "requiresExpressConsent": "warn",
 87        "optOutSpintax": "{Reply STOP to opt out.|Text STOP anytime to unsubscribe.|Want to stop? Reply STOP.|No longer interested? Reply STOP.}",
 88        "optOutFallback": "Reply STOP to opt out."
 89      }
 90    },
 91    "IN": {
 92      "email": {
 93        "requiresPhysicalAddress": false,
 94        "requiresUnsubscribeLink": true
 95      },
 96      "sms": {
 97        "requiresOptOutInBody": false,
 98        "requiresSenderIdInBody": false,
 99        "requiresBusinessHours": false,
100        "optOutSpintax": "{Not interested? Reply 'stop'.|No worries — just text STOP.|Want to opt out? Reply 'stop'.|Happy to remove you — just reply STOP.}"
101      }
102    },
103    "JP": {
104      "_comment": "Japan Anti-Spam Act is consent-centric — no opt-out text required in message body. Processing STOP/opt-out replies is required at campaign level. STOP processed by Twilio globally.",
105      "email": {
106        "requiresPhysicalAddress": true,
107        "requiresUnsubscribeLink": true
108      },
109      "sms": {
110        "requiresOptOutInBody": false,
111        "requiresSenderIdInBody": false,
112        "requiresBusinessHours": false,
113        "optOutSpintax": "{ご不要の場合は STOP とご返信ください。|配信停止は STOP とご返信ください。|不要な方は STOP とご返信いただければ停止します。|ご興味なければ STOP とご返信ください。}"
114      }
115    },
116    "KR": {
117      "_comment": "Korean Network Act (정보통신망법) mandates opt-out instructions in every promotional SMS. '수신거부' is the standard Korean keyword; STOP also processed by Twilio. No optOutFallback — Korean opt-out must be in Korean.",
118      "email": {
119        "requiresPhysicalAddress": true,
120        "requiresUnsubscribeLink": true
121      },
122      "sms": {
123        "requiresOptOutInBody": true,
124        "requiresSenderIdInBody": false,
125        "requiresBusinessHours": false,
126        "optOutSpintax": "{원치 않으시면 STOP 으로 답장하세요.|수신 거부하려면 STOP 으로 답장하세요.|더 이상 받고 싶지 않으시면 STOP 으로 답장해 주세요.|수신 취소: STOP 으로 답장하세요.}",
127        "optOutFallback": "수신 거부: STOP 으로 답장하세요."
128      }
129    },
130    "DE": {
131      "email": {
132        "requiresPhysicalAddress": true,
133        "requiresUnsubscribeLink": true,
134        "requiresGdprVerification": true,
135        "requiresImpressum": "warn"
136      },
137      "sms": {
138        "requiresOptOutInBody": false,
139        "requiresSenderIdInBody": false,
140        "requiresBusinessHours": false,
141        "optOutSpintax": "{Kein Interesse? Antworten Sie mit STOP.|Abmelden: einfach STOP antworten.|Nicht mehr interessiert? Einfach STOP zurückschreiben.|Kein Problem — antworte einfach STOP.}"
142      }
143    },
144    "FR": {
145      "email": {
146        "requiresPhysicalAddress": true,
147        "requiresUnsubscribeLink": true,
148        "requiresGdprVerification": true
149      },
150      "sms": {
151        "requiresOptOutInBody": false,
152        "requiresSenderIdInBody": false,
153        "requiresBusinessHours": false,
154        "optOutSpintax": "{Pas intéressé ? Répondez STOP.|Pour vous désabonner, répondez STOP.|Pas de problème — répondez simplement STOP.|Plus intéressé ? Un STOP suffit.}"
155      }
156    },
157    "IT": {
158      "email": {
159        "requiresPhysicalAddress": true,
160        "requiresUnsubscribeLink": true,
161        "requiresGdprVerification": true
162      },
163      "sms": {
164        "requiresOptOutInBody": false,
165        "requiresSenderIdInBody": false,
166        "requiresBusinessHours": false,
167        "optOutSpintax": "{Non interessato? Rispondi STOP.|Per cancellare l'iscrizione, rispondi STOP.|Nessun problema — rispondi STOP per disiscriverti.|Non vuoi più ricevermi? Rispondi STOP.}"
168      }
169    },
170    "ES": {
171      "email": {
172        "requiresPhysicalAddress": true,
173        "requiresUnsubscribeLink": true,
174        "requiresGdprVerification": true
175      },
176      "sms": {
177        "requiresOptOutInBody": false,
178        "requiresSenderIdInBody": false,
179        "requiresBusinessHours": false,
180        "optOutSpintax": "{¿No te interesa? Responde STOP.|Para cancelar, responde STOP.|Sin problema — responde STOP cuando quieras.|¿Ya no te interesa? Basta con responder STOP.}"
181      }
182    },
183    "MX": {
184      "email": {
185        "requiresPhysicalAddress": false,
186        "requiresUnsubscribeLink": true
187      },
188      "sms": {
189        "requiresOptOutInBody": false,
190        "requiresSenderIdInBody": false,
191        "requiresBusinessHours": false,
192        "optOutSpintax": "{¿No te interesa? Responde STOP.|Para cancelar, responde STOP.|Sin problema — responde STOP cuando quieras.|¿Ya no te interesa? Basta con responder STOP.}"
193      }
194    },
195    "NL": {
196      "email": {
197        "requiresPhysicalAddress": true,
198        "requiresUnsubscribeLink": true,
199        "requiresGdprVerification": true
200      },
201      "sms": {
202        "requiresOptOutInBody": false,
203        "requiresSenderIdInBody": false,
204        "requiresBusinessHours": false,
205        "optOutSpintax": "{Geen interesse? Stuur STOP terug.|Afmelden: antwoord STOP.|Liever niet meer ontvangen? Antwoord STOP.|Geen probleem — stuur gewoon STOP terug.}"
206      }
207    },
208    "SE": {
209      "email": {
210        "requiresPhysicalAddress": true,
211        "requiresUnsubscribeLink": true,
212        "requiresGdprVerification": true
213      },
214      "sms": {
215        "requiresOptOutInBody": false,
216        "requiresSenderIdInBody": false,
217        "requiresBusinessHours": false,
218        "optOutSpintax": "{Inte intresserad? Svara STOP.|Avregistrera dig: svara STOP.|Inga problem — svara bara STOP.|Vill du sluta ta emot? Svara STOP.}"
219      }
220    },
221    "DK": {
222      "email": {
223        "requiresPhysicalAddress": true,
224        "requiresUnsubscribeLink": true,
225        "requiresGdprVerification": true
226      },
227      "sms": {
228        "requiresOptOutInBody": false,
229        "requiresSenderIdInBody": false,
230        "requiresBusinessHours": false,
231        "optOutSpintax": "{Ikke interesseret? Svar STOP.|Afmeld: svar STOP.|Intet problem — svar bare STOP.|Vil du afmelde dig? Svar STOP.}"
232      }
233    },
234    "PL": {
235      "email": {
236        "requiresPhysicalAddress": true,
237        "requiresUnsubscribeLink": true,
238        "requiresGdprVerification": true
239      },
240      "sms": {
241        "requiresOptOutInBody": false,
242        "requiresSenderIdInBody": false,
243        "requiresBusinessHours": false,
244        "optOutSpintax": "{Nie jesteś zainteresowany? Odpowiedz STOP.|Aby zrezygnować, odpowiedz STOP.|Bez problemu — wystarczy odpowiedzieć STOP.|Chcesz zrezygnować? Odpowiedz STOP.}"
245      }
246    },
247    "ID": {
248      "email": {
249        "requiresPhysicalAddress": false,
250        "requiresUnsubscribeLink": true
251      },
252      "sms": {
253        "requiresOptOutInBody": false,
254        "requiresSenderIdInBody": false,
255        "requiresBusinessHours": false,
256        "optOutSpintax": "{Tidak tertarik? Balas STOP.|Untuk berhenti, balas STOP.|Tidak masalah — cukup balas STOP.|Ingin berhenti menerima pesan? Balas STOP.}"
257      }
258    },
259    "ZA": {
260      "email": {
261        "requiresPhysicalAddress": true,
262        "requiresUnsubscribeLink": true
263      },
264      "sms": {
265        "requiresOptOutInBody": false,
266        "requiresSenderIdInBody": false,
267        "requiresBusinessHours": false,
268        "optOutSpintax": "{Not interested? Just reply 'stop'.|Happy to remove you — just text STOP.|No problem — text 'stop' to unsubscribe.|Rather not hear from me? Just reply STOP.}"
269      }
270    }
271  }