new-site/scripts/workers/create_campaigns.py
justin f8cd37ac8c Initial commit — Performance West telecom compliance platform
Includes: API (Express/TypeScript), Astro site, Python workers,
document generators, FCC compliance tools, Canada CRTC formation,
Ansible infrastructure, and deployment scripts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-27 06:54:22 -05:00

829 lines
55 KiB
Python

#!/usr/bin/env python3
"""
create_campaigns.py — Build and POST all Listmonk email campaigns.
Lists:
3 = FCC Carriers - Direct Contacts (7 emails, ISP-first angle, FCC enforcement last)
4 = FCC Carriers - Outside Counsel (5 emails, legal/liability angle)
5 = FCC compliance Removed - Noncompliant (1 email, emergency recovery)
6 = FCC Carriers - ISP / Broadband (7 emails, clean-separation angle)
Run: python3 scripts/workers/create_campaigns.py
"""
import requests, json, sys
LISTMONK_URL = "https://lists.performancewest.net"
AUTH = ("api", "6X1rKPea61N4rZ1S65Hx5zvqzbCj30F6nvEe9oVGH_Y")
URL = "https://performancewest.net/order/canada-crtc"
PHONE = "1-888-411-0383"
EMAIL = "info@performancewest.net"
CONTACT = (
f'Email <a href="mailto:{EMAIL}" style="color:#e63f2a;text-decoration:none;">{EMAIL}</a> '
f'or call <a href="tel:+18884110383" style="color:#e63f2a;text-decoration:none;">{PHONE}</a>'
)
# ── Footers ──────────────────────────────────────────────────────────────────
RMD_NOTE = ""
REM_NOTE = ""
COUN_NOTE = ""
# ── HTML helpers ─────────────────────────────────────────────────────────────
def hdr(eyebrow, headline, sub=None):
s = f'<p style="margin:8px 0 0;font-family:Arial,sans-serif;font-size:13px;color:#a0b4cc;line-height:1.5;">{sub}</p>' if sub else ''
return (
'<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="background:#1a2744;padding:0;">'
'<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding:18px 40px 14px;">'
'<table cellpadding="0" cellspacing="0" border="0"><tr>'
'<td style="vertical-align:middle;padding-right:12px;"><img src="https://performancewest.net/images/logo.png" width="90" alt="Performance West" style="display:block;width:90px;height:auto;"></td>'
'<td style="vertical-align:middle;border-left:1px solid #2d4e78;padding-left:12px;"><span style="color:#8fa8d0;font-family:Arial,sans-serif;font-size:11px;letter-spacing:1.5px;text-transform:uppercase;">Telecom Services</span></td>'
'</tr></table></td></tr></table>'
'<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="background:#e63f2a;height:3px;font-size:0;line-height:0;">&nbsp;</td></tr></table>'
'<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding:28px 40px 32px;">'
f'<p style="margin:0 0 8px;font-family:Arial,sans-serif;font-size:11px;color:#e63f2a;letter-spacing:2px;text-transform:uppercase;font-weight:600;">{eyebrow}</p>'
f'<h1 style="margin:0;font-family:Arial,sans-serif;font-size:24px;font-weight:700;color:#ffffff;line-height:1.3;">{headline}</h1>{s}'
'</td></tr></table></td></tr></table>'
)
def flagbar(left, right):
return (
'<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="background:#f0f4ff;padding:10px 40px;border-bottom:1px solid #dde5f0;">'
'<table cellpadding="0" cellspacing="0" border="0"><tr>'
'<td style="padding-right:16px;vertical-align:middle;"><img src="https://performancewest.net/images/flags/usa.png" width="22" height="14" alt="USA" style="display:inline;vertical-align:middle;">'
f'<span style="font-family:Arial,sans-serif;font-size:12px;color:#4a5568;margin-left:6px;vertical-align:middle;">{left}</span></td>'
'<td style="padding:0 16px;color:#cbd5e0;font-size:14px;vertical-align:middle;">&rarr;</td>'
'<td style="vertical-align:middle;"><img src="https://performancewest.net/images/flags/canada.png" width="22" height="14" alt="Canada" style="display:inline;vertical-align:middle;">'
f'<span style="font-family:Arial,sans-serif;font-size:12px;color:#4a5568;margin-left:6px;vertical-align:middle;">{right}</span></td>'
'</tr></table></td></tr></table>'
)
def stats(*items):
w = 100 // len(items)
cells = "".join(
f'<td width="{w}%" style="padding:0 6px;"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr>'
f'<td style="background:#1a2744;border-radius:6px;padding:18px 12px;text-align:center;">'
f'<div style="font-family:Arial,sans-serif;font-size:26px;font-weight:700;color:#ffffff;line-height:1;">{v}</div>'
f'<div style="font-family:Arial,sans-serif;font-size:11px;color:#8fa8d0;margin-top:6px;line-height:1.4;">{l}</div>'
'</td></tr></table></td>'
for v, l in items
)
return f'<table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:24px 0;"><tr>{cells}</tr></table>'
def cta(text, url):
return (
'<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td align="center">'
'<table cellpadding="0" cellspacing="0" border="0" style="margin:28px auto;"><tr>'
f'<td style="background:#e63f2a;border-radius:4px;"><a href="{url}" style="display:inline-block;padding:14px 36px;font-family:Arial,sans-serif;font-size:15px;font-weight:700;color:#ffffff;text-decoration:none;">{text}</a></td>'
'</tr></table></td></tr></table>'
)
def carriers_block():
data = [
("Twilio","NASDAQ: TWLO"),("Bandwidth","NASDAQ: BAND"),("Telnyx","Washington DC"),("RingCentral","NYSE: RNG"),
("Vonage","Holmdel NJ"),("8x8","NASDAQ: EGHT"),("Zoom Phone","NASDAQ: ZM"),("Dialpad","San Ramon CA"),
("Google Voice","Alphabet / GOOGL"),("Ooma","NYSE: OOMA"),("Onvoy / Sinch","OMX: SINCH"),("Sangoma","NASDAQ: SANG"),
]
rows = ""
for i in range(0, len(data), 4):
cells = "".join(
f'<td width="25%" style="padding:4px;"><table width="100%" cellpadding="0" cellspacing="0" border="0"><tr>'
f'<td style="background:rgba(255,255,255,0.09);border:1px solid rgba(255,255,255,0.15);border-radius:6px;padding:8px 6px;text-align:center;">'
f'<div style="font-family:Arial,sans-serif;font-size:12px;font-weight:600;color:#ffffff;">{n}</div>'
f'<div style="font-family:Arial,sans-serif;font-size:10px;color:#fca5a5;margin-top:2px;">{t}</div>'
'</td></tr></table></td>'
for n, t in data[i:i+4]
)
rows += f"<tr>{cells}</tr>"
return (
'<table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:28px 0;"><tr>'
'<td style="background:#5c0a0a;border-radius:8px;padding:20px 24px;">'
'<p style="margin:0 0 14px;font-family:Arial,sans-serif;font-size:14px;font-weight:700;color:#ffffff;text-align:center;">'
'Join other US voice carriers registered to do business in Canada '
'<img src="https://performancewest.net/images/flags/canada.png" width="22" height="14" alt="Canada" style="display:inline;vertical-align:middle;margin-left:6px;"></p>'
f'<table width="100%" cellpadding="0" cellspacing="0" border="0">{rows}</table>'
'</td></tr></table>'
)
def ftr(note=""):
note_html = f'{note}<br>' if note else ''
return (
'<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr>'
'<td style="background:#f4f5f7;padding:20px 40px;border-top:1px solid #e8ecf0;text-align:center;">'
'<img src="https://performancewest.net/images/logo.png" width="70" alt="Performance West" style="display:block;margin:0 auto 10px;width:70px;height:auto;opacity:0.5;">'
'<p style="margin:0 0 6px;font-family:Arial,sans-serif;font-size:12px;color:#9ca3af;">'
'Performance West Inc. &nbsp;&middot;&nbsp; <a href="https://performancewest.net" style="color:#9ca3af;">performancewest.net</a></p>'
f'<p style="margin:0;font-family:Arial,sans-serif;font-size:11px;color:#b0b7c3;line-height:1.6;">{note_html}'
'<a href="{{ UnsubscribeURL }}" style="color:#b0b7c3;">Unsubscribe</a></p>'
'</td></tr></table>'
)
def bq(t):
return (
'<table width="100%" cellpadding="0" cellspacing="0" border="0" style="margin:20px 0;"><tr>'
'<td style="border-left:4px solid #e63f2a;padding:12px 20px;background:#fdf4f3;'
f'font-family:Arial,sans-serif;font-size:15px;color:#2d3748;line-height:1.7;font-style:italic;">{t}</td></tr></table>'
)
def P(t):
return f'<p style="margin:0 0 16px;font-family:Arial,sans-serif;font-size:15px;color:#2d3748;line-height:1.7;">{t}</p>'
def PS(t):
return f'<p style="margin:0 0 16px;font-family:Arial,sans-serif;font-size:14px;color:#6b7280;line-height:1.7;">{t}</p>'
def H2(t):
return f'<h2 style="margin:24px 0 10px;font-family:Arial,sans-serif;font-size:17px;font-weight:700;color:#1a2744;">{t}</h2>'
def UL(*items):
return (
'<ul style="margin:0 0 16px;padding-left:22px;font-family:Arial,sans-serif;font-size:15px;color:#2d3748;line-height:1.7;">'
+ "".join(f'<li style="margin-bottom:8px;">{i}</li>' for i in items)
+ '</ul>'
)
def assemble(hdr_html, fb_html, body_html, ftr_html):
inner = (
hdr_html + fb_html
+ f'<table width="100%" cellpadding="0" cellspacing="0" border="0"><tr><td style="padding:32px 40px;background:#ffffff;" class="body-pad">{body_html}</td></tr></table>'
+ ftr_html
)
return (
'<!DOCTYPE html><html lang="en"><head><meta charset="UTF-8"><meta name="viewport" content="width=device-width,initial-scale=1"><style>'
'@media only screen and (max-width:600px){.wrap{width:100%!important;border-radius:0!important;}.body-pad{padding:24px 20px!important;}h1{font-size:20px!important;}}'
'body,table,td,p,a{-webkit-text-size-adjust:100%;-ms-text-size-adjust:100%;}table{border-collapse:collapse!important;}img{border:0;outline:none;text-decoration:none;}'
'</style></head><body style="margin:0;padding:0;background:#eef0f3;">'
'<table width="100%" cellpadding="0" cellspacing="0" border="0" style="background:#eef0f3;padding:20px 0;"><tr><td align="center">'
'<table width="620" cellpadding="0" cellspacing="0" border="0" class="wrap" style="width:620px;max-width:620px;background:#ffffff;border-radius:8px;overflow:hidden;box-shadow:0 2px 8px rgba(0,0,0,0.08);">'
f'<tr><td>{inner}</td></tr></table></td></tr></table></body></html>'
)
def create_campaign(name, subject, lists, body_html):
s = requests.Session()
s.auth = AUTH
r = s.post(f"{LISTMONK_URL}/api/campaigns", json={
"name": name, "subject": subject, "lists": lists,
"type": "regular", "content_type": "html",
"body": body_html, "status": "draft",
}, timeout=30)
if not r.ok:
print(f" ERROR {r.status_code}: {r.text[:200]}", file=sys.stderr)
return None
cid = r.json().get('data', {}).get('id', '?')
print(f" [{cid}] {name}")
return cid
# ════════════════════════════════════════════════════════════════════
# LIST 5 — REMOVED CARRIERS (1 email)
# "Your traffic is blocked. Here's the path back online."
# ════════════════════════════════════════════════════════════════════
print("\n=== LIST 5: Removed Carriers ===")
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("We set up Canadian CRTC-registered carrier entities for US operators who need to route traffic under a separate legal jurisdiction. The setup takes 6\u201310 weeks. The FCC has no authority over a Canadian corporation.")
+ H2("How it works.")
+ UL(
"We incorporate a BC corporation \u2014 a completely separate legal entity from your US company",
"We register it with the CRTC as a BITS carrier \u2014 your Canadian international carrier authorization",
"We provision a Canadian DID under your new carrier identity",
"Canada and the US share the <strong>same +1 country code</strong> \u2014 your customers dial the same way",
"No Canadian citizenship or residency required \u2014 we handle everything remotely",
)
+ stats(("6\u201310 wks","Full Canadian entity,<br>live and routing"),("$0","CRTC registration<br>fee for resellers"),("+1","Same country code<br>as the US"))
+ H2("What\u2019s included for $3,899 USD.")
+ UL(
"BC corporation \u2014 separate legal entity",
"CRTC BITS registration",
"Canadian DID provisioned and active",
"Vancouver virtual registered office",
".ca domain + 14 email addresses",
"Full corporate binder, delivered digitally",
"Canadian business banking referral \u2014 remote setup, under 5 minutes",
)
+ cta("Start your Canadian carrier setup \u2192", URL)
+ PS(f"Questions? {CONTACT} to talk through how the setup works for your specific situation.")
+ P("\u2014 Performance West")
)
create_campaign(
"REMOVED 1/1 \u2014 Canadian carrier setup for displaced operators",
"Route your traffic under a Canadian carrier \u2014 outside FCC jurisdiction",
[5],
assemble(
hdr("Canadian Carrier Setup", "Route traffic under a Canadian entity.<br>Outside FCC jurisdiction.", "CRTC-registered carrier \u2014 operational in 6\u201310 weeks"),
flagbar("US entity \u2014 FCC jurisdiction", "Canadian CRTC entity \u2014 separate jurisdiction, clean slate"),
b, ftr(REM_NOTE)
)
)
# ════════════════════════════════════════════════════════════════════
# LIST 6 — ISP / BROADBAND OPERATORS (7 emails)
# These are regional ISPs, fiber co-ops, cable operators, WISPs.
# Core pitch: clean separation — voice goes to Canada, data stays in US.
# ════════════════════════════════════════════════════════════════════
print("\n=== LIST 6: ISP / Broadband Operators ===")
# ISP Email 1 — The clean separation pitch
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("If you're a US carrier offering voice services, <strong>your data business may be sharing compliance risk with your voice business</strong>.")
+ P("One FCC show cause order, one enforcement action event, and the same company name that runs your fiber plant and your subscriber base is also the one listed in the enforcement action.")
+ bq("We separate voice into a Canadian carrier entity so your US data company stays completely clean.")
+ H2("What clean separation looks like.")
+ UL(
"<strong>Your US company</strong> \u2014 focuses entirely on broadband, data services, and your existing subscriber base. Zero FCC carrier compliance obligations.",
"<strong>Your Canadian company</strong> \u2014 holds the voice operation. CRTC-registered, separate legal entity, separate regulatory jurisdiction. FCC has no reach into it.",
"Same +1 country code \u2014 your customers dial the same numbers, nothing changes on their end",
"Canadian DIDs provisioned under your Canadian carrier identity",
"Stripe Canada, CAD invoicing, Canadian business banking \u2014 clean financial separation too",
)
+ stats(("100%","Your US data company<br>insulated from FCC voice risk"),("6\u201310 wks","Full Canadian carrier<br>entity live and routing"),("$0","Annual CRTC<br>registration fee"))
+ H2("Who this is for.")
+ UL(
"Regional fiber providers and WISPs who added voice as a bundled service",
"Cable operators running VoIP over their plant",
"Electric co-ops and rural telcos that offer voice alongside broadband",
"Any ISP that would rather not be holding an FCC carrier registration",
)
+ cta("See what\u2019s included \u2192", URL)
+ PS(f"Questions? {CONTACT} to talk through how the separation would work for your specific setup.")
+ P("\u2014 Performance West")
)
create_campaign(
"ISP 1/7 \u2014 Clean separation / protect your data company",
"Your broadband company shouldn\u2019t be carrying your voice compliance risk",
[6],
assemble(
hdr("Voice \u2192 Canada. Data stays in the US.", "Separate the risk.<br>Keep your broadband business clean.", "Canadian CRTC entity \u2014 voice in a different jurisdiction"),
flagbar("US data company \u2014 no FCC carrier obligations", "Canadian voice company \u2014 separate legal entity"),
b, ftr(RMD_NOTE)
)
)
# ISP Email 2 — The FCC enforcement reality
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("In August 2025, the FCC removed <strong>hundreds of carriers from the FCC regulatory system in a single order</strong> (recent FCC orders). In the same month, a separate order removed another 185.")
+ P("These weren't all bad actors. Many were small providers \u2014 regional ISPs, rural telcos, co-ops \u2014 who missed a recertification deadline or had a technical deficiency in their mitigation plan. Two business days' notice, then industry-wide block.")
+ bq("If your voice service is under your main US company name, a enforcement action event takes down your data business brand along with it.")
+ H2("The enforcement action problem for ISPs.")
+ UL(
"The FCC's enforcement posture has shifted from individual action to enforcement action \u2014 bulk orders affecting hundreds of carriers at once",
"Small providers are disproportionately affected \u2014 they don't have compliance teams monitoring FCC dockets",
"When a US company is removed, every downstream partner \u2014 including your broadband interconnects \u2014 sees the same company name in the enforcement order",
"A Canadian entity is simply not on the FCC's radar \u2014 it's not in their jurisdiction, not in their database, not subject to their orders",
)
+ stats(("100+","FCC enforcement<br>actions per year"),("2 days","Notice before<br>industry-wide block"),("0","FCC enforcement orders<br>ever issued against<br>a CRTC-registered reseller"))
+ P("The Canadian entity doesn't eliminate voice compliance requirements entirely \u2014 you still need to comply with CRTC rules. But CRTC enforcement is slower, more procedural, and has never involved a enforcement action event in the history of the program.")
+ cta("See the full setup \u2192", URL)
+ PS(f"Questions about how CRTC compliance compares to FCC? {CONTACT}.")
+ P("\u2014 Performance West")
)
create_campaign(
"ISP 2/7 \u2014 FCC enforcement action reality",
"hundreds of carriers removed in one FCC order. Here\u2019s how that happens to an ISP.",
[6],
assemble(
hdr("FCC Enforcement Reality", "hundreds of carriers removed<br>in a single order.", "recent FCC orders, August 2025 \u2014 and why ISPs are especially exposed"),
flagbar("US carrier \u2014 subject to FCC enforcement action events", "Canadian carrier \u2014 outside FCC jurisdiction entirely"),
b, ftr(RMD_NOTE)
)
)
# ISP Email 3 — Social proof / who else is registered
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("You\u2019re not the first US voice operator to set up a Canadian carrier entity. Every company in the grid below has gone through the same CRTC registration process and now operates under a separate Canadian carrier identity.")
+ carriers_block()
+ P("These aren\u2019t fringe operators. They\u2019re publicly traded CPaaS platforms, UCaaS vendors, and wholesale voice providers \u2014 the same companies many ISPs buy trunking from. They all chose to establish a Canadian entity.")
+ H2("Why established operators choose this structure.")
+ UL(
"Separate regulatory jurisdiction \u2014 Canadian operations aren't affected by FCC actions against the US entity",
"Canadian DIDs and local number inventory under a Canadian carrier identity",
"Canadian business banking and CAD revenue \u2014 financial separation from the US operation",
"Clean acquisition target \u2014 a Canadian reseller entity sells faster and with fewer regulatory complications than a US Section 214 licensee",
)
+ P("The CRTC registration process is the same regardless of size. There\u2019s no size advantage \u2014 Twilio went through the same filing you would.")
+ cta("Start your Canadian carrier setup \u2192", URL)
+ P("\u2014 Performance West")
)
create_campaign(
"ISP 3/7 \u2014 Social proof / who\u2019s already registered",
"Twilio, Bandwidth, Zoom, and your company \u2014 all on the CRTC registry",
[6],
assemble(
hdr("You\u2019re in Good Company", "Twilio did it. Bandwidth did it.<br>Here\u2019s who else is on the CRTC registry.", "503 US voice operators already registered"),
flagbar("US voice operation \u2014 FCC jurisdiction", "Canadian CRTC entity \u2014 same +1, separate jurisdiction"),
b, ftr(RMD_NOTE)
)
)
# ISP Email 4 — The revenue angle
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("Most ISPs think of the Canadian entity as a compliance move. It\u2019s also a revenue move.")
+ H2("What a Canadian carrier entity opens up.")
+ UL(
"<strong>Canadian subscriber base</strong> \u2014 CCTS membership allows you to take Canadian retail voice customers. Canada has 38 million people, largely underserved by independent providers.",
"<strong>Canadian wholesale termination</strong> \u2014 Canadian-bound traffic is often cheaper to terminate via a Canadian carrier than routing through a US carrier with Canadian interconnects",
"<strong>Canadian DIDs</strong> \u2014 provision local Canadian numbers (604, 416, 613, 514, etc.) and sell them to US businesses wanting a Canadian presence",
"<strong>CAD revenue</strong> \u2014 invoice Canadian customers in CAD, receive payment into a Canadian bank account, simplify cross-border accounting",
"<strong>Stripe Canada</strong> \u2014 a Canadian Stripe account has access to different payment methods and lower interchange rates for Canadian cardholders",
)
+ stats(("38M","Canadian population \u2014<br>underserved by<br>independent ISPs"),("$349 CAD","Annual CRTC<br>maintenance cost"),("~0%","CRTC licence<br>fee for resellers"))
+ P("The Canadian market for independent voice providers is less saturated than the US. The major carriers (Rogers, Bell, TELUS) dominate retail, but the wholesale and reseller market is open.")
+ cta("See what\u2019s included in the setup \u2192", URL)
+ PS(f"Want to talk through the Canadian revenue opportunity? {CONTACT}.")
+ P("\u2014 Performance West")
)
create_campaign(
"ISP 4/7 \u2014 Canadian revenue opportunity",
"The Canadian carrier setup isn\u2019t just compliance \u2014 it\u2019s a new revenue stream",
[6],
assemble(
hdr("The Revenue Angle", "38 million Canadians.<br>Underserved by independent providers.", "What a Canadian carrier identity opens up for your business"),
flagbar("US-only voice operation", "Canadian carrier entity \u2014 new market access"),
b, ftr(RMD_NOTE)
)
)
# ISP Email 5 — M&A / exit angle
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("If you\u2019re building your ISP with an exit in mind, the structure you choose today affects what your company looks like to a buyer in 5 years.")
+ bq("A US broadband company with no FCC carrier obligations is a simpler acquisition than one that comes bundled with Section 214 licensing, FCC regulatory compliance history, and potential enforcement exposure.")
+ H2("How the structure affects your exit.")
+ UL(
"<strong>Clean US data company</strong> \u2014 buyers of broadband infrastructure don\u2019t want to inherit FCC carrier compliance. A clean separation means your data asset has no regulatory tail.",
"<strong>Canadian voice entity</strong> \u2014 CRTC-registered resellers can be acquired without an Investment Canada national security review. No Team Telecom equivalent. No CFIUS filing.",
"<strong>Faster Canadian M&A</strong> \u2014 CRTC reseller acquisitions typically close in 30\u201390 days. The Rogers-Shaw deal took 18 months, but that was a C$26B facilities-based deal. Reseller acquisitions are administrative.",
"<strong>No post-close revocation risk</strong> \u2014 unlike US Section 214 licences (see: China Telecom Americas, revoked 20 years after grant), CRTC reseller registrations don\u2019t carry retroactive revocation risk for compliant operators.",
)
+ H2("Recent Canadian telecom M&A that closed quickly.")
+ UL(
"Bell acquires Distributel (incl. ThinkTel) \u2014 C$20M+ deal, administrative CRTC notification, no public hearing",
"Rogers acquires Comwave \u2014 standard CRTC reseller transfer notification",
"Eastlink acquires NeoTech \u2014 regional ISP tuck-in, under 60 days",
)
+ cta("See the full setup \u2192", URL)
+ P("\u2014 Performance West")
)
create_campaign(
"ISP 5/7 \u2014 M&A / exit angle",
"A clean US data company sells better than one carrying FCC carrier history",
[6],
assemble(
hdr("Building to Sell?", "A clean US data company<br>is a simpler acquisition.", "How the Canadian structure affects your exit"),
flagbar("US company with FCC carrier obligations \u2014 regulatory tail", "Clean US data company + separate Canadian voice entity"),
b, ftr(RMD_NOTE)
)
)
# ISP Email 6 — Process walkthrough
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("The most common question we get: <em>how much work is this for me?</em>")
+ P("Honest answer: almost none. Here\u2019s exactly what the 6\u201310 week process looks like.")
+ H2("What we handle.")
+ UL(
"<strong>Week 1\u20132:</strong> BC name reservation and corporation incorporation. We file, you review and eSign the articles.",
"<strong>Week 2\u20133:</strong> CRTC BITS notification filed. We prepare and submit all documentation.",
"<strong>Week 3\u20134:</strong> Canadian DID provisioned under your new carrier identity. Routing configured to forward or SIP trunk to your existing switch.",
"<strong>Week 4\u20135:</strong> Vancouver virtual registered office and .ca domain registered under your BC corporation number (required for CIRA).",
"<strong>Week 5\u20136:</strong> HestiaCP email hosting provisioned \u2014 up to 14 email addresses under your .ca domain.",
"<strong>Week 6\u201310:</strong> CRTC BITS registration confirmed. Corporate binder compiled and delivered.",
)
+ H2("What you do.")
+ UL(
"Review and eSign the BC articles of incorporation (DocuSign-style, takes 5 minutes)",
"Choose your .ca domain name via our client portal",
"Open your Canadian business bank account (remote, under 5 minutes)",
"That\u2019s it.",
)
+ stats(("6\u201310 wks","Total timeline"),("~30 min","Your time investment"),("$3,899","All-in USD price"))
+ cta("Start your Canadian carrier setup \u2192", URL)
+ PS(f"Questions about the process? {CONTACT}.")
+ P("\u2014 Performance West")
)
create_campaign(
"ISP 6/7 \u2014 Process walkthrough",
"What 6 weeks of Canadian carrier setup actually looks like",
[6],
assemble(
hdr("How It Works", "6\u201310 weeks.<br>About 30 minutes of your time.", "A complete walkthrough of the setup process"),
flagbar("Your existing US voice operation", "New Canadian carrier entity \u2014 running in parallel"),
b, ftr(RMD_NOTE)
)
)
# ISP Email 7 — FCC enforcement / final close (the enforcement angle last)
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("This is the last email in this sequence. I want to be direct about why I\u2019m reaching out.")
+ P("US carriers offering voice services are subject to FCC enforcement. Over the past 18 months, the FCC has removed thousands of carriers \u2014 including small regional providers \u2014 through enforcement action orders with two business days\u2019 notice.")
+ bq("The question isn\u2019t whether the FCC\u2019s enforcement posture is fair to small ISPs. The question is whether you want your broadband business exposed to it.")
+ H2("The simple version.")
+ UL(
"Move voice to a Canadian entity",
"Your US data company has zero FCC carrier compliance obligations",
"Your Canadian voice company operates under CRTC rules \u2014 a different regulator, different enforcement history, different risk profile",
"Same +1 country code, same phone numbers, no change for your subscribers",
)
+ P("We\u2019ve set this up for carriers across the US. The process takes 6\u201310 weeks. The all-in price is $3,899 USD. There\u2019s no ongoing licence fee from the CRTC.")
+ cta("Start your Canadian carrier setup \u2192", URL)
+ PS("If you\u2019re not ready right now but this is something you\u2019re thinking about, reply and I\u2019ll put a note in the file. No follow-up pressure. I\u2019d rather you reach out when it\u2019s the right time than rush a decision.")
+ P("\u2014 Justin Hannah, Performance West")
)
create_campaign(
"ISP 7/7 \u2014 FCC enforcement / final close",
"Last email: the direct case for separating your voice and data companies",
[6],
assemble(
hdr("Final Note", "The direct case for<br>separating voice from data.", "Why ISPs shouldn\u2019t carry FCC carrier risk in their main company"),
flagbar("US company \u2014 voice + data bundled, FCC risk shared", "US data company (clean) + Canadian voice entity"),
b, ftr(RMD_NOTE)
)
)
# ════════════════════════════════════════════════════════════════════
# LIST 3 — GENERAL CARRIERS (6 new emails: 2-7, resequenced)
# Email 1 (FCC enforcement) already exists — these follow it
# New sequence: revenue, social proof, M&A, objection handling,
# process walkthrough, final close
# ════════════════════════════════════════════════════════════════════
print("\n=== LIST 3: General Carriers (emails 2-7) ===")
# General Email 2 — Revenue / Canadian market opportunity
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("Most people think of the Canadian carrier setup as a compliance hedge. It\u2019s also a straight revenue play.")
+ H2("What a Canadian CRTC registration opens up.")
+ UL(
"<strong>Canadian DID inventory</strong> \u2014 provision local Canadian numbers (604 Vancouver, 416 Toronto, 514 Montreal, etc.) and sell them to businesses that want a Canadian presence",
"<strong>Canadian retail voice</strong> \u2014 CCTS membership allows you to take Canadian retail customers under your Canadian brand",
"<strong>Canadian wholesale termination</strong> \u2014 Canadian-bound traffic can be cheaper to terminate directly via Canadian interconnects under a Canadian carrier identity",
"<strong>CAD revenue and Canadian banking</strong> \u2014 invoice Canadian customers in CAD, keep it in a separate Canadian account, simplify cross-border accounting",
"<strong>Stripe Canada</strong> \u2014 access to Canadian payment methods, lower interchange on Canadian cards",
)
+ stats(("38M","Canadian population"),("$349 CAD/yr","Annual CRTC<br>maintenance fee"),("~30 min","Time to open a<br>Canadian bank account"))
+ P("Canada\u2019s independent voice market is less saturated than the US. Rogers, Bell, and TELUS dominate, but the wholesale and reseller market is open. Your Canadian carrier identity is your entry point.")
+ cta("See the full setup \u2192", URL)
+ PS(f"Want to discuss the Canadian revenue opportunity? {CONTACT}.")
+ P("\u2014 Performance West")
)
create_campaign(
"CRTC 2/7 \u2014 Canadian revenue opportunity",
"The Canadian carrier setup isn\u2019t just a backup \u2014 it\u2019s a new market",
[3],
assemble(
hdr("The Revenue Angle", "38 million Canadians.<br>One registration to reach them.", "What a Canadian carrier identity opens up"),
flagbar("US-only carrier operation", "Canadian carrier entity \u2014 new market, new revenue"),
b, ftr(RMD_NOTE)
)
)
# General Email 3 — Social proof
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("Every company in the grid below has gone through the same CRTC BITS registration process. They now operate as registered Canadian international carriers.")
+ carriers_block()
+ P("These are publicly traded US companies \u2014 CPaaS platforms, UCaaS vendors, wholesale carriers. They all chose to establish a Canadian carrier entity. The registration process is identical regardless of size: there\u2019s no size advantage, no fast track for large companies.")
+ H2("What they all have in common.")
+ UL(
"A Canadian corporation incorporated in BC or Ontario",
"A CRTC BITS (Basic International Telecommunications Services) registration",
"A Canadian DID under their Canadian carrier identity",
"Operations that run independently of their US regulatory status",
)
+ P("Your setup would look exactly the same. The CRTC doesn\u2019t differentiate between a two-person carrier and Twilio.")
+ cta("Start your Canadian carrier setup \u2192", URL)
+ P("\u2014 Performance West")
)
create_campaign(
"CRTC 3/7 \u2014 Social proof / who\u2019s already registered",
"Twilio, Bandwidth, RingCentral, Zoom \u2014 all on the CRTC registry",
[3],
assemble(
hdr("You\u2019re in Good Company", "These US carriers are already<br>on the CRTC registry.", "The same process, regardless of size"),
flagbar("US carrier operation", "Canadian CRTC entity \u2014 same process for everyone"),
b, ftr(RMD_NOTE)
)
)
# General Email 4 — M&A / exit
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("If you\u2019re building your carrier operation with an exit in mind, where you hold your carrier licences affects what you look like to a buyer.")
+ bq("A Canadian CRTC-registered reseller is a cleaner acquisition target than a US Section 214 licensee. No Team Telecom. No CFIUS. No post-close revocation risk.")
+ H2("Why Canadian carrier M&A closes faster.")
+ UL(
"<strong>No national security review</strong> \u2014 Canada\u2019s Investment Canada Act national security review applies to infrastructure owners, not registered resellers. Foreign buyers face no mandatory filing.",
"<strong>No Team Telecom</strong> \u2014 the US DOJ/FBI/DHS process that can block or delay acquisitions indefinitely doesn\u2019t apply to Canadian entities",
"<strong>No retroactive revocation</strong> \u2014 the FCC revoked China Telecom\u2019s Section 214 authorization in 2021, 20 years after it was granted. CRTC reseller registrations don\u2019t carry that risk.",
"<strong>Administrative transfer process</strong> \u2014 CRTC reseller acquisitions require a notification, not a full public hearing. Deals close on commercial timelines.",
)
+ H2("Recent Canadian telecom deals that closed cleanly.")
+ UL(
"Bell acquires Distributel (incl. ThinkTel) \u2014 staggered payments 2022\u20132023, standard CRTC notification",
"Rogers acquires Comwave \u2014 standard reseller transfer, no hearing",
"Eastlink acquires NeoTech \u2014 under 60 days, no public process",
)
+ cta("See what\u2019s included in the setup \u2192", URL)
+ P("\u2014 Performance West")
)
create_campaign(
"CRTC 4/7 \u2014 M&A / exit angle",
"Why a Canadian carrier entity is a cleaner exit than a US Section 214 licence",
[3],
assemble(
hdr("Building to Sell?", "Canadian carrier M&A closes faster<br>than US Section 214 transfers.", "No Team Telecom. No CFIUS. No retroactive revocation."),
flagbar("US Section 214 licensee \u2014 CFIUS, Team Telecom, revocation risk", "Canadian CRTC reseller \u2014 administrative transfer, clean exit"),
b, ftr(RMD_NOTE)
)
)
# General Email 5 — Objection handling
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("We hear a few consistent objections to the Canadian carrier setup. Here\u2019s the honest answer to each.")
+ H2("\u201cWe\u2019re already FCC compliant. We don\u2019t need a backup.\u201d")
+ P("Compliance isn\u2019t the same as protection. The FCC\u2019s enforcement action orders have caught compliant carriers \u2014 providers who had filed mitigation plans, passed their certifications, and were removed anyway because of a deficiency the FCC identified after the fact. recent FCC orders removed hundreds of carriers in a single order. Being compliant doesn\u2019t mean you\u2019re immune to a bulk enforcement action.")
+ H2("\u201cWe don\u2019t have Canadian customers.\u201d")
+ P("You don\u2019t need Canadian customers to benefit from a Canadian carrier identity. The value is the separate regulatory jurisdiction, the clean legal entity, and the operational independence \u2014 not the Canadian subscriber base. Canadian customers are an opportunity, not a requirement.")
+ H2("\u201cThis is too much overhead.\u201d")
+ P("The setup takes 6\u201310 weeks. After that, annual maintenance is $349 CAD \u2014 an annual report filing, a CRTC notification update, and a registered office renewal. It\u2019s about 2 hours of work per year if you do it yourself, or we can handle it for you.")
+ H2("\u201cWe\u2019d rather fix the FCC problem directly.\u201d")
+ P("Do both. The Canadian entity doesn\u2019t prevent you from maintaining your FCC registration. It means your US FCC status is no longer the only thing standing between your operation and a full traffic blackout.")
+ cta("See the full setup \u2192", URL)
+ P("\u2014 Performance West")
)
create_campaign(
"CRTC 5/7 \u2014 Objection handling",
"You don\u2019t need this. Until you do. (Answering the common objections)",
[3],
assemble(
hdr("The Objections", "We\u2019re compliant. We don\u2019t have<br>Canadian customers. Too much overhead.", "Honest answers to the most common pushback"),
flagbar("Single US entity \u2014 single point of failure", "US entity + Canadian entity \u2014 operational redundancy"),
b, ftr(RMD_NOTE)
)
)
# General Email 6 — Process walkthrough
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("The most common question we hear: <em>how much work is this for me?</em>")
+ P("Almost none. Here\u2019s the complete timeline.")
+ H2("The 6\u201310 week process.")
+ UL(
"<strong>Week 1\u20132:</strong> BC name reservation and corporation incorporation. We file, you eSign the articles.",
"<strong>Week 2\u20133:</strong> CRTC BITS notification filed and acknowledged.",
"<strong>Week 3\u20134:</strong> Canadian DID provisioned. Configured to forward to your existing US numbers or terminate on your SIP trunk.",
"<strong>Week 4\u20135:</strong> Vancouver virtual registered office and .ca domain registered under your BC corporation.",
"<strong>Week 5\u20136:</strong> Email hosting provisioned \u2014 up to 14 addresses at your .ca domain.",
"<strong>Week 6\u201310:</strong> CRTC BITS registration confirmed. Corporate binder compiled and delivered. Canadian banking referral sent.",
)
+ H2("Your time investment: about 30 minutes total.")
+ UL(
"eSign the BC incorporation articles (5 minutes)",
"Choose your .ca domain via our client portal (5 minutes)",
"Open your Canadian business bank account (under 5 minutes, fully remote)",
"Review and receive your corporate binder",
)
+ stats(("6\u201310 wks","Complete timeline"),("~30 min","Your time required"),("$3,899 USD","All-in price"))
+ cta("Start your Canadian carrier setup \u2192", URL)
+ P("\u2014 Performance West")
)
create_campaign(
"CRTC 6/7 \u2014 Process walkthrough",
"What 6\u201310 weeks of Canadian carrier setup actually looks like",
[3],
assemble(
hdr("How It Works", "6\u201310 weeks.<br>About 30 minutes of your time.", "A complete walkthrough of the setup process"),
flagbar("Your existing US carrier operation", "New Canadian carrier entity \u2014 running in parallel"),
b, ftr(RMD_NOTE)
)
)
# General Email 7 — Final close (direct, personal)
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("Last email in this sequence.")
+ P("I want to be direct. The FCC\u2019s enforcement posture over the last 18 months has been aggressive \u2014 enforcement action orders, shortened cure periods, and a consistent pattern of removing carriers that fall behind on certifications.")
+ P("A Canadian CRTC-registered carrier entity puts your voice operation in a separate regulatory jurisdiction. The FCC can\u2019t touch it. It\u2019s not in their database. It\u2019s not subject to their orders.")
+ bq("Your Canadian entity is your operational insurance. Same +1 country code. Same phone numbers. No change for your customers. No FCC jurisdiction.")
+ P("The setup is $3,899 USD. It takes 6\u201310 weeks. We handle everything. You sign a few documents.")
+ P("If this is the right time, click below. If it\u2019s not, reply and tell me when would be a better time to follow up \u2014 or tell me it\u2019s not something you\u2019re interested in and I\u2019ll take you off the list.")
+ cta("Start your Canadian carrier setup \u2192", URL)
+ P("\u2014 Justin Hannah, Performance West")
)
create_campaign(
"CRTC 7/7 \u2014 Final close",
"Last email: your Canadian carrier insurance policy",
[3],
assemble(
hdr("Final Note", "Your operational insurance.<br>Same numbers. No FCC jurisdiction.", "The direct close"),
flagbar("Single US entity \u2014 full FCC exposure", "US entity + Canadian CRTC entity \u2014 operational redundancy"),
b, ftr(RMD_NOTE)
)
)
# ════════════════════════════════════════════════════════════════════
# LIST 4 — OUTSIDE COUNSEL (5 emails)
# These are lawyers / compliance contacts at large firms.
# Tone: peer-to-peer, professional, liability-focused.
# ════════════════════════════════════════════════════════════════════
print("\n=== LIST 4: Outside Counsel (5 emails) ===")
# Counsel Email 1 — The liability framing
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("If your client operates as a registered US carrier, they\u2019re exposed to the FCC\u2019s current enforcement posture.")
+ P("In 2025, the FCC removed over 1,400 carriers through enforcement action orders. The notice period was two business days. The effect was immediate: industry-wide traffic block, with no grace period for remediation.")
+ bq("If your client\u2019s voice operation goes dark, the liability question is whether they had reasonable structural protection available and chose not to implement it.")
+ H2("What \u2018reasonable structural protection\u2019 looks like.")
+ P("A Canadian CRTC-registered carrier entity provides operational continuity independent of the client\u2019s FCC registration status. It\u2019s a separate legal entity, incorporated in British Columbia, registered with Canada\u2019s telecom regulator, and operating under a completely separate regulatory framework.")
+ UL(
"FCC enforcement actions do not extend to Canadian corporations",
"Canada and the US share the +1 country code \u2014 customers are not affected by a transition to Canadian routing",
"The entity can be established in 6\u201310 weeks, before any enforcement event occurs",
"Cost: $3,899 USD setup, $349 CAD/year maintenance",
)
+ P("We work directly with carriers and their counsel. We can provide a full description of the structure, the regulatory basis for the separation, and the ongoing compliance requirements under CRTC rules.")
+ cta("See the full structure \u2192", URL)
+ PS(f"Want a detailed writeup for client review, or to discuss whether this structure fits your client\u2019s situation? {CONTACT}.")
+ P("\u2014 Performance West")
)
create_campaign(
"COUNSEL 1/5 \u2014 Liability framing / client protection",
"Your client has FCC carrier exposure. Here\u2019s the structural fix.",
[4],
assemble(
hdr("For Telecom Counsel", "Your client has FCC carrier exposure.<br>Here\u2019s the structural protection.", "Canadian CRTC entity \u2014 separate jurisdiction, operational continuity"),
flagbar("Client\u2019s US carrier \u2014 FCC enforcement exposure", "Canadian entity \u2014 separate legal entity, separate jurisdiction"),
b, ftr(COUN_NOTE)
)
)
# Counsel Email 2 — Regulatory comparison (FCC vs CRTC)
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("A brief comparison of the FCC and CRTC enforcement environments, for counsel advising on carrier structure.")
+ H2("FCC \u2014 enforcement posture (current).")
+ UL(
"FCC enforcement actions have increased significantly, affecting hundreds of carriers through shortened compliance windows.",
"Show cause process: carriers receive a deficiency notice, typically 30 days to cure, but recent orders have shortened this significantly",
"Post-cure verification: the FCC has revoked certifications after initial approval where subsequent review found deficiencies",
"Team Telecom: DOJ/FBI/DHS national security review can delay or block acquisitions of Section 214 licensees, with no statutory deadline",
"Retroactive revocation: China Telecom Americas\u2019 Section 214 authorization was revoked in 2021, 20 years after it was granted",
)
+ H2("CRTC \u2014 enforcement posture.")
+ UL(
"No enforcement action mechanism exists for BITS-registered resellers",
"Enforcement actions are procedural and adjudicative \u2014 the CRTC does not block traffic; it issues show cause orders with response periods",
"No national security review for reseller acquisitions under the Investment Canada Act",
"No retroactive revocation of BITS registrations has occurred in the history of the program",
"Annual maintenance: file an updated ownership notification, pay the annual registered office fee. No certification equivalent to the FCC compliance process.",
)
+ P("The structural risk profile of a CRTC-registered reseller is materially different from a US Section 214 licensee. For clients with voice operations, the question of which jurisdiction holds the carrier registration has practical consequences for business continuity and transaction structure.")
+ cta("See the full carrier setup \u2192", URL)
+ PS("Reply if you\u2019d like a written comparison of the two regulatory frameworks suitable for a client memo.")
+ P("\u2014 Performance West")
)
create_campaign(
"COUNSEL 2/5 \u2014 FCC vs CRTC regulatory comparison",
"FCC vs. CRTC: a regulatory comparison for carrier counsel",
[4],
assemble(
hdr("Regulatory Comparison", "FCC vs. CRTC enforcement.<br>Not the same risk profile.", "A brief comparison for telecom counsel"),
flagbar("FCC jurisdiction \u2014 enforcement action, no-deadline national security review", "CRTC jurisdiction \u2014 procedural enforcement, no enforcement action"),
b, ftr(COUN_NOTE)
)
)
# Counsel Email 3 — Transaction structure / M&A angle for lawyers
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("For counsel advising on telecom M&A, the jurisdiction of the carrier registration has material consequences for transaction structure, timeline, and regulatory approval risk.")
+ H2("US Section 214 licensee \u2014 transaction considerations.")
+ UL(
"<strong>FCC transfer of control</strong> \u2014 Section 214 transfers require FCC approval. Review timelines vary from 30 days to 18+ months depending on whether Team Telecom is engaged.",
"<strong>Team Telecom</strong> \u2014 DOJ/FBI/DHS national security review applies to any transfer involving foreign ownership. No statutory deadline. Can result in NSSA (Network Security Agreement) requirements, divestitures, or outright blocks.",
"<strong>CFIUS</strong> \u2014 mandatory filing for telecom transactions involving foreign buyers. Review timelines are statutory but mitigation negotiations can extend the effective timeline significantly.",
"<strong>Retroactive exposure</strong> \u2014 FCC can revisit Section 214 authorizations post-close if national security concerns emerge.",
)
+ H2("Canadian CRTC reseller \u2014 transaction considerations.")
+ UL(
"<strong>CRTC transfer notification</strong> \u2014 reseller ownership changes require a notification to the CRTC, not an application for approval. Administrative process, no hearing.",
"<strong>No Investment Canada national security review</strong> \u2014 for resellers (non-facilities-based), the national security provisions of the Investment Canada Act do not apply.",
"<strong>No CFIUS filing</strong> \u2014 the CFIUS mandatory filing requirement is a US-law concept and does not apply to acquisitions of Canadian corporations.",
"<strong>Timeline</strong> \u2014 reseller transactions have closed in 30\u201390 days. Bell\u2019s acquisition of Distributel and Rogers\u2019 acquisition of Comwave both used standard CRTC notification.",
)
+ P("For clients considering a transaction \u2014 either as acquirer or target \u2014 the question of whether the carrier registration is held in a US or Canadian entity has direct consequences for approval timeline, regulatory risk, and deal certainty.")
+ cta("See the Canadian carrier structure \u2192", URL)
+ P("\u2014 Performance West")
)
create_campaign(
"COUNSEL 3/5 \u2014 M&A transaction structure",
"Section 214 vs. CRTC reseller: transaction structure implications for counsel",
[4],
assemble(
hdr("M&A Transaction Structure", "Section 214 transfer vs.<br>CRTC reseller notification.", "Transaction timeline and regulatory risk implications"),
flagbar("US Section 214 \u2014 FCC approval, Team Telecom, CFIUS", "Canadian CRTC reseller \u2014 notification only, no national security review"),
b, ftr(COUN_NOTE)
)
)
# Counsel Email 4 — The setup process (for counsel to present to client)
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("For counsel who want to present this to a client, here is a brief description of the setup process and ongoing compliance obligations.")
+ H2("Setup process (6\u201310 weeks).")
+ UL(
"<strong>BC corporation incorporation</strong> \u2014 separate legal entity from the US parent. Name reservation, articles of incorporation, registered office. We handle the filing; client reviews and executes the articles.",
"<strong>CRTC BITS notification</strong> \u2014 Basic International Telecommunications Services registration. We prepare and submit the notification. No application fee.",
"<strong>Canadian DID provisioning</strong> \u2014 a Canadian phone number provisioned under the new carrier identity. Configured per client instructions.",
"<strong>Virtual registered office</strong> \u2014 Vancouver BC address used as the corporation\u2019s registered office (required for BC incorporation and CIRA .ca domain registration).",
"<strong>.ca domain and email</strong> \u2014 domain registered under the BC corporation number (CIRA requirement), up to 14 email addresses provisioned.",
"<strong>Corporate binder</strong> \u2014 full documentation package delivered digitally.",
)
+ H2("Ongoing compliance obligations (annual).")
+ UL(
"<strong>BC Annual Report</strong> \u2014 filed annually with BC Registry, confirms registered office and director information. We can file on client\u2019s behalf.",
"<strong>CRTC ownership update</strong> \u2014 if ownership structure changes, a notification is filed with the CRTC. No fee.",
"<strong>Registered office renewal</strong> \u2014 annual fee for the Vancouver virtual registered office address.",
"<strong>Annual maintenance cost</strong> \u2014 $349 CAD/year all-in for BC Annual Report, registered office, and CRTC notification update.",
)
+ P("The structure creates no Canadian tax obligations for a US-owned corporation that does not have Canadian-sourced income. Counsel should confirm with Canadian tax advisors for the client\u2019s specific situation.")
+ cta("See the full setup details \u2192", URL)
+ PS("Reply if you\u2019d like a detailed term sheet or structure memo suitable for client review.")
+ P("\u2014 Performance West")
)
create_campaign(
"COUNSEL 4/5 \u2014 Setup and compliance overview for client review",
"Canadian CRTC carrier structure: setup process and annual obligations",
[4],
assemble(
hdr("For Client Review", "Setup process and ongoing<br>compliance obligations.", "A brief description suitable for client presentation"),
flagbar("Client\u2019s US carrier operation", "New Canadian CRTC-registered entity"),
b, ftr(COUN_NOTE)
)
)
# Counsel Email 5 — Final / referral ask
b = (
P("Hi {{ .Subscriber.FirstName }},")
+ P("Last email in this sequence.")
+ P("We work with a number of telecom counsel who refer clients to us when the Canadian carrier structure is appropriate. The arrangement is straightforward: you identify the client need, we handle the setup, and if you\u2019d like a referral arrangement we can discuss that separately.")
+ H2("What we provide to counsel.")
+ UL(
"A written description of the structure suitable for inclusion in a client advice letter",
"A regulatory comparison memo (FCC vs. CRTC) on request",
"Direct coordination with the client for all setup steps \u2014 you don\u2019t need to be in the middle of the process",
"Status updates throughout the 6\u201310 week setup timeline",
"A completed corporate binder for your file at closing",
)
+ H2("Referral structure.")
+ P("We pay a flat referral fee of $300 USD per completed CRTC carrier setup, paid 14 days after the corporate binder is delivered to the client. No ongoing obligation, no volume requirement. If a client you refer doesn\u2019t complete the setup, no fee is owed.")
+ P("If this is something your firm handles directly rather than referring out, we\u2019re happy to work as a vendor to your process instead.")
+ cta("See the full setup details \u2192", URL)
+ PS(f"Want to discuss a referral arrangement or request the regulatory comparison memo? {CONTACT}.")
+ P("\u2014 Justin Hannah, Performance West")
)
create_campaign(
"COUNSEL 5/5 \u2014 Referral arrangement",
"Working with telecom counsel: referral arrangement and support materials",
[4],
assemble(
hdr("For Telecom Counsel", "Referral arrangement.<br>$300 per completed setup.", "What we provide and how the referral structure works"),
flagbar("Client\u2019s current US carrier exposure", "Canadian CRTC entity \u2014 structural protection"),
b, ftr(COUN_NOTE)
)
)
print("\nAll campaigns created.")