Canada's anti-spam law puts real rules on outbound email. A prompt can ask a model to follow them; only code can make sure it does. Here is how our own lead engine is built around that difference.
Outbound email in Canada has a regulator attached. Canada's Anti-Spam Legislation — CASL — expects a commercial message to rest on consent, to identify who sent it, to include a way to reach the sender, and to carry an unsubscribe mechanism that works. None of that is exotic. What makes it hard is that modern outreach is increasingly written by a language model, and a model is precisely the component that cannot be trusted to remember a rule every time.
Growth Engine is the lead engine we built for our own companies. It is built and not yet launched, and it was designed around one idea: the model writes the email, and code decides whether the email is allowed to exist. This is how it works, and it is not legal advice — the specifics of consent are a conversation for your lawyer, not your developer.
Only addresses the business published
Consent is where most outbound tools cut the corner. Growth Engine only contacts an address that the business published on its own website, and it keeps the source URL as evidence of where the address came from. An address that was guessed — the familiar first-name-at-domain pattern — is not a published address, so it fails closed: the lead is dropped rather than contacted on a hunch. An address that has asked not to be contacted is suppressed, and a suppressed address fails closed the same way.
"Fails closed" is the important phrase. When the evidence is missing or unclear, the system does not send. The cost of that choice is some leads never contacted. The cost of the opposite choice is a message the business had no right to send.
The footer is appended, not generated
Every message needs the sender's mailing address and an unsubscribe line. Asking a model to include them works most of the time, which is another way of saying it fails some of the time. Growth Engine does not ask. The unsubscribe footer and the mailing address are appended deterministically after the model has finished writing, so the part of the email the law cares most about is the part the model never touches.
The same pattern handles tone. A banned-phrase check runs after the model has written the draft — not instead of it, and not as an instruction inside the prompt. If the draft promises something it should not, the check catches it before anyone sees it.
Qualification without a model
Before any of that, the engine decides who is worth contacting, and that decision uses no model at all. It sweeps Ontario niches through Google Places on a weekly rotation, taking only open businesses that have a website, into an intake webhook that validates, deduplicates and assigns a lead ID before anything downstream sees the record. Qualification is a nought-to-hundred score from rating, review volume and business type, routed to one of five service lines. No model, no network call, same answer every time.
That matters for compliance as much as for sales. When a regulator, or a prospect, asks why a business was contacted, the answer is a score you can replay, not a judgement a model made once and cannot repeat.
A person on the send button
The model's job is narrow: each prospect's homepage is fetched, capped and stripped, then scored on six dimensions — first impression, mobile, search, call to action, trust and booking flow — and turned into three issues, three recommendations and one hook for the draft. Then the draft stops. Every one waits for an approval tap, in chat or in an admin queue, before the mail worker touches it.
That gate sits exactly where our own guide says a gate belongs: at the last reversible moment, immediately before the first step a stranger can see. Once an email is sent, it cannot be unsent.
What to take from it
If your outreach is written by a model, the useful question is not "did we tell the model the rules?" It is "which of the rules would still hold if the model ignored them?" Consent evidence, suppression, the footer and the final approval should all hold. A model's output is a draft; the compliance is the code around it.
The same principle runs through everything else we build with models — more in the guide to putting AI agents into a real process, and in which steps should use AI at all.