beyondcalls.aiv8.42.0

BeyondCalls Documentation

The AI Revenue Operating System for autonomous outbound sales. Multi-channel sequences, AI voice dialing, real-time call coaching, and intelligent email automation.

Architecture

BeyondCalls is built on a modern stack designed for real-time sales operations:

  • Frontend — Next.js 16, React, TypeScript, Tailwind CSS, shadcn/ui
  • Backend — Next.js API Routes (App Router), Prisma ORM
  • Database — PostgreSQL with multi-schema architecture (public, revenue_os, communications)
  • Voice — Telnyx TeXML Voice, Telnyx WebRTC SDK, Retell AI
  • Transfer Architecture (v6.2.1) — Zero-Delay Pre-Connect with AMD Gating: agent joins conference simultaneously with prospect call (0s dead air). AMD confirmation gates disposition screen. endConferenceOnExit="true" ensures prospect hangup ends both calls. LHU auto-submits in 1.5s.
  • Real-time — Pusher for live event streaming to SDR desktops
  • Email — Resend API for transactional email, with SMTP fallback
  • AI — OpenAI GPT-4o for email generation, Retell AI for voice conversations
  • Auth — Clerk for authentication and team management
  • Hosting — Google Cloud Run (GCP) with Cloud SQL PostgreSQL

Quick Start

After signing in to the dashboard, the typical SDR workflow is:

  1. Import Leads — Upload a CSV or connect Apollo/ZoomInfo/Explorium in Lead Gen settings
  2. Create a Campaign — Set up a power-dial campaign with your script, talking points, and DID selection
  3. Build Sequences — Create multi-step email sequences with AI-generated content and collateral
  4. Start Dialing — Launch the power dialer from the SDR Desktop. The AI handles initial conversations.
  5. Take Transfers — When the AI confirms a human prospect, you're seamlessly connected via direct dial (sub-2 second latency)
  6. Review & Coach — Use the AI Coaching Dashboard to review calls, analyze performance, and replay Retell conversations

Power Dialer

The power dialer calls multiple prospects simultaneously, dramatically increasing connect rates. When a human answers, the system bridges them to you instantly.

How It Works

  1. Select a campaign and click Start Power Dial on the SDR Desktop
  2. The system dials 3-5 leads from your campaign simultaneously
  3. Each call runs through AMD (Answering Machine Detection) or Retell AI
  4. Voicemails and machines are automatically disconnected
  5. The first human to answer wins — all other calls are cancelled
  6. You're connected via direct <Dial><Client> bridge with sub-2 second latency — no conference overhead
Pro Tip: AMD detection runs for 5 seconds. During this time the prospect hears silence. If AMD returns "unknown," the system treats it as a human and connects you — better to talk to a maybe-human than miss a real one.

Hot-Bridge Transfers

Hot-Bridge is the premium transfer mode using Retell AI. Instead of silent AMD, an AI agent has a natural conversation with the prospect first.

v6.0.0 Direct-Dial Transfer Flow

  1. AI calls prospect — Retell AI dials the prospect and has a natural conversation
  2. Human verification — The AI confirms the answerer is a real human (not voicemail)
  3. Instant response — Webhook returns to Retell in <200ms via after(), AI speaks "Transferring you now" immediately
  4. Direct dial redirect — Prospect's existing call is redirected with <Dial><Client>agent-xxx</Client></Dial> — just 2 media hops
  5. Seamless handoff — SDR hears the prospect within 1-2 seconds. No conference overhead, no audio crackling.
v6.0.0 Architecture: Transfers no longer use Conference by default. The prospect's PSTN call is directly bridged to the SDR's WebRTC client (2 media hops instead of 3). Conferences are only created on-demand when a supervisor needs to listen, whisper, or barge in.

Direct Dial Architecture

The v6.0.0 Hybrid Transfer Architecture fundamentally changes how calls are connected:

Before (Conference-Based — v5.x)

text
Prospect PSTN → Conference → SDR WebRTC
                     ↑
              3 media hops, ~5-8s latency
              Audio crackling from triple relay

After (Direct-Dial — v6.0.0)

text
Prospect PSTN → Provider Bridge → SDR WebRTC
                     ↑
              2 media hops, <2s latency
              Zero audio crackling

Key Components

  • Nuclear Path — Retrieves the underlying Call SID from Retell and redirects it with calls(sid).update(twiml). The prospect never disconnects.
  • Fallback Path — If we can't retrieve the Call SID, we create a new outbound call with <Dial><Client> TwiML.
  • Dial Complete Webhook/api/webhooks/warm-transfer/dial-complete stores the SDR's child Call SID for potential conference escalation.
  • On-Demand Escalation/api/webhooks/warm-transfer/escalate-conference upgrades any direct-dial call to a conference when a supervisor needs access.
  • SDR LHU Auto-Detect — If the prospect disconnects, the SDR Desktop automatically pre-selects "Lead Hung Up" disposition.

Latency Benchmarks

ParameterTypeRequiredDescription
Hot-Bridge webhook response153-207msNoTime for Retell to receive tool result (AI speaks instantly)
AMD Callback (2x-5x power dial)240-337msNoTime to return AMD result and trigger agent call
dial-complete webhook134-182msNoSDR call SID storage, call lifecycle management
escalate-conference134-194msNoOn-demand conference creation for supervisor

AI Context Summarization

Paste any sales document (pitch decks, competitive analysis, product specs) into the Campaign Context Editor, and GPT-4o instantly extracts curated talking points for live calls.

How It Works

  1. Open the Sales Context tab in any campaign or the SDR Desktop
  2. Paste your raw document text (min. 20 characters)
  3. Click the AI Summarize button
  4. GPT-4o extracts: 5 icebreakers, 5 pain points, and an elevator pitch
  5. Results appear in the new AI Insights tab and are saved to the campaign
  6. During live calls, the Sales Copilot automatically injects these as priority icebreakers

API

POST/api/warm-transfer/campaigns/[id]/summarize-contextExtract icebreakers & pain points from raw context
ParameterTypeRequiredDescription
textstringYesRaw sales context text (min 20 chars, max ~8000 chars processed)
The AI summary is stored on the campaign and automatically used by the Copilot during live calls. No manual copy-paste needed.

AI Call Coaching

The Coaching Dashboard analyzes your calls and provides actionable feedback:

  • Call Recordings — Review all recorded calls with playback controls
  • AI Analysis — Get automated feedback on talk-to-listen ratio, objection handling, and closing techniques
  • Retell Replay — Review what the AI said to the prospect before the transfer
  • Performance Metrics — Track connect rates, call durations, and conversion trends over time

iPhone VM Guard

iPhone VM Guard prevents transfers to voicemail by running a secondary AMD check before completing the hot-bridge transfer. If the prospect's phone goes to voicemail after initial pickup (common with iPhone's "Silence Unknown Callers"), the transfer is blocked and the call is ended gracefully.

Retell AI Replay

Replay AI-prospect conversations directly from the SDR Desktop or Coaching Dashboard:

  • Structured Transcript — Turn-by-turn chat bubbles showing what the AI and prospect said
  • Audio Playback — Play, pause, and seek through the call recording
  • Call Metadata — Duration, sentiment analysis, call outcome, disconnect reason
  • Multi-Call View — See all AI calls for a specific lead

Email Sequences

Build multi-step outreach sequences that combine email, phone, SMS, LinkedIn, and conditional logic.

Supported Step Types

  • EMAIL — Automated email with personalization variables and tracking
  • PHONE_CALL — Reminder to make a phone call (integrates with power dialer)
  • SMS — Text message step (via SMS)
  • LINKEDIN — LinkedIn outreach reminder or automation
  • CONDITION — Branch logic based on email opens, clicks, replies, or bounces

Writing Styles

Each sequence can be configured with a writing style that affects all AI-generated content:

ParameterTypeRequiredDescription
formalstyleNoProfessional, business-appropriate language. No slang or contractions.
casualstyleNoFriendly and conversational. Uses contractions naturally.
assertivestyleNoDirect and confident. Leads with strong value propositions.
consultativestyleNoHelpful and advisory. Asks insightful questions. Positions as trusted advisor.
educationalstyleNoInformative and teaching-oriented. Shares data and insights.

Sales Collateral

Attach sales materials to sequence steps. Collateral is automatically referenced in AI-generated emails.

  • Types — Whitepapers, Case Studies, ROI Calculators, Product Demos, Pricing Sheets, Battle Cards
  • AI Targeting — Each piece has metadata: target industries, personas, pain points, buying stages
  • Performance Tracking — Track times used, opens, and reply rates per collateral piece

AI Email Generation

Generate personalized email content using GPT-4o. The AI considers lead context, sequence configuration, previous emails, and attached collateral.

bash
curl -X POST /api/v2/sequences/generate-email \
  -H "Content-Type: application/json" \
  -d '{
    "firstName": "Sarah",
    "lastName": "Chen",
    "title": "VP of Sales",
    "company": "Acme Corp",
    "industry": "SaaS",
    "writingStyle": "consultative",
    "stepType": "initial_outreach",
    "customInstructions": "Mention our recent Series B funding"
  }'

Open & Click Tracking

Every email sent through the sequence engine includes automatic tracking:

Open Tracking

A 1x1 transparent pixel is injected at the bottom of every HTML email. When the recipient's email client loads the image, an OPENED event is recorded with timestamp and user agent.

Click Tracking

All links in outbound emails are automatically wrapped with tracking redirects. When a recipient clicks a link, a CLICKED event is recorded before redirecting to the original URL.

Note: Apple Mail Privacy Protection may pre-fetch images, which can inflate open rates. Click tracking is generally more reliable for measuring engagement.

API Reference

All API endpoints require authentication via Clerk. Include the session token in the request headers.

Sequences

GET/api/v2/sequencesList all sequences
POST/api/v2/sequencesCreate a new sequence
GET/api/v2/sequences/[id]Get sequence details
PUT/api/v2/sequences/[id]Update a sequence
DELETE/api/v2/sequences/[id]Delete a sequence
GET/api/v2/sequences/[id]/stepsList steps for a sequence
POST/api/v2/sequences/[id]/stepsAdd a step to a sequence
POST/api/v2/sequences/[id]/enrollEnroll leads in a sequence
POST/api/v2/sequences/processProcess due enrollments (trigger engine)

Collateral

GET/api/v2/collateralList all sales collateral
POST/api/v2/collateralCreate collateral
PUT/api/v2/collateralUpdate collateral
DELETE/api/v2/collateralDelete collateral

Email Accounts

GET/api/v2/email-accountsList connected email accounts
POST/api/v2/email-accountsConnect a new email account
PUT/api/v2/email-accounts/[id]Update account settings
DELETE/api/v2/email-accounts/[id]Disconnect an account
POST/api/v2/email-accounts/[id]/testTest email account connection

AI Email Generation

POST/api/v2/sequences/generate-emailGenerate personalized email content
ParameterTypeRequiredDescription
leadIdstringNoAuto-enrich from lead data (name, company, industry)
sequenceIdstringNoAuto-enrich from sequence config (writing style, brand voice)
firstNamestringNoProspect's first name
companystringNoProspect's company name
titlestringNoProspect's job title
industrystringNoProspect's industry
writingStylestringNoformal, casual, assertive, consultative, educational
stepTypestringNoinitial_outreach, follow_up, breakup, nurture, re_engagement
customInstructionsstringNoAdditional prompt instructions for the AI
collateralSummarystringNoSummary of attached collateral to reference
previousEmailsstring[]NoPrevious email subjects for context continuity

Response:

