Compliance & DNC engine
TCPA, GDPR, DMARC, LinkedIn caps, WhatsApp opt-in — all enforced before send.
The compliance engine is a single chokepoint every channel worker calls before it sends anything: DNC list, quiet hours, daily and hourly caps, opt-out keyword detection and consent tracking. Because it is one gate rather than one per channel, a STOP received on SMS opts that recipient out everywhere at once.
- ·Cross-channel DNC with wildcard '*' support
- ·Quiet hours in the operator's timezone, not yours
- ·STOP / UNSUBSCRIBE auto-opt-out on every inbound
- ·LinkedIn weekly invite cap enforced per account
- ·WhatsApp template approval gating
The detail.
One gate, every channel
Before any worker dispatches a touch, evaluate_send() checks the account status, the account's quiet hours, the DNC list (specific channel + the wildcard '*'), the per-account min-gap, the hourly cap, and the daily cap. Skip the gate? You can't — the dispatcher won't run a worker that doesn't call it.
Auto opt-out, not opt-out-when-someone-remembers
Every inbound message runs through detect_opt_out() with the channel-specific keyword set (STOP, STOPALL, UNSUBSCRIBE for SMS / WhatsApp; phrase matching for email). A match writes a DNC row immediately. The next outbound to that recipient, on any channel, is blocked.
Audit trail, not a black box
Every block logs the reason (dnc_listed, quiet_hours, hourly_limit, …) and the suggested retry-after window. When an operator asks 'why didn't this go?' the answer is one click into the touch detail.
vs. point-tool DNC managers / spreadsheets
The honest comparison — what changes when you switch.
Four things you won’t find elsewhere.
One gate, every worker
evaluate_send() is the single chokepoint. Email worker, call dispatcher, LinkedIn worker, SMS sender, WhatsApp dispatcher — they all call the same function. Skipping the gate is impossible by design.
Wildcard '*' DNC
A DNC entry with channel='*' opts the lead out of every channel simultaneously. STOP on SMS protects email, calls, LinkedIn, and WhatsApp at the same time.
Recipient-timezone quiet hours
We compute quiet hours from the lead's country code (E.164) or stored timezone — not the operator's office hours. A 9 AM call in Berlin doesn't fire at 4 AM in New Delhi.
Reason codes, not 'rejected'
Every block returns dnc_listed · quiet_hours · hourly_limit · daily_limit · channel_paused · template_unapproved with a retry-after hint, so the operator knows what to fix.
How a team would use this.
TCPA officer audits a 6-month outbound run
Filter /call/cdr by outcome=blocked across the 6-month window. Each row shows the lead, the channel, the block reason, the operator who triggered the dial, and any force-flag overrides. The export goes to the auditor as a CSV; zero gaps, zero spreadsheet reconciliation.
STOP on WhatsApp protects every channel instantly
A lead replies STOP to a Day-3 WhatsApp template. The classifier writes a DNC row with channel='*' before the operator triages the inbox. The Day-5 SMS, Day-7 call, and Day-10 LinkedIn DM scheduled for that lead all skip with reason=dnc_listed. The audit log records it for the compliance review.
DLT-required India SMS attempt with no registration
An operator builds an SMS step targeting Indian numbers but the workspace has no DLT entity registered. evaluate_send() returns reason=dlt_not_registered with a one-click link to /settings/compliance/dlt. The send never hits the carrier API, so there's no carrier-side rejection log to clean up later.
The full story.
Compliance is the most expensive thing to retrofit into an outbound stack. TCPA fines run $500-$1,500 per violating call; GDPR penalties scale to 4% of global revenue; LinkedIn account suspensions take weeks to recover. The economics make it cheaper to enforce compliance at the dispatcher gate, before any carrier API is called, than to clean up after the fact. Autocloz's evaluate_send() function is that gate — every worker on every channel calls it before dispatch, and it returns a structured reason code on any block.
The wildcard DNC pattern (channel='*') is the load-bearing primitive. When a recipient says STOP on SMS, the right behaviour is not 'opt them out of SMS' — it's 'opt them out of everything you might do to them next'. Autocloz's DNC table supports per-channel rows (channel='sms') and wildcard rows (channel='*') simultaneously; the gate checks both. STOP on any channel writes a wildcard row by default. The operator can downgrade to per-channel via Settings if they have a documented business reason.
Timing runs on two clocks. Each sending account has quiet hours in its own timezone, which stops a mailbox or a number sending at night where it lives. A campaign's sending window is then evaluated in the lead's timezone when one is stored on the lead (from a booking or set on the lead profile), falling back to the campaign's timezone and then the workspace's. Autocloz does not infer a timezone from the phone number, so a 9 AM window in Berlin needs the Berlin timezone on the lead, or a campaign set to Berlin time.
India-specific compliance is its own surface. DLT (Distributed Ledger Technology) registration is mandatory before any SMS can hit Indian numbers; principal entity, header, and template all need approval. WhatsApp Business templates need Meta approval per market. Autocloz does not perform either registration. For India SMS you configure the DLT-registered sender ID from your provider (MSG91, for example), and WhatsApp templates are submitted to Meta and used once Meta approves them. Carrier or Meta rejections are recorded on the touch with the reason, so a failed send is visible rather than silent.
Try it free.
No credit card. Every feature on this page included.