Cold-calling regulations are why most "AI sales agent" demos never make it into production. Crixin Voice ships every guard-rail we ran in the hosted Teams product — TCPA windows, DNC, answering machine detection, consent, opt-out — wired in before any TwiML ever leaves your machine. Disable them deliberately, not accidentally.
Each gate runs as a pre-dial check. If a gate fails, no Twilio API call is made and the lead is moved to the appropriate state — blocked_tcpa, dnc, or do_not_recontact.
Outbound calls only between 8:00 AM and 9:00 PM in the lead's local time, derived from area code → US state → time zone. A call queued at midnight UTC for a 415 number won't dial until 8 AM Pacific.
Numbers added to your tenant's DNC list are blocked permanently. The list is local — it's a Firestore collection in the hosted product, a JSON file or the --dnc-list path in the OSS one. Federal DNC scrubbing is your responsibility (see disclaimer below).
dncEvery lead must carry a consent_basis field — express_written, existing_business_relationship, b2b_office, or none. Calls with none are blocked unless you set requireConsent: false at hire time.
blocked_no_consentTwilio's AMD is enabled on every call (MachineDetection=DetectMessageEnd). If a machine answers, the agent waits for the beep, drops the configured voicemail TwiML, hangs up. No human ever hears a half-spoken pitch into voicemail.
Every call recording is transcribed and scanned for opt-out phrases ("don't call me", "remove me from your list", "stop calling", + 30+ variants and Spanish equivalents). Match → number is added to DNC immediately and the lead is set to do_not_recontact.
Defaults are on. You can soften individual gates per-agent or per-campaign, but the surface is explicit — a forgotten flag won't land you in court.
// crixin.config.ts import { defineConfig } from "crixin/voice"; export default defineConfig({ compliance: { tcpaWindow: { start: "08:00", end: "21:00" }, dncList: "./dnc.json", requireConsent: true, amd: "DetectMessageEnd", optOutPhrases: "./opt-out.json", // or "default" onOptOut: "auto_dnc_and_lock", // or "log_only" }, });
Every call writes a compliance row. Hosted product writes to Firestore teams_compliance_log; OSS writes to whatever durable store you configure (default: a JSONL file).
{
"call_sid": "CAabc…",
"to": "+14155550100",
"from": "+14155551111",
"timestamp_utc": "2026-05-09T17:42:18Z",
"local_time": "2026-05-09 10:42 PT",
"tcpa_window_passed": true,
"dnc_check_passed": true,
"consent_basis": "existing_business_relationship",
"amd_result": "human",
"opt_out_detected": false,
"recording_url": "https://api.twilio.com/.../RE5b…/Recordings/RE5b…",
"transcript_excerpt": "…thanks for calling, please send the deck."
}
Crixin Voice is a tool, not a compliance program. The five gates above are the same defenses we ran in production — but production for our SaaS, with our DNC list, our consent collection, our retention rules. You are responsible for:
· Scrubbing against the federal DNC registry (donotcall.gov) before importing leads into the system. Crixin Voice does not auto-scrub.
· Capturing express written consent where required (TCPA, your state, your industry). The consent_basis field is a record of what you claim, not what we verified.
· State-specific rules (e.g., Florida HB 761's prior express written consent requirement, Oklahoma's TCPA mini-statute, Washington's RCW 80.36.400).
· Recording disclosure. Two-party-consent states (CA, FL, IL, MD, MA, MT, NH, PA, WA) require you to announce the recording at the start of the call. The default opener TwiML includes the disclosure; if you swap it out, that's on you.
· This page is not legal advice. Talk to a TCPA-class-action defense attorney before running any high-volume campaign.