json
{
  "subject": "Quick question about Acme's Q4 pipeline",
  "body": "Hi Sarah, ...",
  "bodyHtml": "<div>...</div>",
  "preheader": "I noticed Acme recently...",
  "cta": "Would a 15-minute call this week work?",
  "personalizationNotes": "Referenced VP title, SaaS industry",
  "model": "gpt-4o",
  "tokensUsed": 347
}

Email Tracking

GET/api/v2/emails/track/open?id={eventId}Tracking pixel (returns 1x1 GIF)

Returns a transparent 1x1 GIF image. Records an OPENED event for the given email event ID. No authentication required — this is embedded in emails.

GET/api/v2/emails/track/click?id={eventId}&url={destinationUrl}Click redirect (302)

Records a CLICKED event and redirects (302) to the destination URL. No authentication required — this wraps links in emails.

GET/api/v2/emails/eventsList email events (sent, opened, clicked, etc.)

Retell Replay

GET/api/v2/retell/replay?callId={retellCallId}Get call transcript, recording, and analysis
GET/api/v2/retell/replay?leadId={leadId}Get all Retell calls for a lead

Response:

json
{
  "call": {
    "callId": "call_abc123",
    "callStatus": "ended",
    "durationMs": 45000,
    "recordingUrl": "https://...",
    "callAnalysis": {
      "userSentiment": "Positive",
      "callSuccessful": true
    },
    "segments": [
      { "role": "agent", "content": "Hi, this is Joe from..." },
      { "role": "user", "content": "Oh hi Joe, how are you?" }
    ]
  }
}

Analytics

GET/api/v2/sequences/analyticsSequence performance analytics

Returns conversion funnel metrics: enrolled, sent, opened, clicked, replied, meetings booked. Supports per-sequence filtering and time period selection.


Webhooks

Webhook endpoints that receive callbacks from Telnyx, Retell AI, and Resend.

Warm Transfer Webhooks

POST/api/webhooks/warm-transferMain call status webhook
POST/api/webhooks/warm-transfer/amd-callbackAMD detection results
POST/api/webhooks/warm-transfer/conferenceConference events (join, leave)
POST/api/webhooks/warm-transfer/inbound-callInbound call routing
POST/api/webhooks/warm-transfer/recording-statusRecording completion
POST/api/webhooks/warm-transfer/call-statusCall lifecycle events

Dial Complete (v6.0.0)

POST/api/webhooks/warm-transfer/dial-completeDirect-dial action callback — called when <Dial> completes

Called by the provider when the <Dial><Client> action completes (either party hangs up, or the dial fails). Handles call lifecycle management for direct-dial transfers:

ParameterTypeRequiredDescription
CallSidstringYesProspect's parent call SID
DialCallSidstringYesSDR's child call SID (stored for conference escalation)
DialCallStatusstringYescompleted, busy, no-answer, failed, canceled
CallDurationstringNoCall duration in seconds
leadIdstringYesLead ID (query param)
campaignIdstringNoCampaign ID (query param)

Escalate Conference (v6.0.0)

POST/api/webhooks/warm-transfer/escalate-conferenceOn-demand conference upgrade for supervisor listen/whisper/barge

Upgrades a direct 2-party call to a Conference when a supervisor needs to listen, whisper, or barge in. Gets both call SIDs from the lead record and redirects both legs into a new conference.

ParameterTypeRequiredDescription
leadIdstringYesLead ID — used to look up both prospect and SDR call SIDs

Response:

json
{
  "success": true,
  "conferenceName": "escalate-abc123def-1711523456789",
  "message": "Direct-dial call escalated to conference. Supervisor can now join."
}

Retell AI Webhooks

POST/api/webhooks/retell/statusRetell call status updates
POST/api/webhooks/retell/toolsRetell tool execution (hot_bridge_transfer, etc.)

The tools webhook handles custom tool calls from the Retell AI agent, including hot_bridge_transfer (direct-dial bridge, v6.0.0), schedule_callback, and end_call. Uses Next.js after() to return the tool result in <200ms while executing all telephony/Pusher bridging in the background.

Resend Email Webhooks

POST/api/v2/webhooks/resendEmail delivery events (delivered, bounced, complained)

Configuration

Setup guides for all third-party integrations.

Telephony Setup

Required environment variables:

env
TWILIO_ACCOUNT_SID=ACxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_AUTH_TOKEN=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
TWILIO_PHONE_NUMBER=+15551234567
TWILIO_PHONE_NUMBERS=+15551234567,+15559876543
TWILIO_TWIML_APP_SID=APxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

The TwiML App routes Device SDK calls to the /api/webhooks/warm-transfer/inbound-call webhook. All phone numbers must be configured with this same Voice URL for inbound call handling.

Critical: Do not set edge on the WebRTC SDK or region on Conference TwiML. Let the provider auto-select the closest edge server for optimal audio quality.

Retell AI Setup

env
RETELL_API_KEY=key_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
RETELL_AGENT_ID=agent_xxxxxxxxxxxxxxxxxxxxxxxxxxxx
RETELL_CONVERSATION_FLOW_ID=conversation_flow_xxxxxxxxxxxx
RETELL_FROM_NUMBER=+15551234567

Configure your Retell agent with a conversation flow that includes the hot_bridge_transfer custom tool. The tool webhook URL should point to /api/webhooks/retell/tools.

Phone Numbers

ParameterTypeRequiredDescription
Telnyx NumbersPSTNNoPrimary outbound DIDs. Used for power dialing and AMD path via TeXML.
Retell-Telnyx NumbersSIPNoManaged by Retell. Good for AI inbound/outbound. Cannot be redirected from your provider account.
Custom (Imported)SIPNoYour Telnyx numbers imported into Retell. Best of both worlds — AI + redirect control.
SIP Trunk: Custom numbers require a properly configured SIP Trunk and SIP Domain for outbound routing. See the Telnyx portal for setup.

Email Accounts

Connect email accounts for sequence sending in Dashboard > Email Config:

  • Resend API — Fastest setup. Add your Resend API key and verified sending domain.
  • SMTP — Any SMTP server (Gmail, Outlook, custom). Requires host, port, username, password.
  • Gmail OAuth — Connect via Google OAuth for Gmail sending without app passwords.

Email Campaigns (v7.0)

Complete email automation: from lead discovery to personalized campaign launch in 8 steps.

8-Step Campaign Wizard

Navigate to /dashboard/email-wizard to launch the campaign builder:

  1. Campaign Setup — Name, ICP profile, Campaign Brief selection for AI grounding
  2. Lead Generation — Apollo search OR CSV upload with enrichment
  3. Email Template — Tone selection (5 styles), template skeleton, sender info. Load from existing sequences.
  4. Sales Collateral — Attach whitepapers, case studies, ROI calculators
  5. Bulk Generation — GPT-4o generates unique personalized email per lead (up to 50/batch)
  6. Review & Edit — Inline edit each email before sending
  7. Mailbox Selection — Choose connected email account
  8. Launch — Campaign summary, go live, track in analytics

AI Intelligence Engine

The Intelligence Engine v2 generates personalized emails at scale using GPT-4o:

POST/api/email/bulk-generateBulk generate personalized emails
  • 5 Writing Tones: Formal, Casual, Assertive, Consultative, Educational
  • Template Injection: Provide a skeleton with {{name}}, {{company}} placeholders
  • Campaign Brief Context: AI references uploaded PRDs and product docs for zero-hallucination emails
  • Batch Processing: 5 leads per API call, up to 50 leads per run with progress tracking

AI Sequence Optimizer

Navigate to /dashboard/sequence-optimizer for AI-powered sequence analysis:

POST/api/v2/sequences/optimizeAnalyze sequence with GPT-4o and get recommendations
  • Performance Analysis: Evaluates subject lines, body content, timing, and follow-up cadence
  • Prioritized Recommendations: HIGH / MEDIUM / LOW impact suggestions
  • Predicted Improvement: Estimated uplift percentages for each recommendation
  • One-Click Apply: Apply recommendations directly to your sequence

Email Account Setup

Configure sending accounts in Dashboard > Email Config. Four providers supported:

ParameterTypeRequiredDescription
ResendAPI KeyNoFastest setup. Add API key + verified domain. Best deliverability.
SendGridAPI KeyNoEnterprise-grade. API key + verified sender identity.
Gmail OAuthOAuth 2.0NoGoogle OAuth flow with refresh token. No app password needed.
SMTPCredentialsNoAny provider: host, port (587 STARTTLS / 465 SSL), username, password.
v7.0.2 Fix: SMTP auto-detects encryption: port 587 uses STARTTLS, port 465 uses SSL. Gmail OAuth redirect URI is now properly validated.

Lead Generation

Multi-provider lead sourcing with inline API key management.

Apollo.io Integration

Connect your Apollo API key in Dashboard > Lead Gen > Providers to access:

  • People Search: Filter by job title, industry, location, company size, seniority
  • People Enrich: Batch enrichment of up to 25 leads per request with verified emails and phone numbers
  • Campaign Wizard Integration: Search and enrich leads directly in Step 2 of the wizard

Provider Management

Manage API keys for multiple data providers:

GET/api/lead-gen/providersList connected providers
POST/api/lead-gen/providersConnect a new provider (Apollo, ZoomInfo, Explorium)
DELETE/api/lead-gen/providers/[id]Disconnect a provider
v7.0.2 Fix: The "Unauthorized" error when saving API keys was fixed by restoring the Clerk auth middleware (proxy.ts).

CSV Upload

Upload leads via CSV in the Campaign Wizard (Step 2) or the Lead Gen page:

  • Smart Column Parsing: Automatically maps email, name/first_name+last_name, company, title, industry
  • Deduplication: Detects and skips existing leads by email address
  • Enrichment: Optionally enrich imported leads via Apollo after upload

Production & Scaling

Ops tools for production readiness and SDR scaling.

System Health Check

GET/api/healthComprehensive system diagnostics

Returns granular status for all subsystems. Use as a daily pre-flight check before SDRs log in:

json
{
  "status": "green",          // green | yellow | red
  "version": "7.3.8",
  "services": {
    "database": { "status": "ok", "latencyMs": 12 },
    "telephony": { "status": "ok", "details": "Telnyx active. 12 DIDs, SIP connected, A-attestation." },
    "retell": { "status": "ok", "details": "Agent: agent_xxx" },
    "pusher": { "status": "ok", "details": "Cluster: mt1" },
    "email": { "status": "ok", "details": "Providers: Gmail OAuth" },
    "ai": { "status": "ok", "details": "OpenAI configured" }
  },
  "agents": { "total": 5, "available": 3, "busy": 2, "stale": 0 },
  "scale": { "currentCPS": 5, "recommendedRatio": 3, "maxSDRs": 10 }
}

Scaling to 10-50 SDRs

10 SDR Configuration (Phase 1)

ParameterTypeRequiredDescription
Power Dial Ratio3xNo3 concurrent calls per SDR. 10 SDRs x 3 = 30 calls, spread over 6s at CPS=5.
Provider CPS5NoCalls Per Second limit. Do not exceed. Staggered naturally by 3x ratio.
DB Connection Pool15NoAppend ?connection_limit=15&pool_timeout=30 to DATABASE_URL
DID Pool40-60NoPhone numbers for rotation. Prevents spam flagging.
Pusher PlanFree/StarterNoFree plan supports 200 concurrent connections (fine for 10 SDRs).
Agent Heartbeat5s / 45s staleNoSDR sends heartbeat every 5s. Stale after 45s missed.

50 SDR Configuration (Phase 2)

ParameterTypeRequiredDescription
Telnyx SIPSIPNoDirect Telnyx SIP routing. 50% PSTN cost reduction.
DB Pool25NoIncrease connection_limit to 25.
Pusher PlanGrowthNoUpgrade for 500+ concurrent connections.
Cloud Runmin 2 instancesNoPrevent cold starts. Set min-instances=2 in GCP.

