Intry

Telephony

TelephonyProvider abstraction, inbound call flow, and Twilio→Telnyx migration.

Overview

All voice and SMS carrier operations go through the TelephonyProvider interface in src/services/telephony/. Never import Twilio or Telnyx SDKs directly in route handlers.

Deep runbooks: TELNYX_MIGRATION.md, docs/TELNYX_TELEPHONY_DEPLOYMENT_SETUP.md.

Provider selection

ScopeSource
Per virtual numberVirtualNumber.telephonyProvider (twilio | telnyx) — canonical for voice
Property overrideProperty.telephonyProviderOverride for new number purchases
Global fallbackTELEPHONY_PROVIDER env (SMS/comms fallback; deprecated for VNMS)
TELEPHONY_PROVIDER=twilio   # or: telnyx

Inbound call flow

  1. Callbox dials unit's virtual number (E.164).
  2. Carrier webhook → POST /twilio/inbound-call or POST /telnyx/inbound-call.
  3. Core looks up VirtualNumberUnit → residents.
  4. IVR plays; Knock notifies resident devices.
  5. Approve/deny → DTMF or TeXML redirect → door release.
  6. Call + Approval rows persisted.

Routes are mirrored via createVoiceGatewayRouter() in src/routes/voiceGatewayRouter.ts.

Webhook paths (selected)

PurposeTwilioTelnyx
Gate inbound/twilio/inbound-call/telnyx/inbound-call
Call status/twilio/call-status/telnyx/call-status
Approve DTMFTwiML update/telnyx/access-approved-dtmf
10DLC events/webhooks/10dlc/events

Virtual numbers (ADR-001)

  • Assigned per unit, not per property.
  • Tenant cap: unitCount + 5 numbers.
  • Pool management: /api/admin/virtual-numbers/* (see Virtual numbers API).
  • After release, numbers may enter quarantine before reuse.

Migration status (IN-189)

PhaseStatus
TelephonyProvider + TeXML adapterComplete
Parallel /telnyx/* routesComplete
Per-number provider fieldComplete
Production cutoverIn progress — see tools/intry-core-telnyx/CUTOVER.md

OTP verification still uses Twilio Verify regardless of voice provider.


Last verified: 2026-06-21 (commit 293c4a7)

On this page