Phase 1 Audit Results (v7.0.2)

Verdict: CONDITIONAL GO — All code checks passed. Two ops actions required before launch.

Passed Checks

  • API Key Token generation (SK-prefix) verified
  • AMD async detection (DetectMessageEnd) active on all dial paths
  • endConferenceOnExit=true on all conference legs
  • No record:true on any calls.create()
  • DNC check before every dial
  • Stale lead auto-release before batch
  • Agent heartbeat (5s) with 45s stale threshold
  • Pusher fully configured (cluster mt1)
  • Cross-campaign SDR routing isolation verified

Required Ops Actions

  1. DB Connection Pooling: Append &connection_limit=15&pool_timeout=30 to DATABASE_URL in GCP
  2. Recording Strategy: Verify account-level recording or re-enable Conference recording

Changelog

The complete per-version breakdown lives in memory/CHANGELOG.md. The most recent v8.x releases are summarized below; deeper 7.x history follows further down.

v8.48.0 — August 2026 — DID reputation forecasts, rest lifecycle, bulk provisioning & org isolation

  • Reputation & rotation forecasts. Every caller ID now shows its age, no-audio/gateway-strike signals, dials-per-day and a projected rotation date from a score-burn model — plus a floor-wide Non-Spam % KPI so the fleet's health is one glance.
  • Rest lifecycle (cooldown, not release). Flagged numbers can be rested for 30 days — they stay owned (callbacks keep routing), leave rotation instantly, and return clean automatically once carriers age out the spam label. Auto-rest/auto-revive runs on a floor-guarded cron sweep.
  • Bulk Purchase & Distribute. One admin action buys up to 200 numbers with an area-code spread matched to your lead geography, gives every SDR without a dedicated DID one, pools the rest, registers Voice Integrity, and puts everything through the 14-day warmup guard. Dry-run plan and explicit cost confirmation before any money moves.
  • Workspace DID isolation. A workspace can only dial from numbers it owns or pooled ones — new orgs get a clear "buy numbers first" path (and a default pool at signup) instead of silently borrowing another org's caller IDs.

v8.47.0 — August 2026 — Network resilience for congested offices (low-bandwidth voice + dial protection + quality forensics)

  • Low-Bandwidth Voice Mode. The browser softphone now negotiates Opus at 16 kbps (PCMU fallback) and pins media to the Singapore edge with roaming fallback — about a third of the wire bandwidth of G.711 with far better packet-loss concealment, sized for an India floor running ~20 SDRs × 3 lines on shared Wi-Fi.
  • Network-aware dial protection. When the live network probe classifies the office connection as POOR, new Power Dial batches hard-pause (in-flight calls untouched) behind a red banner with live RTT/jitter metrics, and dialing auto-resumes the moment the connection recovers — no more burning leads on silent or dropping calls.
  • In-call quality forensics. The Twilio SDK's live quality warnings (packet loss, jitter, high RTT, low MOS, ICE drops) are now logged per call to the forensics store — warnings clustering on one SDR point at their machine/Wi-Fi; floor-wide warnings point at the office uplink.
  • Office IT Runbook. A one-page checklist for the office IT team (bandwidth math, wired-over-Wi-Fi, QoS for Twilio UDP media, SIP ALG off, dual-ISP failover) ships in the repo as OFFICE_IT_RUNBOOK.md.

v8.44.0 – v8.46.1 — August 2026 — Floor-stability rollup

  • Deterministic identity resolution (fixed silent calls / wrong-VM routing caused by duplicate roster rows), team-management authority fix for platform owners, DID reconciliation + gateway-failure auto-retry on manual dial, a no-audio detector with a per-DID 24h forensics card, the DID warmup guard (14-day window + daily cap for fresh numbers), and the SDR header Network Health pill.

v8.42.0 — June 2026 — Marketing site: expanded Platform & dedicated How-it-works + auth data-loss guard

  • Public /features rebuilt and expanded (impact metrics, a "replaces your stack" before→after, a capability comparison checklist, and a go-live onboarding timeline) and a new dedicated /how-it-works page (anatomy-of-a-call timeline, non-human handling, a live-ops floor mockup and an FAQ). /resources and these Docs rebranded to the navy/red BeyondCalls theme.
  • Auth data-loss guard. Returning users are now matched against ALL of their verified Clerk emails (not just the primary), so a Google / magic-link sign-in can never drop an existing user into a new empty workspace and hide their historical call logs and campaigns.

v8.41.0 — June 2026 — Landing redesign (light + dark editions)

  • The landing page was rewritten around the AI-workforce positioning with a fully theme-responsive dark (near-black navy) and light edition, a live-ops hero mockup, and the "Dial → Detect → Verify → Bridge" narrative.

v8.40.0 — June 2026 — Public auth + isolated tenants

  • Trusted email domains join the main organization; every other authenticated email is provisioned an isolated workspace (their own Organization, scoped reads only) instead of hitting a request-access dead-end. Kill-switch via PUBLIC_ISOLATED_SIGNUP=false.

v8.39.0 — June 2026 — AMD dead-air hang-up fix

  • Tightened AMD end-of-speech thresholds so a verified human is bridged ~0.4–0.8s faster — closing the trailing dead-air gap that made prospects hang up right after "hello".

v8.37.0 — June 2026 — Power-dial race fix + global outbound dialing

  • Fixed a call-status race that stranded leads at completed+attemptNumber=0 (dropping them from every dial pool), enabled outbound dialing to 21+ countries, and added country flags + local-time calling windows for international prospects.

v8.34.0 — 2026 — Multi-country dialing foundation

  • Additive groundwork so a mixed-country list (India + UK + US + AU) can be uploaded, previewed and safely dialed: phone-country detection, per-campaign coverage checker, and country-matched DID selection.

v8.33.0 — 2026 — SDR profile: campaign roster + inbox deep-links

  • SDRs can now see every campaign they've touched (including cancelled/archived), with per-SDR stats and deep-links from a voicemail disposition straight to playback in My Inbox.

v8.32.3 — July 17, 2026 — Power Dial session stats + pop-up never freeze (React batching fix)

  • The recurring "dashboard stats are frozen" SDR bug is fully fixed. v8.32.1 keyed the dedupe correctly by callSid and passed its unit test, but the pop-up and top-strip still froze in production. Real root cause: React 18 automatic batching. Three call sites replace the power-dial feed with a filter that drops terminal legs (batch response, Pusher power-dial-started, and the implicit intermediate step when a terminal Pusher update lands in the same tick). React merges multiple setPowerDialFeed calls in one event-loop tick into ONE commit — so the intermediate render (leg = voicemail) never happens and the feed useEffect that counts terminals never sees the transition. The dial IS placed and the DB records it, but the client-side totals sit frozen because the very legs that would have incremented them were filtered out one microtask before the effect could count them.
  • Fix (defence-in-depth): the two feed-replacement filters now KEEP a terminal leg unless countedCallSidsRef already accounts for it — the useEffect gets a guaranteed render tick to count it before it's dropped on the next batch. Filters stay pure (ref reads only) so React concurrent rendering can never double-count. The Pusher power-dial-lead-update handler also refreshes the leg's callSid when the payload carries a new one (retell / carrier retries) so the callSid dedupe stays correct on redials. sessionStartAt and the effect body itself (v8.32.1) are untouched. tests/test_v8323_stats_never_freeze.ts 13/13.

v8.32.2 — July 16, 2026 — New SDR disposition "No Longer Works" (NLWH)

  • Wires NLWH end-to-end as a terminal / wrong-person disposition (semantically identical to NTRP/WN — a human answered but the target has moved on from the company we're dialing). Aliases no_longer_works / no_longer_works_here / no-longer-works normalize to NLWH. Classifies as human_connected, never re-dialed (terminal + restart-terminal + human-disposition membership).

v8.32.1 — July 16, 2026 — Power Dial banner stopped freezing after cool-off (v1)

  • Two independent bugs made the persistent banner look frozen once a session survived a cool-off: session counters keyed by leadId (a re-dialed lead was already in the set → skipped) and the elapsed timer resetting on every batch (feed-min derivation). Fixed by dedupe-by-callSid and a persistent sessionStartAt. See v8.32.3 for the React-batching follow-up that closes the residual production freeze.

v8.32.0 — July 16, 2026 — Analytics: VMs demoted from "Human Connects — Proof"

  • When AMD confirmed a machine AND the classifier's raw code is the ambiguous CONNECTED (no SDR-set disposition), the row is now demoted to voicemail in the drill-down, the reconciliation summary and the CSV. Explicit SDR dispositions (MF/QUAL/CB/FUP/NI/…) are never touched — the SDR was the human on the call, AMD was wrong. Overview stat cards, SDR leaderboard and recordings unchanged.

v8.31.0 — July 15, 2026 — Meetings drill-down

  • Click the "Meetings Booked" stat card on Analytics → Overview to open an audit table of every meeting booked in the period: SDR, prospect (name/phone/company), campaign or "Manual dial", when the meeting is scheduled, the SDR's notes, and the call recording played inline. Manual-dial meetings matched via the same-agent nearest-in-time recording.

v8.30.1 — July 15, 2026 — Meetings-booked undercount fixed

  • Meetings are now counted from the disposition EVENT log (the same source of truth the SDR dashboard uses), deduped per lead/call. Manual/direct dials (no leadId) are counted, and an MF set today on a lead dialed days earlier is attributed to today — not the dial date.

v8.30.0 — July 15, 2026 — Recording reconciliation sweep + Drop Analysis

  • Recording reconciliation. New hourly cron treats Twilio as the source of truth: missing rows are created, misattributed rows are re-attributed (dialed-number match), untouchable rows are left alone. Conservative by design — nothing is guessed.
  • Drop Analysis page (Operations → Drop Analysis): per-SDR drop rate, Twilio error-code breakdown, recent-drops feed. Built on the new CallDisconnect telemetry captured on every SDR softphone call end.

v8.29.0 — July 15, 2026 — On-screen disconnect reasons + manual-dial recording attribution

  • The telephony device now classifies every call end (network/media ERROR with Twilio error code translated to plain English, LOCAL, or REMOTE) and the reason renders on the wrap-up screen. Abnormal drops also fire an immediate toast so "my call randomly disconnected" tickets become self-explanatory.
  • Manual-dial recording attribution: the voice webhook now resolves the dialing SDR from the client identity and passes org + agent + dialed phone to the recording callback → correct lead in the SDR's org (blind "most recent lead" fallback disabled for direct dials).

v8.28.0–v8.28.2 — July 15, 2026 — Continuous-pipeline power dialer overhaul

  • Pipeline refill — resolved legs are topped up immediately while siblings still ring (no more "whole batch pinned to the slowest leg").
  • DB polling fallbackGET /api/warm-transfer/power-dial/status resolves legs even when Pusher events are dropped (previously stalled every such batch to the 40-45s watchdog).
  • Pause-aware watchdog — the 5s watchdog now respects the server-directed cool-off window instead of hammering the API and re-firing the "cooling off" toast every 10s.
  • Stuck-lead reaper — leads whose terminal webhook was lost are auto-recycled after 10 minutes so first-pass coverage is complete.
  • Persistent SDR banner with engine state (DIALING/PAUSED with a countdown/QUEUEING), first-pass coverage progress bar ("X/Y leads dialed at least once"), live dials/min and session totals.
  • Stale-claim arbitration (v8.28.2) — an AgentPresence row pinned to a dead Twilio CallSid is healed with an atomic conditional update so batches can never 409 forever.

v8.26.0 — July 13, 2026 — Per-SDR atomic bridge lock

  • The AMD winner path now claims the SDR presence conditionally (only if not on another live call); a colliding bridge INVITE is ended, the lead requeued (+30 min cool-off), and the SDR presence released. Root cause of the "VM greeting playing mid-conversation" + "wrap-up at 0:02 mid-call" + wrong-prospect identity reports.

Historical v7.x release notes follow below.

v7.6.8 — June 1, 2026 — Inbound-calls voicemail playback ("Missing recording SID") fix

  • "Missing recording SID" on the Inbound Calls page. The /api/inbound-calls API built the player URL with the wrong query param (?recordingSid= instead of ?sid=), so the recording SID never reached the stream route. The recording itself was fine — only the URL was malformed. Surfaced (not caused) by the v7.6.6 inline error surfacing. Guard test added so the wrong param can't return.

v7.6.7 — June 1, 2026 — Recording Health (admin drift detector)

  • Recording Health card on /dashboard/admin/dial-errors — a read-only, per-provider (Twilio/Telnyx) check that pings the most-recent recording to verify it's actually fetchable with this environment's credentials, catching deployed-env credential drift before an SDR hits a dead player. Per-provider badges (Playable / Failing / Not configured / No recordings) with sample SID, HTTP status, latency, and the exact error.
  • New GET /api/admin/telephony/recording-health. Deliberately separate from the playback path — /api/v2/recordings/stream and the calling path are untouched. 11/11 invariants + a live probe of the real Twilio voicemail returned ok.

v7.6.6 — June 1, 2026 — Recording/Voicemail Playback Permanent Fix

  • Recordings/voicemails wouldn't play (greyed out at 0:00 / 0:00) in the deployed app. The v7.6.5 HTTP-Range fix targeted the wrong layer. A native <audio src> doesn't carry the Clerk bearer token through the Cloud Run proxy → 401 → silent grey-out.
  • Fix: a shared authenticated loader attaches the bearer token and plays from an in-memory Blob, and a reusable <RecordingPlayer> now surfaces the exact error inline + Retry so it can never silently fail again. Rolled out to My Inbox voicemails, inbound-calls, the recordings library, warm-transfer recordings, and coaching. 10/10 + regression 8/8.

v7.6.5 — June 1, 2026 — Wrong-Prospect Fix (permanent) + Voicemail Playback Fix

  • Wrong prospect on connected power-dial calls (permanent fix). During a live call the desktop + CRM panel could show a different prospect than the one on the line. The confirmed-winner guard now covers every activeLead write path (a centralised gated setter), the winner is reset when a new batch dials (so back-to-back batches never show the previous prospect), and the bridged call's own leadId is treated as authoritative.
  • Voicemail playback. Voicemails in My Inbox (and the missed-callbacks player) now play correctly — the recording stream proxy implements HTTP Range / 206 Partial Content (Chrome's <audio> requires it) for both Twilio and Telnyx.

v7.6.4 — May 31, 2026 — My Inbox: SDR Voicemail Box + Unified Activity Dashboard

  • Every SDR gets a personal inbox. New /dashboard/my-inbox workspace with two tabs — Voicemails and My Activity. Voicemail boxes are now fully active for dedicated DIDs.
  • Voicemails — voicemails left on the DIDs you own (lead/company/title, caller, DID, time, duration) with an inline recording player + transcript, an editable Notes field, a Mark resolved toggle, and a Schedule callback action that books a meeting for the prospect and resolves the voicemail.
  • My Activity — a single, filterable disposition log of meetings booked, voicemails received, and dispositions set — each row carries the CRM customer details (name, company, phone, email, campaign). Filter by type / campaign / date-range / meeting-status with one-click CSV export.
  • New GET/PATCH /api/me/voicemails, POST /api/me/voicemails/schedule-callback, GET /api/me/activity. InboundCallLog gained an ownerNotes column. 11/11 invariants.

v7.6.3 — May 29, 2026 — My Missed Callbacks (SDR surface + badge + toast)

  • SDRs never lose a missed callback. New "My Missed Callbacks" section on the Inbound Calls page, scoped to DIDs you own — shows prospects who rang back while you were offline, with lead/company, caller, DID, time, an inline recording player, and a one-tap Call back button.
  • Sidebar badge on "Inbound Calls" showing a live count of your unresolved missed callbacks, plus an on-login toast nudge the next time you come online.
  • A missed callback auto-clears once you call back and log a disposition. 100% additive + read-only — no telephony or schema changes. 7/7 invariants.

v7.6.2 — May 29, 2026 — Callback Won-Back Attribution & ROI Leaderboard

  • Prove the ROI of warm callbacks. When a rep dispositions a lead, the outcome is auto-attributed to a recent inbound dedicated-DID callback (within 3h). Positive outcomes (meeting booked / qualified) flag the callback as won back.
  • Callback ROI card on the Admin SDR-DIDs page — total callbacks, won-back count, conversion %, and an estimated pipeline figure (won-backs × CALLBACK_MEETING_VALUE_USD, default $1,500), plus a "Callbacks Converted" leaderboard.
  • New GET /api/admin/sdr-did-assignments/attribution. InboundCallLog gained disposition + won-back attribution columns. 10/10 invariants.

v7.6.1 — May 29, 2026 — Callback SLA + Auto-Assignment & DID Webhook Auto-Config

  • Never drop a callback. When a prospect rings back a dedicated DID and the owning rep is offline, the callback is auto-assigned to the next available rep on the same campaign (with the same Warm Callback context) instead of going to voicemail.
  • Voicemail is the last resort — only when no campaign-mate is online — and now raises a callback_missed SystemAlert for supervisors. SLA target is configurable via CALLBACK_SLA_SECONDS (default 60s).
  • Supervisor "Dedicated-DID Callbacks" badge on Live Ops shows how callbacks were handled (owner / fallback / voicemail) in the last hour and flags SLA breaches (GET /api/admin/diagnostics/callbacks-waiting). The Warm Callback banner shows a "Covering — originally the owner's prospect" note on fallback calls.
  • Auto-configure on assignment — assigning a DID (manual or auto-distribute) now points its Twilio Voice webhook at the inbound handler automatically; no manual "Configure for Warm Transfer" step. 11/11 E2E invariants.

v7.6.0 — May 29, 2026 — SDR Dedicated DIDs (Phases 1–3)

  • Every rep gets their own callback number. Map Twilio DIDs 1:1 to SDRs so a prospect calling back lands on the exact rep who dialed them, with full CRM context.
  • Phase 1 — assignment engine — new SdrDidAssignment model (partial unique index enforces one active assignment per number); assign / unassign / list APIs + auto-distribute (sticky round-robin, lead-weighted, geographic) with dry-run preview and a "need more DIDs" SystemAlert. Fixed the P0 compile blocker (query referenced 4 fields that don't exist in the schema). 13/13 invariants.
  • Phase 2 — Admin console — new /dashboard/admin/sdr-dids page (stats, DID-shortage banner, Auto-Distribute preview → apply, assignments table, SDR roster, Assign dialog) + overview API + Sync Twilio Numbers importer to pull your existing Twilio inventory into the assignable pool.
  • Phase 3 — Inbound recognition + Warm Callback — the inbound webhook routes a callback on a dedicated DID to the assigned rep's browser (conference) when online, else voicemail + a missed-callback ping. The SDR Desktop shows a Warm Callback banner — "calling back X · last dialed by Y on Z" + prior disposition/notes — with one-tap "Resume — use last notes." Usage tracked per assignment. 9/9 E2E HTTP invariants.
  • Did not touch the tuned WebRTC / TWILIO_ONLY_MODE / power-dial race logic — Phase 3 adds an inbound branch + an additive SDR banner only.

v7.5.31 — May 19, 2026 — Docs Sync & Version Bump (Consolidates v7.5.25 → v7.5.30)

  • Pure documentation release — no source-code changes. All 7 release surfaces (version.ts, docs/CHANGELOG.md, memory/CHANGELOG.md, memory/PRD.md, memory/ROADMAP.md, README.md, public/user-guide.html) brought back into lockstep on v7.5.31. yarn release --check ✅ GREEN.
  • README "What's New" body had stuck at v7.5.24; PRD title at v7.5.25; in-app /docs header at v7.5.25 — all fixed.

v7.5.30 — May 19, 2026 — "Best Ratio?" Data-Backed Hint + Provider-Agnostic Connect Toast

  • NEW UIRatioInsightHint.tsx surfaces a tiny analytics pill under the SDR ratio picker with a one-click APPLY when a clear historical winner exists. Renders 4 states: brand-new campaigns (nothing), <100 dials (progress bar), no clear winner (muted text), clear winner (amber pill + click-to-expand bar chart).
  • NEW BACKENDGET /api/warm-transfer/campaigns/[id]/ratio-analytics: CTE-backed SQL joining POWER_DIAL_STARTED events with WarmTransferLead.powerDialGroupId, grouped by ratio. Recommendation gated on total ≥100 dialed, ≥2 ratios with ≥20 samples each, winner > next-best by ≥3 pp. Tie-break: lower ratio wins.
  • UX — Telephony connect toast made provider-agnostic. "Phone connected via Telnyx" → "Your phone is now connected, you can make and receive calls".

v7.5.29 — May 19, 2026 — Sticky preferredDialRatio per Campaign

  • NEW — Reps lock a default 1x–5x ratio per campaign (Enterprise discovery = 1x, SMB outbound = 3x). Auto-applies on campaign select; debounced (800ms) save on ratio change. Dot indicator on the ratio button matching the saved default.
  • SCHEMAWarmTransferCampaign.preferredDialRatio Int? (nullable 1–5). Migration applied additively to live DB.
  • BACKENDPATCH /api/warm-transfer/campaigns/[id] accepts preferredDialRatio in body. 400 on invalid (outside 1–5).

v7.5.28 — May 19, 2026 — Power Dial 2-Row Layout + BC Clerk Reskin

  • FIX (UX) — 3x / 4x / 5x ratio buttons were unclickable because the Power Dial control row overflowed the 300–340px campaigns column. Redesigned into 2 rows: ROW 1 = primary action (Power Dial / Stop / icon-only Force Hangup), ROW 2 = labeled "RATIO" grid-cols-5 grid that always fits the column. Every ratio button now clickable at any panel width.
  • NEWaria-pressed + aria-label on every ratio button; primary action truncates with ellipsis on collapse.
  • BC BRANDING — Full beyondcalls.ai reskin of Clerk via <ClerkProvider appearance={...}>. BC logo, brand red (#B31942) primary, dark navy surface, Open Sans typography across sign-in / sign-up / UserButton / UserProfile.

v7.5.27 — May 19, 2026 — Recent Disconnects Pill (SDR Self-Diagnostic)

  • NEW UI — "Recent disconnects" pill in the SDR header surfaces the last 3 phone-bridge drops in 24h. Reps self-diagnose flaky wifi vs. browser tab-throttling without raising a ticket. Click opens popover with reason, hint, device state, and call state at the time of the drop. Escalating advisories: 2+ drops → "switch network", 3+ → "restart browser before next shift".
  • NEW BACKENDPOST/GET /api/warm-transfer/agent/device-disconnect logs structured events with a reason whitelist. Piggybacks on existing WarmTransferEvent table — zero new schema.

v7.5.26 — May 18, 2026 — Silent Power Dialer Stall Fix (P0, Reported by Live SDR)

  • FIX (critical) — "Power dialing automatically stopped" with no clear reason. Root cause: silent Twilio WebRTC device disconnect → power-dial churned through 10 "No agents" retries (~70s exponential backoff) before stopping with an easily-missed toast. Twilio account, Telnyx account, and 60/40 load balancer were all verified healthy at the time — purely a UX/state-coordination bug.
  • INSTANT HALT — Auto-dial stops the moment isAvailable flips false. No more 70-second silent retry storm.
  • VISIBLE OFFLINE BANNER — Persistent in-UI banner above the SDR Desktop main pane fires whenever isAvailable=false while a campaign is selected and dialer is IDLE. One-click Go Available button restores availability.
  • CLEARER STOP TOASTS — All terminal Power Dialer stop toasts now persistent (duration: Infinity) with manual Dismiss action and explicit root-cause language.

v7.5.25 — Feb 14, 2026 — Multi-Phone Per Lead + CSV Upload Validation

  • NEW — Each lead can carry up to 3 phone numbers (primary + 2 alts). On non-success dispositions (NA / BUSY / VM / WN / NTRP / NLW / NI / LHU) the disposition route promotes the next alt to phone and queues it for the next batch. Success / callback / DNC stop the chain. DNC propagates across ALL known numbers per lead.
  • CSV UPLOAD — Accepts Phone / Phone 2 / Phone 3 AND Mobile / Office / Home / Direct conventions. E.164 + NANP validation per phone. Inline failures editor lets the SDR fix bad rows and re-upload as JSON.
  • SCHEMAWarmTransferLead.alternatePhones String? (JSON array, capped at 2 alts) + WarmTransferLead.triedPhones String? (audit trail). Both nullable, additive.

v7.5.24 — May 13, 2026 — Channel Limits Aligned with Actual 5 CPS Carrier Plans

  • INFRA SAFETY — Channel limits in cloudbuild.yaml reduced (Twilio 15→5, Telnyx 10→5) to match the actual 5 CPS carrier plans. Prevents 30443 / D1 90041 / 429 rate-limit errors.
  • AUDIT — DID inventory, Programmable Voice, AMD, Strategy-tab gap analysis delivered alongside (see PRD v7.5.24).

v7.5.23 — May 13, 2026 — Telephony Load Balancer: 60/40 Twilio/Telnyx Target-Split (Production-Enabled)

  • NEWTELEPHONY_TARGET_SPLIT env var (e.g. twilio=60,telnyx=40) gives a stable, predictable carrier mix regardless of momentary in-flight counts. 10,000-dial simulation: 60.5% Twilio / 39.5% Telnyx, 0.47% drift from target.
  • ENABLED IN PRODUCTION_TELEPHONY_LOAD_BALANCE flipped false → true in cloudbuild.yaml. Backward-compatible: when TELEPHONY_TARGET_SPLIT is unset, behavior falls back to legacy free-slot weighting (v7.5.8).
  • SAFETY — AMD & latency untouched (per-call provider config). Capacity-safe (0-free-slots excluded, both-saturated → least-loaded). Sticky retry + US-only DIAL_ALLOWED_REGIONS intact. Fully reversible via _TELEPHONY_LOAD_BALANCE='false'.
  • DID RECOMMENDATION — At 4 Twilio DIDs vs 12 Telnyx, the 60% Twilio share concentrates frequency. ≤5 SDRs: fine. 5-10 SDRs: purchase 6-8 more Twilio DIDs. 20+ SDRs: scale to 20+ Twilio DIDs and renegotiate CPS limit.

v7.5.22 — May 13, 2026 — "Find a Recording by Phone" Diagnostic Tool

  • NEW/dashboard/admin/dial-errors now has a "Find a recording by phone" tool. Paste any phone format → get a definitive answer to "does this recording exist anywhere?"
  • ENDPOINTPOST /api/admin/recordings/find-by-phone { phone, sinceDays? }. Queries Twilio Calls API, Telnyx Recordings + Call APIs, and the local DB independently.
  • VERDICTFOUND / CALLS_EXIST_NO_RECORDING / NO_CALLS with per-provider breakdown and a Play button on every recording (via the existing /api/v2/recordings/stream proxy).
  • SAFETY — Telnyx call-leg lookups concurrency-pooled at 5 to stay under rate limits. Reuses phoneMatchVariants, getOrCreateTeamMember, Clerk auth(). No new deps.

v7.5.21 — May 13, 2026 — Telnyx Recordings Were Invisible (Three Compounding Bugs)

  • P0 SYMPTOM — Telnyx recordings (the now-default carrier for many leads after sticky-carrier v7.5.10) never appeared on /dashboard/recordings via any search.
  • RCA — three compounding bugs in src/app/api/v2/recordings/route.ts:
    1. Single-provider gate — auto-sync + Sync Now pulled from only ONE carrier via getActiveProvider(). Sticky-carrier-per-lead routes through both → half the recordings invisible.
    2. Denorm missingsyncTelnyxRecordings set only FKs, never the display columns the list UI reads (leadName/leadPhone/company/agentName/campaignName/disposition).
    3. No phone fallback — when warmTransferEvent.callSid lookup missed, orphans stayed orphan with leadPhone=null → v7.5.20 re-linker couldn't help.
  • FIX — (1) Both sync paths pull from BOTH providers in parallel (Promise.allSettled). (2) syncTelnyxRecordings joins to lead + agent and denormalizes the full display columns. (3) Strategy-2 fallback queries Telnyx Call API for to/from and matches via phoneMatchVariants when Strategy 1 misses. Persists leadPhone even when no match so the v7.5.20 re-linker can pick it up later.
  • RECOVERY — Deploy → /dashboard/recordings → Sync Now → search by name / company / any phone format. Optional: re-link orphans on /dashboard/admin/dial-errors.

v7.5.20 — May 13, 2026 — One-Click Orphan Recording Re-linker (Admin Tool)

  • NEW/dashboard/admin/dial-errors now has an Admin Tools card with Preview (dry run) + Re-link orphan recordings buttons. Backfills CallRecording rows that were persisted with leadId=null by the pre-v7.5.19 strict-equality phone match.
  • ENDPOINTPOST /api/admin/recordings/relink-orphans?dryRun={true|false}&limit=N.
  • SAFETY — Org-scoped · idempotent (only scans leadId IS NULL) · conservative (skips ambiguous multi-lead phones — never guesses) · atomic batches via prisma.$transaction · disposition-safe (manual dispositions never overwritten) · bounded (5k rows/run, max 20k via ?limit=).
  • TECH-DEBT AVOIDANCE — Reuses phoneMatchVariants, getOrCreateTeamMember, Prisma, Clerk auth(), existing Card/Badge/toast primitives. No new helpers, no new dependencies.

v7.5.19 — May 13, 2026 — Recordings Lost to Phone-Format Mismatch

  • P0 — Real human-conversation recordings were syncing into the DB but surfacing as unknown lead on /dashboard/recordings, unfindable by name / company / phone search. Reported example: meeting booked with Stephen Silveira / Aptus Court Reporting / (619) 546-9151.
  • RCAsrc/app/api/v2/recordings/route.ts matched the Twilio call.to E.164 (+16195469151) against WarmTransferLead.phone with strict string equality. CSV leads stored as (619) 546-9151 failed to join → row persisted with leadId/leadName/company = null. Search by name "Silveira" or company "Aptus" then never hit it. The search filter on leadPhone used contains:, which also didn't bridge raw-digit ↔ formatted forms.
  • FIX — All three lookups (syncTwilioRecordings, syncCallRecordings's phoneToLead index, and the ?search= filter) now use phoneMatchVariants(). Any of 6195469151 / (619) 546-9151 / +16195469151 / +1 619 546 9151 hits the same row.
  • RECOVERY/dashboard/recordingsSync Now → search by name, company, or any phone format. Or open the lead in /dashboard/sdr360 Report → recordings tab (lookup by leadId directly).

v7.5.18 — May 13, 2026 — Disposition Window Auto-Skip Fix (Power Dialer Was Racing the SDR)

  • P0 — Power-dial call ends → DispositionForm opens → SDR starts typing notes / opens Schedule Meeting → 30s later the form vanishes and the Power Dialer fires the next batch. No disposition saved, no meeting logged.
  • ROOT CAUSE — Hard-coded 30s setTimeout in the WRAP_UP useEffect (src/app/dashboard/sdr/page.tsx) called resetCall() unconditionally → callState=IDLE → usePowerDialer [callState] resume effect fired the next batch 1500ms later.
  • FIX #1 — WRAP_UP idle window bumped 30s → 5min.
  • FIX #2 — Idle timer now resets on every SDR interaction with the form: disposition click, notes keystroke, callback date, meeting form toggle, every meeting field, action item add/toggle. Implemented via a wrapUpActivityToken state + an onActivity prop wired into every interactive control.
  • FIX #3 — DispositionForm shows a "Power Dialer paused — take your time to set disposition & schedule a meeting" pill when Power Dial is active.
  • NOTE — Meeting scheduling (title / datetime / attendee / duration / notes → POST /api/warm-transfer/dispositionMeeting model + .ics download) was already wired end-to-end. This fix simply makes sure the SDR has time to use it.

v7.5.17 — May 12, 2026 — Inbound Visibility + CRM Self-Heal + Clickable Version

  • NEW PAGE/dashboard/inbound-calls hub. Every incoming call with caller phone, DID it landed on, matched lead, handler (SDR/AI), status, duration, inline recording playback, AI summary, full transcript, and a "Callback Requested" badge. Stats cards and filters. Linked from sidebar under Telephony → Inbound Calls.
  • NEW UI — Direction-aware INCOMING screen. Inbound = PURPLE-themed pulsing hero with ↓ Inbound Call banner, Calling from: <phone> label, "Landed on: your DID" tag. Outbound = green-themed ↑ Outbound Transfer with Connecting to: <phone>. Unmatched callers show amber "Unknown Caller" + "No matching lead".
  • NEW UI — Sidebar version (v7.5.17 ↗) is now a clickable link to /docs#changelog — review the issues fixed in your build with one click.
  • P0 — Phone-normalized lead lookup. "Unknown caller" was firing for leads that EXIST in the DB because phone formats didn't match exactly. New phoneMatchVariants() generates 4-6 plausible formats (E.164, 10-digit, formatted) and OR-matches them.
  • P0 — SDR self-heal effect. Whenever activeLead is in the "unknown-<phone>" fallback state, frontend auto-calls /api/leads/lookup-by-phone and upgrades within ~200ms.
  • NEWGET /api/leads/lookup-by-phone, GET /api/inbound-calls. AMD human-confirmed Pusher events enriched with leadPhone/Email/Title.

v7.5.16 — May 12, 2026 — CRM Persistence + Inbound/Outbound Badge + Audio Diag

  • P0 — Power Dial sibling voicemail events no longer kill the WINNER call. v7.5.7 guard required callState === CONNECTED, but sibling Pusher events arrive during the 200-800ms INCOMING window before SDR auto-accept. New guard uses powerDialFeedRef to identify any in-batch sibling and ignore its events while state is non-IDLE.
  • P0 — CRM panel ALWAYS populated when a call connects. Previously setActiveLead was gated by if (transferData.leadId). Inbound-to-DID + outbound transfers without enriched leadId left CRM blank. Now falls back to { id: 'unknown-<phone>', name: 'Unknown caller', phone: from }.
  • P0 — "SDR not connected" mid-batch — heartbeat staleness check raised from 45s to 120s. Chrome throttles setInterval during heavy WebRTC, letting the 5s heartbeat drift. Frontend now also fires a pre-batch heartbeat right before each power-dial trigger.
  • P0 — Telnyx double-recording — every call produced 2 rows in /dashboard/recordings. Account-level "Record All Calls" on Telnyx + Conference TwiML record="record-from-start" both fired the recording-status webhook with different recordingSids. Fix: gated conference recording behind TELNYX_USE_CONFERENCE_RECORDING env (default OFF). Defense-in-depth: recording-status webhook detects same-(leadId,callSid) duplicates within 5min and keeps only the longer one.
  • NEW UI — INBOUND vs OUTBOUND badge in Active Call header (purple ↓ vs emerald ↑).
  • NEW UI — LEAD PREVIEW fallback panel showing caller phone + direction + "no matching lead" hint when no DB match.
  • NEW — Outbound WebRTC audio-track diagnostic at call.on('accept')/api/diagnostics/audio-stateWarmTransferEvent. RCA-able offline.
  • NEW PAGE/dashboard/admin/dial-errors. Twilio code badges, time/provider filters, expandable rows.
  • IMPROVED — Power-dial backoff (2s → 30s) on ALL batch failures + auto-stop after 5 consecutive fails. Telnyx HTTP 403 detection broadened. DIAL_ALLOWED_REGIONS env filter (default 1 = US/Canada).

v7.5.15 — May 11, 2026 — US-Only Region Filter + Dial Error RCA Page

  • NEWDIAL_ALLOWED_REGIONS env var (default 1 = US/Canada/NANP only). Non-allowed leads are pre-filtered at lead-selection and bulk-marked CONFIG_ERROR so they stop cycling back every batch. Use * to disable, or 1,44,61 for US+UK+AU.
  • NEW PAGE/dashboard/admin/dial-errors for telephony RCA. Reads LOG_ERROR_* rows from WarmTransferEvent with Twilio-code badges (D1=red, auth=red, TwiML=amber).
  • IMPROVED — Power-dial frontend exponential backoff on ANY dial failure (not just "No agents"). 5 consecutive fails → auto-stop with hint to admin/dial-errors.
  • IMPROVED — Telnyx 403 detection broadened. Any 403 / "country not allowed" / "outbound voice profile" marks lead CONFIG_ERROR and clears lastDialedProvider sticky-pref.

v7.5.14 — May 11, 2026 — Documentation Backfill + Version Sync

  • Pure docs release — zero source code changes. Resolves drift across 3 documentation surfaces.
  • docs/CHANGELOG.md — Renamed the mislabeled v7.5.2 block (its body actually described the AMD False-Positive fix) → v7.5.3. Inserted 8 missing 7.x entries: v7.5.7, v7.5.1, v7.0.6, v7.0.5, v7.0.4, v7.0.3, v7.0.2. Now continuous from v7.5.13 → v7.0.0. Count: 47 → 55.
  • src/app/docs/page.tsx (this page) — Was stuck at v7.3.8. Added 17 <h3> blocks (v7.5.13 → v7.5.0, v7.4.1, v7.4.0, v7.3.9, v7.0.6, v7.0.5) plus this v7.5.14 entry.
  • README.md — Title and version badge bumped (were stuck at 7.5.2 while "What's New" body had been updated to v7.5.13).
  • Auditnode scripts/release.js --check now validates 7 surfaces and confirms entry-count parity. All GREEN.
  • Verifiedyarn type-check GREEN, regression 16/16 (no source changes).

v7.5.13 — April 21, 2026 — Duplicate Recording Fix (CRITICAL)

  • CRITICAL: Duplicate Recording Fix — Every call was producing TWO recording entries playing back as overlapped audio. Both dial routes set conferenceRecord: 'record-from-start' on participant create AND immediately called conferences(sid).update({ record: true }) — Twilio happily started a SECOND recording. Removed the redundant trigger in dial/route.ts, power-dial/route.ts, and neutered startConferenceRecording() in the AMD callback.
  • LOGGING — Added [AMD/AgentDial] conf=X agent=Y provider=Z line on every agent-into-conference dial. Grep Cloud Run logs for [AMD/AgentDial] to diagnose any future audio mismatch in seconds.

v7.5.12 — April 21, 2026 — One-Way Audio + Missing Recordings (P0 CRITICAL)

  • Symptom — SDR saw "call connected", REC indicator and timer running, but NO voice from the prospect's end. Recordings later showed the call but audio was empty.
  • Root causeamd-callback/route.ts used the GLOBAL getActiveProvider() when adding the agent to the conference and controlling recording. After v7.5.8 (load balancer) + v7.5.10 (sticky carrier) introduced per-lead provider variance, the prospect could be in a Telnyx conference while the agent was added to a Twilio conference of the same name — two separate conferences on two different switches.
  • FixdialAgentIntoConference() and startConferenceRecording() now accept an explicit provider parameter. AMD callback reads lead.lastDialedProvider (v7.5.10 column) at all 5 call sites. Three-layer fallback: lastDialedProvidercustomData.dialProvider → global. Agent ALWAYS joins the SAME provider conference the prospect is in.
  • iPhone VM redirectcalls(callSid).update({ twiml }) now also uses the per-lead provider so the SDK targets the correct switch.

v7.5.11 — April 21, 2026 — Permanent Build-Failure Prevention

  • CRITICAL BUILD FIX — Cloud Build bd6ecd2d-... failed with TS7016 "Could not find a declaration file for module 'uuid'". Root cause: uuid was being imported but neither uuid nor @types/uuid was in package.json — resolving transitively at runtime but with no type declarations.
  • FIX — Replaced import { v4 as uuidv4 } from 'uuid' with import { randomUUID } from 'crypto' (Node 20 native). Removes the dep entirely — no future @types breakage possible.
  • PERMANENT GUARD — New scripts/check-untyped-imports.js walks every static import in src/, verifies each module is either a Node built-in, declared in package.json with type declarations, or has its own .d.ts. Runs in ~0.3s.
  • PIPELINE — Added prebuild script — yarn build now runs check-imports && type-check BEFORE next build. Cloud Build fails fast at the import-check stage (~0.3s) instead of 30+s into Turbopack. Husky pre-push hook updated to run both checks.

v7.5.10 — April 21, 2026 — Sticky Carrier per Lead

  • NEW: Per-Lead Sticky Carrier — Added lastDialedProvider column to WarmTransferLead. Every successful dial stamps the carrier that placed it; retries reuse it via preferProvider, preserving per-destination answer-rate reputation each carrier has built.
  • WIRED — Single dial reads lead.lastDialedProvider and passes it as sticky-pref to selectProviderForCall. Power Dial computes majority lastDialedProvider across the batch and passes it as sticky-pref.
  • WRITE-SIDE — All 4 success paths (Retell, native Twilio/Telnyx, Twilio failover for D1) stamp lastDialedProvider on success.
  • MIGRATIONprisma/migrations/20260421000001_add_last_dialed_provider/ — nullable column + optional index. Zero-downtime (NULL = no sticky preference).

v7.5.9 — April 21, 2026 — SDR Refactor: Dead Code Out, Shared Constants In

  • REFACTOR (P2) — Deleted 4 stale SDR component shells (CampaignPanel, CallControlBar, LeadPanel, DispositionPanel) that were never wired into production. Documented as safe in docs/SDR_COMPONENT_STATUS.md.
  • SHARED CONSTANTSDISPOSITION_OPTIONS + DispositionOption type promoted to src/lib/dispositions.tsx — survives future UI cleanups, now consumable by analytics / coaching surfaces.
  • NEW EXTRACTIONSMSInbox component extracted from sdr/page.tsx (88 LOC, pure presentational, props-driven, no Pusher closure traps).
  • HEALTH/api/health/regression returns 16/16 GREEN.

v7.5.8 — April 21, 2026 — Twilio/Telnyx Load Balancer + Husky Pre-Push Gate

  • NEW: Telephony Load Balancer — Weighted-random Twilio ↔ Telnyx split based on live free-slot capacity. Default OFF for safety (TELEPHONY_LOAD_BALANCE=false). Flip to true to enable.
  • APIselectProviderForCall(options?) picks weighted by (limit - active). Optional preferProvider for sticky retries. 5s in-memory snapshot cache. Falls back to least-loaded when both are at capacity.
  • TELEMETRYGET /api/telephony/load-balancer returns live capacity, enabled flag, and a 100-pick sample distribution.
  • BUILD SAFETY — Installed husky + cross-env. New yarn type-check runs tsc --noEmit --skipLibCheck. .husky/pre-push blocks pushes that don't type-check.

v7.5.7 — April 21, 2026 — CRM Panel Persistence in Power Dial 3x (P0 CRITICAL)

  • Recurring across forks — SDRs reported the CRM/Lead-Intel panel going blank the moment a Power Dial 3x lead became human and connected. Bug had been "fixed" twice before and kept returning.
  • Root cause — In Power Dial 3x, when one lead becomes human and the SDR connects, the OTHER 2 leads fire voicemail-detected Pusher events. The handler was unconditionally running setActiveLead(null), callManager.resetCall(), and warmTransfer.clearTransfer() on the WINNER lead. Compounded by stale closures — useEffect deps were [teamMemberId, isAvailable], so handler captured stale activeLead + callState at bind time.
  • Fix — Added activeLeadRef + callStateRef to mirror current state. Handler bails out if data.leadId !== activeLeadRef.current?.id while callStateRef.current === 'CONNECTED'. clearActiveLead() rewired to read from refs. handleStopPowerDial uses the safe setter.

v7.5.6 — April 21, 2026 — Cloud Build Unblocked (power-dial Syntax Fix)

  • CRITICAL BUILD FIX — Cloud Build 6638d078-... failed with Turbopack Expression expected at power-dial/route.ts:684. Root cause: an unclosed else { ... } block in the D13 country-whitelist handler tried to close two scopes with a single }. Brace-depth instrumentation confirmed depth went 3 → 2 on one brace where two were required.
  • Fix — Rewrote D13 handler as early-return pattern (push to failedLeads, return null, no else). Brace/paren counts now balanced (218/218, 224/224).

v7.5.5 — April 21, 2026 — Telnyx Recording Playback / Download Fix (CRITICAL)

  • Symptom — Every recording in /dashboard/recordings showed "Recording unavailable". Audio player onError fired; downloads produced HTML/JSON error bodies. 772+ Telnyx recordings affected.
  • Root causerecordings/stream/route.ts was attaching Authorization: Bearer ${TELNYX_API_KEY} when fetching audio. Telnyx returns download_urls.mp3 as an AWS S3 presigned URL, and S3 rejects any extra auth header with HTTP 400 InvalidRequest: Only one auth mechanism allowed.
  • Fix — Drop the Bearer header on the S3 fetch. Telnyx metadata fetch still uses Bearer. Verified end-to-end: HTTP 200, 25,388 bytes, first 4 bytes ID3 (valid MP3).

v7.5.4 — April 20, 2026 — Critical Production Fixes: AMD, Recordings, Telnyx D13

  • AMD False-Positive "Rings Twice" — Power Dial 3x calls would ring twice then disconnect. ZERO-DELAY logic connected agent on carrier "in-progress" (early media) instead of waiting for AMD human confirmation. Disabled premature agent connection — agent now connects EXCLUSIVELY after AMD confirms human. 1-3s connection delay (acceptable tradeoff).
  • Recording Download Fix — Download button was returning CSV/HTML instead of .mp3. Added getToken() Clerk auth + credentials on all recording requests + blob type validation.
  • Telnyx D13 Country Whitelist Handling — Cryptic "Dial error 403" now auto-detected; leads marked CONFIG_ERROR, system alert created with actionable admin instructions.
  • Recording System Nuclear Fix — Retry with exponential backoff (2 retries), extended timeout (60s), provider-specific error messages, blob validation. New GET /api/v2/recordings/health.
  • Follow-ups — Admin/Manager default to "All" scope. lastDIDUsed in API. Banner when viewing "Mine" with 0 results.

v7.5.3 — April 19, 2026 — AMD False-Positive + Ops Escape Hatches + Capacity

  • AI Call-Analysis Persistent Cache — Added aiAnalysis Json?, aiAnalyzedAt, aiAnalyzedBy to CallRecording. Restored cache in GET/POST /api/call-analysis.
  • ProblematicNumber Tracking — New model tracks phones whose carriers trigger AMD false positives via misleading early-media. Auto-flagged after 3 incidents.
  • AMD False-Positive Auto-Correctcompleted webhook with duration<5s on a "connected" lead and answeredBy != 'human' overrides to no_answer instead of preserving stale connected.
  • Force Hangup + Reconcile Stuck LeadsPOST /api/warm-transfer/force-hangup (per-lead emergency hangup) + POST /api/warm-transfer/reconcile-stuck-leads (org-scoped bulk reset of leads stuck >2min).
  • Telnyx→Twilio Per-Lead Failover — Power Dial detects Telnyx D1/90041 channel-limit errors mid-batch and transparently retries via Twilio.
  • Provider Capacity WidgetGET /api/telephony/capacity + new ProviderCapacityWidget UI with live utilization %.
  • Cloud Build Regression Gate — Post-deploy step hits /api/health/regression; build fails if not green.

v7.5.2 — April 19, 2026 — Regression Audit + Failover + Regression API

  • Regression Audit (Issues #2–#14) — Full regression sweep of all 13+ user-reported issues across v7.0.7 → v7.3.9. Each fix verified via grep + source inspection. ALL CONFIRMED RESOLVED.
  • NEW: GET /api/health/regression — 16 source-level checks against the 13 resolved issues + 3 UX regressions + 1 audio-regression guard. Returns JSON with pass/fail per check.
  • NEW: Admin → Regression Health Page/dashboard/admin/regression one-click audit with badges, file:line evidence, re-run button.
  • NEW: Automatic Provider Failover (Telnyx ↔ Twilio) — Dial route wraps attempts in a failover loop. If primary fails (e.g., 20003 auth, network), fallback is tried after TELEPHONY_FAILOVER_DELAY_MS.
  • Build-Breaking Bugs Fixedcall-analysis route Python-only import, CallRecording.customData reference, prisma.callEvent nonexistent model, providerSidproviderId, supervisor page c.idc.campaignId, regression API Turbopack over-bundling.

v7.5.1 — April 19, 2026 — Supervisor Call History + SDR Page Decomposition

  • Supervisor Call History Tab — Full call log with filters by agent / campaign / disposition / date range, pagination, color-coded disposition badges.
  • Export to CSV — Download call history for reporting and external analysis.
  • SDR Page Decomposition — Extracted CampaignPanel, CallControlBar, LeadPanel, DispositionPanel into src/app/dashboard/sdr/components/*.

v7.5.0 — April 19, 2026 — Per-Campaign Provider + DID Purchase UI + Automatic Failover

  • Per-Campaign Provider Selection — Choose Twilio or Telnyx per campaign. Provider badge (orange / green) on campaign cards.
  • DID Purchase UI — Search and buy phone numbers from both Twilio and Telnyx in one place. POST /api/phone-numbers/search, POST /api/phone-numbers/buy.
  • Automatic Failover InfrastructuredialWithFailover() function added for provider redundancy.
  • Schema — Added telephonyProvider field to WarmTransferCampaign.

v7.4.1 — April 19, 2026 — Dual-Provider Restoration (Twilio + Telnyx)

  • DUAL-PROVIDER — Restored full Twilio + Telnyx side-by-side support. Provider selection respects explicit TELEPHONY_PROVIDER env var even when both are configured.
  • Phone Numbers API — Returns DIDs from BOTH Twilio and Telnyx with provider labels.
  • Telephony Status API — Tests connectivity to both providers, reports active / available.
  • Recordings UI — Provider badges (orange / green) on each recording row.
  • HelpersisProviderAvailable(), getAvailableProviders() for multi-provider support.

v7.4.0 — April 18, 2026 — Recording Availability Fix for Twilio Suspension

  • Twilio Account Suspension Handling — Twilio recordings now show clear "Twilio (Suspended)" status instead of cryptic errors.
  • Recordings Banner — Explains Twilio suspension and shows count of unavailable vs. available recordings.
  • Provider Detection — AudioPlayer visually distinguishes Twilio (red/disabled) from Telnyx (green/playable).
  • Stream API — Returns clear error for suspended Twilio recordings with provider info. Download button disabled with tooltip.

v7.3.9 — February 21, 2026 — Critical Call + DID Dropdown + SDR Visibility Fixes

  • CRITICAL: One-Way Audio for Telnyx WebRTC — Added a remote audio element so prospect audio now plays.
  • CRITICAL: Phone Numbers Dropdown — Now fetches Telnyx DIDs from the API (was showing stale Twilio numbers).
  • FIX: Disposition-in-2-seconds — Deferred activeCall until the call genuinely reaches active state.
  • FIX: Outbound call failure — Returns to IDLE instead of showing disposition.
  • FIX: SDR Campaign Visibility — All org campaigns now visible to all SDRs.

v7.3.8 — February 20, 2026 — Production Deployment Fixes + DID Analytics

  • CRITICAL: Cloud Run Telnyx Env Vars — Added all 10 Telnyx env vars to cloudbuild.yaml. Previously Cloud Run had zero Telnyx credentials, routing all calls to suspended Twilio.
  • CRITICAL: Provider DetectiongetActiveProvider() now unconditionally prefers Telnyx when any Telnyx credential exists. Prevents accidental Twilio routing.
  • FIX: Build Error — Resolved Cannot find name getProviderClient in recordings enrich route.
  • FIX: SDR Dial — Guarded call.on() for Telnyx (Call objects don't support .on). Provider-aware call ID extraction.
  • FIX: WebRTC Stability — Socket close debounced 6s. Auto-reconnect with 30s cooldown. Old client cleanup before reconnect.
  • NEW: Phone Numbers Telnyx Support — API fetches from Telnyx API with env var fallback. UI shows Telnyx tab with green badges and A-attestation.
  • NEW: Health Monitor v7.3.8checkTelephony() replaces checkTwilio(). Shows Telnyx DID count and SIP status.
  • NEW: DID Analytics — Disposition events store DID used. SDR dashboard shows per-DID call counts. DID column in dispositions tab.
  • IMPROVED: Token Route — Telnyx fallback when Twilio creds missing. Diagnostic logging for Cloud Run debugging.

v7.3.0 — April 16, 2026 — Full Telnyx Migration + Telephony Abstraction

  • NEW: Full Telnyx Migration — 30+ files converted from Twilio. All dial, power-dial, DID, recording, AMD, WebRTC paths now route through Telnyx.
  • NEW: Provider AbstractionIVoiceProvider interface with Twilio + Telnyx implementations. Switch via TELEPHONY_PROVIDER env var.
  • NEW: Telnyx TeXML Dial — Prospect + agent calls via TeXML API. Conference join, recording, AMD all via TwiML-compatible markup.
  • NEW: AMD Parity — Aggressive AMD params preserved: speechThreshold=1200, speechEndThreshold=500, silenceTimeout=2000, timeout=30s.
  • NEW: useTelephonyDevice — Provider-agnostic WebRTC hook. Supports @twilio/voice-sdk and @telnyx/webrtc.
  • NEW: 12 Telnyx DIDs — All assigned to TeXML App "ASOC Mission Control" with production webhook.
  • NEW: Complete DID Management — Search, bulk purchase, recording sync all via Telnyx API.
  • NEW: Status API/api/telephony/status shows active provider, health, balance, number count.
  • IMPROVED: Dial + Power-Dial — Both routes support Telnyx and Twilio paths. Zero-delay pre-connect preserved.
  • PRESERVED — Conference recording, Smart DID rotation, STIR/SHAKEN A-attestation (native on Telnyx).

v7.2.1 — April 15, 2026 — Legal/Compliance Pages + GDPR Cookie Consent

  • NEW: 7 Legal Pages — Privacy Policy (/privacy), Terms & Conditions (/terms), EULA (/eula), Cookie Policy (/cookies), Opt-Out & Data Deletion (/opt-out), AI & Automation Policy (/ai-policy), Compliance Center (/compliance).
  • NEW: GDPR Cookie Consent Banner — Accept All, Essential Only, Customize (Functional/Analytics toggles). localStorage persistence with version tracking.
  • NEW: Opt-Out Form — Interactive request form for DNC, data access, data deletion, recording deletion, AI opt-out.
  • NEW: Compliance Center — 6 regulation cards (TCPA, GDPR, CCPA, STIR/SHAKEN, CAN-SPAM, TSR) + regional compliance table (US, EU, UK, Canada, Australia, India).
  • IMPROVED: Footer — "Legal & Compliance" section with links to all 7 legal pages.

v7.2.0 — April 13, 2026 — Production Hardening + DID Infrastructure + CRM

  • NEW: DID Purchase UI — Buy DIDs by city ($1.15/number/month) with cost confirmation. POST /api/twilio/dids/purchase.
  • NEW: Smart DID Rotation — Region-based caller ID (same state → neighbor → lowest volume). 50-call daily limit per DID.
  • NEW: SDR Dedicated DID — 1:1 DID per SDR for inbound/outbound. Admin assignment via Team page.
  • NEW: CRM Lead 360 Report — Full prospect view with call history, recordings, meetings, CSV export. GET /api/crm/lead-report.
  • NEW: SDR Personal Dashboard/dashboard/sdr-analytics with stats, dispositions, recordings, meetings, date filters, CSV.
  • NEW: System Alerts Module — 9 health checks, sidebar badge, cron API. GET /api/cron?task=health-check.
  • INFRA: AMD Validation GuardvalidateAMDParams() clamps to safe min/max. Prevents outages.
  • INFRA: Disposition Refactor — Shared telephony-utils.ts for status mapping, error codes.
  • INFRA: SDR Page Decomposition — 3,041 → 2,830 lines (6 extracted components).
  • FIX: 1x Dial Recording — Re-enabled record-from-answer-dual for manual outbound calls.
  • FIX: 1x Dial Disposition — WRAP_UP transition now reliable.

v7.1.2 — April 13, 2026 — CRITICAL: AMD Parameter Fix + Recording Fix

  • CRITICAL: AMD speechEndThreshold — 400→500ms (below 500ms minimum blocked ALL dials).
  • NEW: System Alerts Dashboard/dashboard/alerts with 6 health checks, ack/resolve, severity filtering.
  • NEW: Lead Edit/Delete — Inline editing and deletion in campaign lead list.
  • NEW: Campaign Soft Delete — Preserves all data. Restore via modal.
  • NEW: In-Call DTMF Dialpad — Keypad for IVR navigation during active calls.
  • FIX: Triple-Redundancy Recording — conferenceRecord + REST API + webhook.
  • FIX: Dashboard Counters — callsHandledToday incremented, Connected excludes VM/DNC/DND.

v7.1.0 — April 13, 2026 — Scale Readiness + DID Reputation + AMD Tuning

  • NEW: Scale Dashboard/dashboard/twilio-scale with real-time STIR/SHAKEN attestation, CPS monitoring, concurrent call tracking, DID pool health, agent capacity, and automated scale recommendations.
  • NEW: DID Reputation Scoring — Per-DID scores (0-100), grades A-F, trend detection (improving/declining/stable), auto-flagging below threshold, configurable time ranges (7d/14d/30d).
  • NEW: Auto-Rotate DIDs — Bulk deactivation of flagged DIDs from active pool. Safety guard keeps min 2 active. Manual per-DID deactivation available.
  • NEW: Scale Readiness APIGET /api/twilio/scale-readiness returns account CPS, Trust Hub, concurrent calls, dial stats, recommendations.
  • NEW: DID Reputation APIGET /api/twilio/did-reputation + POST for auto-rotate/deactivate.
  • FIX: DNC Disposition Bug — SDR can now hang up and see disposition form without dialer auto-advancing. Root cause: WRAP_UP race condition in disconnect useEffect.
  • FIX: AMD Voicemail Detection — Tightened parameters: speechThreshold 2400→2000ms, speechEndThreshold 1200→800ms, silenceTimeout 5000→3500ms.

v7.0.8 — April 10, 2026 — Deployment Fix + Recording Enrichment

  • FIX: Cloud Build CLERK_SECRET_KEY — Combined bash step clears stale secret bindings before deploy.
  • NEW: Recording EnrichmentPOST /api/v2/recordings/enrich maps orphaned recordings to leads.
  • NEW: Real-time Recording Webhook — DB insertion on recording-status callback.

v7.0.7 — April 9, 2026 — Call Recordings + CSV Export

  • NEW: Call Recordings System — Auto-sync from provider, full pagination (10K), 3-strategy lead matching, CSV export.
  • NEW: CSV Export on Call Logs — Export up to 10K events.
  • IMPROVED: Campaign Analytics — Restart archives historical counters.

v7.0.6 — April 10, 2026 — Audio Fix + Disposition + Follow-ups + Dedicated DIDs

  • FIX: Manual Dial "All Agents Busy" — TwiML App Voice URL was misconfigured to the inbound webhook. Repointed to /api/twilio/voice via Twilio REST API.
  • FIX: One-Way Audio (Prospect Cannot Hear SDR) — Switched ALL conference joins to client.conferences(name).participants.create(). Eliminates TwiML parent→child call bridge that was losing browser audio.
  • FIX: Recording Audio Dropout — Removed record: 'record-from-ringing-dual' from voice and inbound-call routes.
  • FIX: Disposition Popup — Always appears post-call (auto-LHU-submit removed).
  • FIX: Callback Date — Now persisted via dedicated picker on CB/FUP dispositions (WarmTransferLead.callbackDate).
  • FIX: Notes Auto-BleedingcallNotes + callbackDate cleared on every new call.
  • FIX: CB/FUP Leads — Status set to callback_scheduled (excluded from auto-dialer).
  • NEW: Follow-ups & Meetings Page (/dashboard/followups) — list, calendar, analytics views.
  • NEW: Dedicated Inbound DID per SDR — Assignable from profile page. Rings the SDR's browser directly when online; AI receptionist + miss notification when offline.

v7.0.5 — April 9, 2026 — Nuclear Telephony Fix: Persistent Ringing + Recording

  • CRITICAL: Persistent Ringing — Root cause: Pusher incoming-transfer arrived 200-800ms before the Twilio WebRTC call reached the browser. The old 100ms auto-accept timer fired when twilio.incomingCall was still null, falling through to makeCall() which created a SECOND outbound call while the original kept ringing forever.
  • Fix — Auto-accept now triggers from the twilio.incomingCall useEffect (when the call ACTUALLY arrives). makeCall fallback removed. Polling (10 × 200ms) replaces the blind 1000ms wait. Three-layer auto-accept (Pusher confirm + INCOMING state safety net + handleAnswer polling).
  • CRITICAL: Recording Not Workingrecord="record-from-start" had been silently removed from Conference TwiML in v6.2.5. Restored on the PROSPECT's Conference TwiML in both single and power-dial routes (NOT on agent TwiML — prevents dual-stream audio).

v7.0.4 — April 9, 2026 — Campaign-Aware DID Pools + SDR Launch Guide

  • FIX: SDR Desktop DID Dropdown — Previously showed only global/env numbers (4 DIDs). Now dynamically loads DIDs from the campaign's assigned phone pool when an SDR selects a campaign. Falls back to global numbers when no pool is assigned.
  • FIX: Single Dial Pool RoutingPOST /api/warm-transfer/dial now checks the campaign's didPoolIds and uses pool numbers (matching power-dial behavior). Previously only used global active DIDs.
  • IMPROVED: DID Count Badge — SDR Desktop header shows the number of available DIDs and indicates when using a campaign pool.
  • NEW: Campaign Launch Guide — Step-by-step guide in User Guide covering the full workflow: Create Pool → Create Campaign → Upload Leads → Context → Assign SDR → Activate → Dial.
  • DOCS: Phone Pools Section — New comprehensive section in User Guide covering pool creation, campaign assignment, and DID rotation behavior.

v7.0.3 — April 9, 2026 — AI Context Summarization + Docs Update

  • NEW: AI Context Summarization — Paste sales docs, GPT-4o extracts top 5 icebreakers + pain points. New POST /api/warm-transfer/campaigns/[id]/summarize-context endpoint.
  • NEW: AI Insights Tab — Third tab in Campaign Context Editor shows elevator pitch, numbered icebreakers, and pain point cards.
  • IMPROVED: Copilot Icebreakers — AI-extracted talking points now prioritized over collateral-based icebreakers during live calls. Cap expanded from 6 to 8.
  • NEW: contextSummary Field — Persisted on campaign schema. AI summary survives refresh and auto-feeds into copilot.
  • DOCS: Global Update — Version bump across README, /docs, user guide, release notes, roadmap, and changelog.

v7.0.2 — April 8, 2026 — Phase 1 Production Readiness Audit

  • CRITICAL FIX: Clerk Auth Middlewareproxy.ts had broken export pattern causing auth() to return null on all API routes. Fixed with standard export default clerkMiddleware(). This resolved the "Unauthorized" error when saving Apollo/ZoomInfo API keys.
  • CRITICAL FIX: Recording Bug Prevention — Removed record: options.recordingEnabled from twilio-client.ts:createOutboundCall() to prevent v6.2.4 one-way audio regression.
  • NEW: Comprehensive Health EndpointGET /api/health returns granular status for Telnyx, Retell AI, Pusher, DB, Email, AI, Active Agents + scale configuration.
  • FIX: Hardcoded GCP URLs — Removed stale fallback URLs from power-dial and amd-callback routes. Now fails fast on missing NEXT_PUBLIC_APP_URL.
  • Phase 1 Audit — Full 7-point production readiness verification for 10 SDRs / 1,000 calls per day. All checks passed.

v7.0.0 — April 2, 2026 — Email Outbound System + Campaign Wizard

  • NEW: 8-Step Email Campaign Wizard — Setup → Leads → Template → Collateral → Generate → Review → Mailbox → Launch
  • NEW: AI Intelligence Engine v2 — GPT-4o bulk email generation with 5 tones, template injection, campaign brief context
  • NEW: AI Sequence Optimizer — GPT-4o analysis with prioritized recommendations and predicted uplift
  • NEW: Sequence Template Loader — Load existing sequences in wizard Step 3
  • NEW: Campaign Briefs — Upload PRDs, whitepapers for AI grounding at /dashboard/campaign-briefs
  • NEW: Apollo Lead Enrichment — Batch enrichment up to 25 leads per request
  • NEW: CSV Lead Upload — Smart column parsing with deduplication
  • NEW: Email Analytics Dashboard — Open/Click/Reply/Bounce rates, campaign comparison
  • NEW: 4-Provider Email Config — Resend, SendGrid, Gmail OAuth, SMTP
  • FIXED: SMTP SSL detection — Port 587 → STARTTLS, Port 465 → SSL
  • FIXED: Gmail OAuth redirect URI — Properly validated after server restart

v6.2.5 — March 29, 2026 — Prod Logging + Scale Readiness

  • FIX: Voicemail disposition screen — Voicemails no longer show the disposition screen to SDRs. Root cause: incoming-transfer sent humanDetected: true before AMD ran. Fix: added amdPending flag and human-confirmed Pusher event to gate WRAP_UP behind AMD confirmation.
  • FIX: Prospect hangup didn't end agent call — Prospect conference leg had endConferenceOnExit="false". Changed to "true" in both dial/route.ts and power-dial/route.ts. Hangup now ends both calls.
  • FIX: Slow return to dialing — LHU (Lead Hung Up) auto-submits disposition in 1.5s and returns SDR to IDLE immediately. No more 30s WRAP_UP timeout blocking the dialer.
  • AMD callback — All 4 human-detected paths (single + power, pre-connect + fallback) now send human-confirmed Pusher event
  • SDR pageamdConfirmedRef gates disconnect → WRAP_UP. autoDispositionRef auto-submits LHU.

v6.2.0 — March 29, 2026 — Zero-Delay Conference Pre-Connect (Nuclear Audio Fix)

  • NUCLEAR FIX — Eliminated 8-10s dead air on warm transfers. Prospect was saying "Hello?" into an empty conference because agent call was deferred to AMD callback (3-8s after pickup).
  • Single Dial — Agent + prospect calls fire simultaneously via Promise.allSettled() — 0s dead air
  • Power Dial — Agent call created on first in-progress event (fires before AMD) with atomic group claiming
  • Omnichannel placeholders — WhatsApp, Email, SMS "Coming Soon" cards on Warm Transfer page
  • Disposition display fixes — Color mapping, human-readable names, badges on lead cards and activity feed

v6.1.0 — March 28, 2026 — Live Agent Testing: Browser WebRTC + Phone

  • NEW: Browser Mic Test — Talk to AI agents via WebRTC in your browser. Real-time transcript with agent/user bubbles, mute, duration timer.
  • NEW: Phone Call Test — AI agent calls your phone number for production-accurate testing.
  • NEW: Live Test Panel — Expand/collapse panel with call status indicators, accessible from Agents page and Flow Builder.
  • Power Dial 1x — Sequential one-at-a-time dialing through the power dial engine for high-value prospects.

v6.0.0 — March 27, 2026 — Hybrid Transfer Architecture

  • ARCHITECTURE REWRITE — Replaced Conference-based transfers with direct <Dial><Client> for sub-2s latency and zero audio crackling (2 media hops instead of 3)
  • NEW: dial-complete webhook/api/webhooks/warm-transfer/dial-complete for direct-dial call lifecycle management
  • NEW: escalate-conference webhook/api/webhooks/warm-transfer/escalate-conference for on-demand supervisor access
  • Supervisor auto-escalation — Monitor API auto-creates conference when supervisor clicks listen/barge on a direct-dial call
  • SDR LHU auto-detect — Prospect hangup is auto-detected for Lead Hung Up disposition
  • Persistent ringing fix — Ringtone properly stops on disconnect and WRAP_UP timeout
  • Zero-latency webhooks — Next.js after() returns responses in <250ms across all transfer webhooks
  • Version lock.version-lock file prevents future forks from regressing below v6.0.0

v5.20.0 — March 24, 2026

  • AI-Powered Email Content Generation — GPT-4o generates personalized emails from lead context, writing style, and sequence config
  • Email Open Tracking — Invisible 1x1 pixel, real-time OPENED events, auto-updates step/enrollment counters
  • Email Click Tracking — All links wrapped with tracking redirects, CLICKED events with URL attribution
  • Retell AI Conversation Replay — Transcript + audio playback + sentiment analysis modal
  • Centralized Event Logger — Unified error logging across all v2 APIs
  • Critical Audio Fix — Removed forced edge:ashburn from Device SDK, removed destructive endCall() after redirect, parallelized transfer for sub-2s handoff
  • AMD Fixunknown now treated as human (was incorrectly classified as voicemail)
  • +229 SIP Trunk Fixed — Proper SIP Domain and trunk configuration for Retell custom numbers

v5.19.0 — March 23, 2026

  • Nuclear Audio Fix — Removed region="us1" and record="record-from-start" from all 13 Conference TwiML points

v5.18.0 — March 23, 2026

  • Email Sequence Engine — Multi-channel sequence builder with 5 step types
  • Sales Collateral Library — CRUD with AI-targeting metadata and performance tracking
  • Email Account Configuration — SMTP, Resend, Gmail OAuth with testing
  • Sequence Processor Engine — Automated enrollment processing with personalization
  • Sequence Analytics Dashboard — Conversion funnel and per-step metrics