<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Moisi Trungu</title>
    <description>The latest articles on DEV Community by Moisi Trungu (@moisi_trungu_31647b7ac300).</description>
    <link>https://dev.to/moisi_trungu_31647b7ac300</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F2016431%2Fe664cdc4-b987-4a9a-a206-4875fba0b376.png</url>
      <title>DEV Community: Moisi Trungu</title>
      <link>https://dev.to/moisi_trungu_31647b7ac300</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/moisi_trungu_31647b7ac300"/>
    <language>en</language>
    <item>
      <title>How to Set Up ViciDial DID Routing — Inbound Number Configuration</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Sun, 16 Aug 2026 03:30:03 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/how-to-set-up-vicidial-did-routing-inbound-number-configuration-2gkd</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/how-to-set-up-vicidial-did-routing-inbound-number-configuration-2gkd</guid>
      <description>&lt;h1&gt;
  
  
  How to Set Up ViciDial DID Routing — Inbound Number Configuration
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master complete inbound DID routing configuration in ViciDial, from carrier integration through call distribution to agents, with production-ready examples and troubleshooting strategies.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin this tutorial, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ViciDial installation&lt;/strong&gt;: Running 2.14+ (tested on 2.14.0.1 and later)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asterisk server&lt;/strong&gt;: Version 13+ with chan_sip or PJSIP installed&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database access&lt;/strong&gt;: MySQL/MariaDB with vicidial user credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Root or sudo access&lt;/strong&gt;: Required for Asterisk configuration modifications&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIP carrier account&lt;/strong&gt;: Active account with inbound call capability&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ViciDial admin panel access&lt;/strong&gt;: Web interface at &lt;code&gt;http://your-server/vicidial/admin.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SSH/terminal access&lt;/strong&gt;: To the ViciDial server for CLI operations&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic ViciDial knowledge&lt;/strong&gt;: Familiarity with campaigns, user accounts, and call disposition codes&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding ViciDial DID Routing Architecture
&lt;/h2&gt;

&lt;p&gt;DID (Direct Inward Dialing) routing in ViciDial connects incoming calls from your carrier through Asterisk dialplan logic, into ViciDial's inbound call queue system, and finally to available agents or IVR systems.&lt;/p&gt;

&lt;p&gt;The routing chain flows like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;SIP Carrier → Asterisk (sip-vicidial.conf) → 
Extensions Dialplan (extensions-vicidial.conf) → 
ViciDial Inbound Groups → Call Queue → Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Each DID number must be mapped to:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;An Asterisk context for initial routing&lt;/li&gt;
&lt;li&gt;A ViciDial inbound group&lt;/li&gt;
&lt;li&gt;Queue settings (agents, call recording, etc.)&lt;/li&gt;
&lt;li&gt;Agent assignment strategy (round-robin, longest-idle, etc.)&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Prerequisites Continued: Database Tables
&lt;/h2&gt;

&lt;p&gt;The following ViciDial database tables are critical for DID routing:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Table&lt;/th&gt;
&lt;th&gt;Purpose&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vicidial_inbound_groups&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Defines inbound call groups (queues)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vicidial_users&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Agent accounts and inbound group assignments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vicidial_phone_codes&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;DID to inbound group mapping&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vicidial_carrier_log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Inbound call detail records&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;vicidial_log&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Agent interaction logs&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Step 1: Configure Your SIP Carrier Connection
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1.1 Add Carrier to ViciDial Database
&lt;/h3&gt;

&lt;p&gt;First, register your SIP carrier in the carrier configuration. Log into MySQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Query existing carriers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_carriers&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Insert a new carrier (e.g., VoIP.ms):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_carriers&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_inbound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_outbound&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="n"&gt;inbound_cid&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'VOIPMS'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'VoIP.ms'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SIP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Primary SIP carrier'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Exit MySQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;EXIT&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.2 Configure SIP Trunk in sip-vicidial.conf
&lt;/h3&gt;

&lt;p&gt;Edit the SIP configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/asterisk/sip-vicidial.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add or modify your carrier SIP peer configuration. Example for VoIP.ms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;; &lt;span class="n"&gt;VoIP&lt;/span&gt;.&lt;span class="n"&gt;ms&lt;/span&gt; &lt;span class="n"&gt;SIP&lt;/span&gt; &lt;span class="n"&gt;Trunk&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt;
[&lt;span class="n"&gt;voipms&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="n"&gt;toronto1&lt;/span&gt;.&lt;span class="n"&gt;voip&lt;/span&gt;.&lt;span class="n"&gt;ms&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt;=&lt;span class="n"&gt;account_number&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt;=&lt;span class="n"&gt;your_sip_password&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;your_sip_password&lt;/span&gt;
&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;account_number&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="n"&gt;toronto1&lt;/span&gt;.&lt;span class="n"&gt;voip&lt;/span&gt;.&lt;span class="n"&gt;ms&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;voipms&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;span class="n"&gt;dtmfmode&lt;/span&gt;=&lt;span class="n"&gt;rfc2833&lt;/span&gt;
&lt;span class="n"&gt;canreinvite&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;maxcallbitrate&lt;/span&gt;=&lt;span class="m"&gt;128000&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;,&lt;span class="n"&gt;alaw&lt;/span&gt;
&lt;span class="n"&gt;description&lt;/span&gt;=&lt;span class="n"&gt;VoIP&lt;/span&gt;.&lt;span class="n"&gt;ms&lt;/span&gt; &lt;span class="n"&gt;Inbound&lt;/span&gt; &lt;span class="n"&gt;Trunk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For a local SIP PBX or test environment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;localsip&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="m"&gt;192&lt;/span&gt;.&lt;span class="m"&gt;168&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;100&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt;=&lt;span class="n"&gt;vicidial&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt;=&lt;span class="n"&gt;your_password&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;your_password&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;local&lt;/span&gt;-&lt;span class="n"&gt;pbx&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  1.3 Test Carrier Connection
&lt;/h3&gt;

&lt;p&gt;Reload Asterisk SIP configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the peer is registered:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see your carrier peer listed with status "OK (x ms)".&lt;/p&gt;

&lt;p&gt;Check registration if using registration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show registry"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Create Inbound Groups in ViciDial
&lt;/h2&gt;

&lt;p&gt;Inbound groups are the core container for call distribution in ViciDial. Every inbound DID must belong to an inbound group.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.1 Access the Admin Panel
&lt;/h3&gt;

&lt;p&gt;Navigate to:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;http://your-vicidial-server/vicidial/admin.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log in with your admin credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.2 Create Inbound Group via Admin
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Click &lt;strong&gt;Inbound&lt;/strong&gt; → &lt;strong&gt;Inbound Groups&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;ADD NEW INBOUND GROUP&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the following fields:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example Value&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Inbound Group Name&lt;/td&gt;
&lt;td&gt;Sales_Queue_001&lt;/td&gt;
&lt;td&gt;Unique identifier&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Inbound Group ID&lt;/td&gt;
&lt;td&gt;sales_001&lt;/td&gt;
&lt;td&gt;System-wide unique ID&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Active&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Enable the group&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Calls in Queue Limit&lt;/td&gt;
&lt;td&gt;100&lt;/td&gt;
&lt;td&gt;Max queued calls before rejection&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Greeting Recording&lt;/td&gt;
&lt;td&gt;sales_greeting.wav&lt;/td&gt;
&lt;td&gt;IVR greeting file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Hold Recording&lt;/td&gt;
&lt;td&gt;hold_music.wav&lt;/td&gt;
&lt;td&gt;Music on hold file&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Voicemail Recording&lt;/td&gt;
&lt;td&gt;voicemail.wav&lt;/td&gt;
&lt;td&gt;Voicemail greeting&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CID Group&lt;/td&gt;
&lt;td&gt;EXTERNAL&lt;/td&gt;
&lt;td&gt;Caller ID group for ANI capture&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Call Recording&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Record all inbound calls&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Web Form Recording&lt;/td&gt;
&lt;td&gt;N&lt;/td&gt;
&lt;td&gt;Skip web form integration&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Default Group&lt;/td&gt;
&lt;td&gt;Y&lt;/td&gt;
&lt;td&gt;Primary routing group&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;p&gt;Click &lt;strong&gt;SUBMIT&lt;/strong&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  2.3 Create via Direct Database Insertion
&lt;/h3&gt;

&lt;p&gt;Alternatively, insert directly into the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_inbound_groups&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inbound_group_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inbound_group_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calls_in_queue_limit&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="n"&gt;greeting_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hold_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;voicemail_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cid_group_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_recording&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="n"&gt;web_form_address&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;web_form_recording&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;default_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;park_extension&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="n"&gt;park_timeout&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Sales_Queue_001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'EXTERNAL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'N'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'6900'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1800&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify creation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;inbound_group_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inbound_group_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_inbound_groups&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 3: Assign Agents to Inbound Groups
&lt;/h2&gt;

&lt;p&gt;Agents must be explicitly assigned to inbound groups before they can receive inbound calls.&lt;/p&gt;

&lt;h3&gt;
  
  
  3.1 Assign via Admin Panel
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Admin&lt;/strong&gt; → &lt;strong&gt;Users&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click on an agent's username&lt;/li&gt;
&lt;li&gt;Under &lt;strong&gt;Inbound Settings&lt;/strong&gt;, select the inbound group from the dropdown&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Agent Type&lt;/strong&gt; to "INBOUND" or "BOTH"&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;SUBMIT&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  3.2 Assign via Database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;user_level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify assignment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3.3 Set Agent Availability
&lt;/h3&gt;

&lt;p&gt;Agents must be logged in and in "READY" state to receive calls. This is handled via the agent interface at &lt;code&gt;/agc/vicidial.php&lt;/code&gt;, but you can verify availability:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"queue show sales_001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This command shows all agents in the queue and their status.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Map DIDs to Inbound Groups
&lt;/h2&gt;

&lt;p&gt;DIDs are mapped to inbound groups using the &lt;code&gt;vicidial_phone_codes&lt;/code&gt; table. Each DID number can route to a specific inbound group.&lt;/p&gt;

&lt;h3&gt;
  
  
  4.1 Insert DID-to-Group Mapping
&lt;/h3&gt;

&lt;p&gt;Map a DID number to your inbound group:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_phone_codes&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phone_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_code_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2015550123'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Sales DID Main'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'INGROUP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="s1"&gt;'Primary sales inbound DID'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For multiple DIDs to the same group:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_phone_codes&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phone_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_code_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2015550123'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Sales DID 1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'INGROUP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Sales line'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2015550124'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Sales DID 2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'INGROUP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Sales line'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'2015550125'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Sales DID 3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'INGROUP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Sales line'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify mapping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;phone_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_phone_codes&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;phone_code&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4.2 Configure via Admin Panel (Optional)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Inbound&lt;/strong&gt; → &lt;strong&gt;Phone Codes&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;ADD NEW PHONE CODE&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Enter your DID number in &lt;strong&gt;Phone Code&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Select your inbound group from the dropdown&lt;/li&gt;
&lt;li&gt;Set &lt;strong&gt;Call Type&lt;/strong&gt; to "INGROUP"&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;SUBMIT&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 5: Configure Asterisk Dialplan Extensions
&lt;/h2&gt;

&lt;p&gt;The Asterisk dialplan bridges the gap between the SIP carrier context and ViciDial's inbound group system.&lt;/p&gt;

&lt;h3&gt;
  
  
  5.1 Create Carrier Context in extensions-vicidial.conf
&lt;/h3&gt;

&lt;p&gt;Edit the main extensions file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;nano /etc/asterisk/extensions-vicidial.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add a context for your carrier. This example routes from VoIP.ms:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;voipms&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Inbound&lt;/span&gt; &lt;span class="n"&gt;DID&lt;/span&gt;: ${&lt;span class="n"&gt;EXTEN&lt;/span&gt;} &lt;span class="n"&gt;from&lt;/span&gt; ${&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;num&lt;/span&gt;)})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;num&lt;/span&gt;)=${&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;num&lt;/span&gt;)})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;name&lt;/span&gt;)=${&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;name&lt;/span&gt;)})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;TO_VICIDIAL&lt;/span&gt;=${&lt;span class="n"&gt;EXTEN&lt;/span&gt;})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Gosub&lt;/span&gt;(&lt;span class="n"&gt;route&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;,${&lt;span class="n"&gt;EXTEN&lt;/span&gt;},&lt;span class="m"&gt;1&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()

&lt;span class="n"&gt;include&lt;/span&gt; =&amp;gt; &lt;span class="n"&gt;parked&lt;/span&gt;-&lt;span class="n"&gt;calls&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.2 Create ViciDial Routing Subroutine
&lt;/h3&gt;

&lt;p&gt;Add the main ViciDial routing subroutine in the same file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;route&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(=== &lt;span class="n"&gt;ViciDial&lt;/span&gt; &lt;span class="n"&gt;Routing&lt;/span&gt; &lt;span class="n"&gt;Subroutine&lt;/span&gt; ===)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Received&lt;/span&gt; &lt;span class="n"&gt;DID&lt;/span&gt;: ${&lt;span class="n"&gt;ARG1&lt;/span&gt;})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;DID_NUMBER&lt;/span&gt;=${&lt;span class="n"&gt;ARG1&lt;/span&gt;})

; &lt;span class="n"&gt;Query&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;inbound&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;ODBC_Query&lt;/span&gt;(&lt;span class="n"&gt;vicidial&lt;/span&gt;,&lt;span class="n"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt; &lt;span class="n"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_phone_codes&lt;/span&gt; &lt;span class="n"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone_code&lt;/span&gt;=&lt;span class="s1"&gt;'${DID_NUMBER}'&lt;/span&gt;,&lt;span class="n"&gt;result&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;INBOUND_GROUP&lt;/span&gt;=${&lt;span class="n"&gt;result&lt;/span&gt;})

; &lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="n"&gt;based&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;inbound&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;GotoIf&lt;/span&gt;($[${&lt;span class="n"&gt;LEN&lt;/span&gt;(${&lt;span class="n"&gt;INBOUND_GROUP&lt;/span&gt;})} &amp;gt; &lt;span class="m"&gt;0&lt;/span&gt;]?&lt;span class="n"&gt;found&lt;/span&gt;:&lt;span class="n"&gt;notfound&lt;/span&gt;)

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;(&lt;span class="n"&gt;found&lt;/span&gt;),&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Found&lt;/span&gt; &lt;span class="n"&gt;inbound&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;: ${&lt;span class="n"&gt;INBOUND_GROUP&lt;/span&gt;})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;CHANNEL&lt;/span&gt;(&lt;span class="n"&gt;language&lt;/span&gt;)=&lt;span class="n"&gt;en&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Gosub&lt;/span&gt;(&lt;span class="n"&gt;queue&lt;/span&gt;-&lt;span class="n"&gt;call&lt;/span&gt;,${&lt;span class="n"&gt;INBOUND_GROUP&lt;/span&gt;},&lt;span class="m"&gt;1&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Return&lt;/span&gt;()

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;(&lt;span class="n"&gt;notfound&lt;/span&gt;),&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;No&lt;/span&gt; &lt;span class="n"&gt;inbound&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt; &lt;span class="n"&gt;found&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;DID&lt;/span&gt;: ${&lt;span class="n"&gt;DID_NUMBER&lt;/span&gt;})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Playback&lt;/span&gt;(&lt;span class="n"&gt;sorry&lt;/span&gt;-&lt;span class="n"&gt;youve&lt;/span&gt;-&lt;span class="n"&gt;dialed&lt;/span&gt;-&lt;span class="n"&gt;a&lt;/span&gt;-&lt;span class="n"&gt;wrong&lt;/span&gt;-&lt;span class="n"&gt;number&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()

[&lt;span class="n"&gt;queue&lt;/span&gt;-&lt;span class="n"&gt;call&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(=== &lt;span class="n"&gt;Entering&lt;/span&gt; &lt;span class="n"&gt;Queue&lt;/span&gt;: ${&lt;span class="n"&gt;ARG1&lt;/span&gt;} ===)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;VICIDIAL_INBOUND_GROUP&lt;/span&gt;=${&lt;span class="n"&gt;ARG1&lt;/span&gt;})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;CALL_RECORDING&lt;/span&gt;=&lt;span class="n"&gt;Y&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;UNIQUEID&lt;/span&gt;=${&lt;span class="n"&gt;UNIQUEID&lt;/span&gt;()})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Queue&lt;/span&gt;(${&lt;span class="n"&gt;ARG1&lt;/span&gt;},&lt;span class="n"&gt;t&lt;/span&gt;,,&lt;span class="m"&gt;180&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.3 Alternative: Direct Queue Entry (Simplified)
&lt;/h3&gt;

&lt;p&gt;For simpler configurations without database lookups:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;voipms&lt;/span&gt;]
; &lt;span class="n"&gt;Route&lt;/span&gt; &lt;span class="n"&gt;specific&lt;/span&gt; &lt;span class="n"&gt;DIDs&lt;/span&gt; &lt;span class="n"&gt;directly&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;queues&lt;/span&gt;
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Sales&lt;/span&gt; &lt;span class="n"&gt;DID&lt;/span&gt; &lt;span class="n"&gt;received&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;VICIDIAL_INBOUND_GROUP&lt;/span&gt;=&lt;span class="n"&gt;sales_001&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Queue&lt;/span&gt;(&lt;span class="n"&gt;sales_001&lt;/span&gt;,&lt;span class="n"&gt;t&lt;/span&gt;,,&lt;span class="m"&gt;180&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550124&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Support&lt;/span&gt; &lt;span class="n"&gt;DID&lt;/span&gt; &lt;span class="n"&gt;received&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550124&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;VICIDIAL_INBOUND_GROUP&lt;/span&gt;=&lt;span class="n"&gt;support_001&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550124&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Queue&lt;/span&gt;(&lt;span class="n"&gt;support_001&lt;/span&gt;,&lt;span class="n"&gt;t&lt;/span&gt;,,&lt;span class="m"&gt;180&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550124&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550125&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Billing&lt;/span&gt; &lt;span class="n"&gt;DID&lt;/span&gt; &lt;span class="n"&gt;received&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550125&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;VICIDIAL_INBOUND_GROUP&lt;/span&gt;=&lt;span class="n"&gt;billing_001&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550125&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Queue&lt;/span&gt;(&lt;span class="n"&gt;billing_001&lt;/span&gt;,&lt;span class="n"&gt;t&lt;/span&gt;,,&lt;span class="m"&gt;180&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550125&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5.4 Reload Dialplan
&lt;/h3&gt;

&lt;p&gt;Apply the changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the dialplan loaded correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan show from-voipms"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 6: Configure Queue Parameters in ViciDial
&lt;/h2&gt;

&lt;p&gt;Queue settings control call distribution behavior in your inbound groups.&lt;/p&gt;

&lt;h3&gt;
  
  
  6.1 Queue Strategy Settings
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/asterisk/queues.conf&lt;/code&gt; or add to extensions context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;sales_001&lt;/span&gt;]
&lt;span class="n"&gt;music&lt;/span&gt; = &lt;span class="n"&gt;default&lt;/span&gt;
&lt;span class="n"&gt;strategy&lt;/span&gt; = &lt;span class="n"&gt;rrmemory&lt;/span&gt;
&lt;span class="n"&gt;timeout&lt;/span&gt; = &lt;span class="m"&gt;180&lt;/span&gt;
&lt;span class="n"&gt;announce&lt;/span&gt; = &lt;span class="n"&gt;queue&lt;/span&gt;-&lt;span class="n"&gt;announce&lt;/span&gt;
&lt;span class="n"&gt;announce&lt;/span&gt;-&lt;span class="n"&gt;frequency&lt;/span&gt; = &lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;announce&lt;/span&gt;-&lt;span class="n"&gt;holdtime&lt;/span&gt; = &lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;joinempty&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;leavewhenempty&lt;/span&gt; = &lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;ringall&lt;/span&gt; = &lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;maxlen&lt;/span&gt; = &lt;span class="m"&gt;50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Queue Strategy Explanations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;rrmemory&lt;/code&gt;: Round-robin with memory (preferred for balanced distribution)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;linear&lt;/code&gt;: Sequential agent order&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fewest&lt;/code&gt;: Route to agent with fewest calls&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;leastrecent&lt;/code&gt;: Route to agent idle longest&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  6.2 Create Queue via ViciDial Admin
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Queues&lt;/strong&gt; or queue settings in &lt;strong&gt;Inbound Groups&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Set:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Ring Strategy&lt;/strong&gt;: Round-robin with memory&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ring All Agents&lt;/strong&gt;: No (ring one at a time)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max Queue Size&lt;/strong&gt;: 100&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Wait Timeout&lt;/strong&gt;: 180 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent Ring Timeout&lt;/strong&gt;: 20 seconds (time before moving to next agent)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  6.3 Verify Queue Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"queue show sales_001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;sales_001
      Members:
         Local/agent001@from-internal (dynamic)
         Local/agent002@from-internal (dynamic)
      Callers:
         1. &amp;lt;Anonymous&amp;gt; (wait: 45:23, pos: 1)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 7: Configure ViciDial Logging and Recording
&lt;/h2&gt;

&lt;h3&gt;
  
  
  7.1 Enable Call Recording
&lt;/h3&gt;

&lt;p&gt;Ensure recordings are enabled at both group and system level.&lt;/p&gt;

&lt;p&gt;In &lt;code&gt;vicidial_inbound_groups&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_inbound_groups&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;call_recording&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;record_calls&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.2 Configure Recording Storage
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/asterisk/modules.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;modules&lt;/span&gt;]
&lt;span class="n"&gt;autoload&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;require&lt;/span&gt;=&lt;span class="n"&gt;res_odbc&lt;/span&gt;.&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="n"&gt;require&lt;/span&gt;=&lt;span class="n"&gt;chan_sip&lt;/span&gt;.&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="n"&gt;require&lt;/span&gt;=&lt;span class="n"&gt;app_queue&lt;/span&gt;.&lt;span class="n"&gt;so&lt;/span&gt;
&lt;span class="n"&gt;require&lt;/span&gt;=&lt;span class="n"&gt;app_mixmonitor&lt;/span&gt;.&lt;span class="n"&gt;so&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recordings are typically stored in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/var/spool/asterisk/monitor/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  7.3 Verify Recording Directories
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /var/spool/asterisk/monitor/ | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure ViciDial daemon has write permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; asterisk:asterisk /var/spool/asterisk/monitor/
&lt;span class="nb"&gt;sudo chmod &lt;/span&gt;755 /var/spool/asterisk/monitor/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 8: Test the Complete DID Routing
&lt;/h2&gt;

&lt;h3&gt;
  
  
  8.1 Prepare Test Environment
&lt;/h3&gt;

&lt;p&gt;Ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;At least one agent is logged into &lt;code&gt;/agc/vicidial.php&lt;/code&gt; in READY state&lt;/li&gt;
&lt;li&gt;Agent is assigned to &lt;code&gt;sales_001&lt;/code&gt; inbound group&lt;/li&gt;
&lt;li&gt;Your DID carrier is sending calls properly&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  8.2 Perform Inbound Test Call
&lt;/h3&gt;

&lt;p&gt;Call your DID number from an external phone.&lt;/p&gt;

&lt;p&gt;Monitor call in Asterisk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show channels"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Channel              State   App      Data
SIP/voipms-xxxxx     Up      Queue    (sales_001,t,,180)
Local/agent001@xxx   Up      AppQueue ()
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  8.3 Check ViciDial Agent Screen
&lt;/h3&gt;

&lt;p&gt;The agent's screen at &lt;code&gt;/agc/vicidial.php&lt;/code&gt; should show the incoming call.&lt;/p&gt;

&lt;h3&gt;
  
  
  8.4 Verify Call Logging
&lt;/h3&gt;

&lt;p&gt;Check the call was logged to database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caller_id_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caller_id_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;called_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="n"&gt;duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dispo&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_carrier_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;called_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2015550123'&lt;/span&gt; 
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Also check ViciDial logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caller_id_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dispo&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;talk_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;hold_time&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt; 
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 9: Implement Advanced Routing Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  9.1 Time-Based Routing (Business Hours)
&lt;/h3&gt;

&lt;p&gt;Route to different groups based on time of day:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;voipms&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;DID&lt;/span&gt; &lt;span class="n"&gt;received&lt;/span&gt;: ${&lt;span class="n"&gt;EXTEN&lt;/span&gt;})

; &lt;span class="n"&gt;Check&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="n"&gt;business&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; (&lt;span class="m"&gt;9&lt;/span&gt; &lt;span class="n"&gt;AM&lt;/span&gt; - &lt;span class="m"&gt;5&lt;/span&gt; &lt;span class="n"&gt;PM&lt;/span&gt;, &lt;span class="n"&gt;Mon&lt;/span&gt;-&lt;span class="n"&gt;Fri&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;GotoIf&lt;/span&gt;($[${&lt;span class="n"&gt;IF&lt;/span&gt;($[${&lt;span class="n"&gt;EPOCH&lt;/span&gt;} &amp;gt; ${&lt;span class="n"&gt;STRFTIME&lt;/span&gt;(${&lt;span class="n"&gt;EPOCH&lt;/span&gt;},&lt;span class="m"&gt;2024&lt;/span&gt;-&lt;span class="m"&gt;01&lt;/span&gt;-&lt;span class="m"&gt;01&lt;/span&gt; &lt;span class="m"&gt;17&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;:&lt;span class="m"&gt;00&lt;/span&gt;,%&lt;span class="n"&gt;s&lt;/span&gt;)}]?&lt;span class="m"&gt;1&lt;/span&gt;:&lt;span class="m"&gt;0&lt;/span&gt;)} = &lt;span class="m"&gt;1&lt;/span&gt;]?&lt;span class="n"&gt;afterhours&lt;/span&gt;:&lt;span class="n"&gt;business&lt;/span&gt;)

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;(&lt;span class="n"&gt;business&lt;/span&gt;),&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Routing&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;business&lt;/span&gt; &lt;span class="n"&gt;hours&lt;/span&gt; &lt;span class="n"&gt;group&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Queue&lt;/span&gt;(&lt;span class="n"&gt;sales_001&lt;/span&gt;,&lt;span class="n"&gt;t&lt;/span&gt;,,&lt;span class="m"&gt;180&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;(&lt;span class="n"&gt;afterhours&lt;/span&gt;),&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Routing&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;voicemail&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;VoiceMail&lt;/span&gt;(${&lt;span class="n"&gt;EXTEN&lt;/span&gt;}@&lt;span class="n"&gt;sales_voicemail&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.2 Skill-Based Routing
&lt;/h3&gt;

&lt;p&gt;Route to different groups based on call type/IVR selection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;voipms&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Sales&lt;/span&gt; &lt;span class="n"&gt;main&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;SKILL_GROUP&lt;/span&gt;=&lt;span class="n"&gt;sales_general&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;IVR&lt;/span&gt;(&lt;span class="n"&gt;select&lt;/span&gt;-&lt;span class="n"&gt;department&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Queue&lt;/span&gt;(${&lt;span class="n"&gt;SKILL_GROUP&lt;/span&gt;},&lt;span class="n"&gt;t&lt;/span&gt;,,&lt;span class="m"&gt;180&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()

; &lt;span class="n"&gt;IVR&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;department&lt;/span&gt; &lt;span class="n"&gt;selection&lt;/span&gt;
[&lt;span class="n"&gt;select&lt;/span&gt;-&lt;span class="n"&gt;department&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Selected&lt;/span&gt;: &lt;span class="n"&gt;Billing&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;SKILL_GROUP&lt;/span&gt;=&lt;span class="n"&gt;billing_001&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Return&lt;/span&gt;()

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Selected&lt;/span&gt;: &lt;span class="n"&gt;Technical&lt;/span&gt; &lt;span class="n"&gt;Support&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;SKILL_GROUP&lt;/span&gt;=&lt;span class="n"&gt;support_001&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Return&lt;/span&gt;()

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;3&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Selected&lt;/span&gt;: &lt;span class="n"&gt;Sales&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;3&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;SKILL_GROUP&lt;/span&gt;=&lt;span class="n"&gt;sales_001&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;3&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Return&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  9.3 Load Balancing Across Multiple Groups
&lt;/h3&gt;

&lt;p&gt;Distribute calls across multiple similar groups:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;voipms&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Load&lt;/span&gt; &lt;span class="n"&gt;balanced&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;LB_GROUP&lt;/span&gt;=${&lt;span class="n"&gt;RAND&lt;/span&gt;(&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="m"&gt;3&lt;/span&gt;)})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Queue&lt;/span&gt;(&lt;span class="n"&gt;sales_00&lt;/span&gt;${&lt;span class="n"&gt;LB_GROUP&lt;/span&gt;},&lt;span class="n"&gt;t&lt;/span&gt;,,&lt;span class="m"&gt;180&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;2015550123&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This requires creating &lt;code&gt;sales_001&lt;/code&gt;, &lt;code&gt;sales_002&lt;/code&gt;, and &lt;code&gt;sales_003&lt;/code&gt; groups.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 10: Performance Tuning and Optimization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  10.1 Optimize Queue Performance
&lt;/h3&gt;

&lt;p&gt;Reduce database queries with caching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vi /etc/asterisk/res_odbc.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;asterisk&lt;/span&gt;]
&lt;span class="n"&gt;dsn&lt;/span&gt; = &lt;span class="n"&gt;asterisk&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt; = &lt;span class="n"&gt;vicidial&lt;/span&gt;
&lt;span class="n"&gt;password&lt;/span&gt; = &lt;span class="n"&gt;your_password&lt;/span&gt;
&lt;span class="n"&gt;pooling&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;limit&lt;/span&gt; = &lt;span class="m"&gt;5&lt;/span&gt;
&lt;span class="n"&gt;idleTimeout&lt;/span&gt; = &lt;span class="m"&gt;3600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.2 Monitor Active Calls
&lt;/h3&gt;

&lt;p&gt;Create a monitoring script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# check_vicidial_calls.sh&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nv"&gt;ACTIVE_CALLS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show channels"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SIP/"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
  &lt;span class="nv"&gt;QUEUED_CALLS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"queue show sales_001"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"wait:"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;: Active Calls: &lt;/span&gt;&lt;span class="nv"&gt;$ACTIVE_CALLS&lt;/span&gt;&lt;span class="s2"&gt; | Queued: &lt;/span&gt;&lt;span class="nv"&gt;$QUEUED_CALLS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  &lt;span class="nb"&gt;sleep &lt;/span&gt;5
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x check_vicidial_calls.sh
./check_vicidial_calls.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  10.3 Database Query Optimization
&lt;/h3&gt;

&lt;p&gt;Add indexes for faster lookups:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_phone_codes&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_phone_code&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phone_code&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_phone_codes&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_inbound_group&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inbound_group&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_inbound_group&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;inbound_group&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue: Calls Not Reaching Agents
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Incoming calls drop or go to voicemail instead of ringing agents.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify agent is logged in and READY:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"queue show sales_001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check agent assignment to inbound group:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify queue context includes the inbound group:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan show sales_001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check Asterisk error logs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; queue
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Calls Drop Immediately After Answer
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Agent answers but call immediately disconnects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check SIP peer context matches dialplan context:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 5 &lt;span class="s2"&gt;"context="&lt;/span&gt; /etc/asterisk/sip-vicidial.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify extensions exist in that context:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan show from-voipms"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check for codec mismatch:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peer voipms"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Review logs for SIP errors:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; sip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: DID Not Found / Wrong Routing
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Calls route to wrong queue or default handler.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify DID is in phone_codes table:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_phone_codes&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone_code&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'2015550123'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check phone code format matches (leading zeros, country codes, etc.):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;phone_code&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_phone_codes&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test database query directly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"database show vicidial"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add debug logging to dialplan:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;DEBUG&lt;/span&gt;: &lt;span class="n"&gt;DID&lt;/span&gt;=${&lt;span class="n"&gt;DID_NUMBER&lt;/span&gt;} &lt;span class="n"&gt;Group&lt;/span&gt;=${&lt;span class="n"&gt;INBOUND_GROUP&lt;/span&gt;})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"set verbose 4"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: No Call Recordings
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Calls complete but no recordings appear.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify recording is enabled:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;inbound_group_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_recording&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_inbound_groups&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check recording directory exists and has proper permissions:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /var/spool/asterisk/monitor/ | &lt;span class="nb"&gt;head
sudo chown&lt;/span&gt; &lt;span class="nt"&gt;-R&lt;/span&gt; asterisk:asterisk /var/spool/asterisk/monitor/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify MixMonitor is loaded:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"module show like app_mixmonitor"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check for disk space issues:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; /var/spool/asterisk/monitor/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Review ViciDial call logs for recording path:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;recording_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_recording&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_carrier_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Queue Timeout - Calls Hanging or Looping
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Calls stay in queue too long or loop back to queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify queue timeout settings:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"queue show sales_001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Adjust timeout in extensions-vicidial.conf:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Queue&lt;/span&gt;(&lt;span class="n"&gt;sales_001&lt;/span&gt;,&lt;span class="n"&gt;t&lt;/span&gt;,,&lt;span class="m"&gt;120&lt;/span&gt;)  ; &lt;span class="n"&gt;Reduced&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="m"&gt;120&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check Asterisk queue settings in queues.conf:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 10 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;sales_001&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; /etc/asterisk/queues.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify agent ring timeout:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;sales_001&lt;/span&gt;]
&lt;span class="n"&gt;timeout&lt;/span&gt; = &lt;span class="m"&gt;20&lt;/span&gt;  ; &lt;span class="n"&gt;Ring&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;per&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: High Call Abandonment Rate
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Callers hanging up while waiting in queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Increase number of agents in group:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;agent_count&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Monitor queue depth:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"queue show sales_001"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Callers:"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Enable hold time announcements:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_inbound_groups&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;announce_holdtime&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Implement callback system for high queue depths:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;GotoIf&lt;/span&gt;($[${&lt;span class="n"&gt;QUEUE_MEMBER_COUNT&lt;/span&gt;(&lt;span class="n"&gt;sales_001&lt;/span&gt;)} &amp;gt; &lt;span class="m"&gt;5&lt;/span&gt;]?&lt;span class="n"&gt;callback&lt;/span&gt;:&lt;span class="n"&gt;queue&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;(&lt;span class="n"&gt;callback&lt;/span&gt;),&lt;span class="n"&gt;VoiceMail&lt;/span&gt;(${&lt;span class="n"&gt;EXTEN&lt;/span&gt;}@&lt;span class="n"&gt;sales_callback&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Caller ID Not Displaying Correctly
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Agent sees "Unknown" or generic CID instead of actual caller.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable CID preservation in dialplan:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;num&lt;/span&gt;)=${&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;num&lt;/span&gt;)})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;name&lt;/span&gt;)=${&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;name&lt;/span&gt;)})
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify carrier sends ANI information:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show channels"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;voipms
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check CID Group settings:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_inbound_groups&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;inbound_group_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'sales_001'&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Review actual call logs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;caller_id_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caller_id_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_carrier_log&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;You now have a complete, production-ready DID routing configuration in ViciDial. Here's what you've implemented:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key Components Configured:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;✅ SIP carrier connection with proper peer configuration&lt;/li&gt;
&lt;li&gt;✅ Inbound groups created and configured in ViciDial&lt;/li&gt;
&lt;li&gt;✅ DID-to-group mapping via phone codes table&lt;/li&gt;
&lt;li&gt;✅ Asterisk dialplan with routing logic (from-voipms context)&lt;/li&gt;
&lt;li&gt;✅ Queue management and agent assignment&lt;/li&gt;
&lt;li&gt;✅ Call recording and logging infrastructure&lt;/li&gt;
&lt;li&gt;✅ Advanced routing scenarios (time-based, skill-based, load-balanced)&lt;/li&gt;
&lt;li&gt;✅ Comprehensive troubleshooting procedures&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Critical Configuration Files:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt; — Carrier SIP peer definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt; — Dialplan routing logic&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/etc/asterisk/queues.conf&lt;/code&gt; — Queue parameters (optional)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Critical Database Tables:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;vicidial_carriers&lt;/code&gt; — Carrier registration&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vicidial_inbound_groups&lt;/code&gt; — Queue definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vicidial_phone_codes&lt;/code&gt; — DID mapping&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vicidial_users&lt;/code&gt; — Agent assignments&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vicidial_carrier_log&lt;/code&gt; — Inbound call records&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test with real inbound calls from your carrier&lt;/li&gt;
&lt;li&gt;Monitor performance using &lt;code&gt;queue show&lt;/code&gt; and database queries&lt;/li&gt;
&lt;li&gt;Implement failover routing for redundancy&lt;/li&gt;
&lt;li&gt;Set up alerts for queue depth and agent availability&lt;/li&gt;
&lt;li&gt;Document your specific DID/extension mappings&lt;/li&gt;
&lt;li&gt;Schedule regular backup of extensions and queue configs&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Best Practices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always test configuration changes with test calls before production traffic&lt;/li&gt;
&lt;li&gt;Monitor &lt;code&gt;/var/log/asterisk/messages&lt;/code&gt; during testing and troubleshooting&lt;/li&gt;
&lt;li&gt;Keep detailed notes of all DID numbers, their purposes, and target inbound groups&lt;/li&gt;
&lt;li&gt;Regularly review call logs and agent metrics to optimize routing&lt;/li&gt;
&lt;li&gt;Implement proper access controls for admin panel and database&lt;/li&gt;
&lt;li&gt;Test failover scenarios and call handling during agent unavailability&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Your ViciDial DID routing is now ready for production use with proper logging, recording, and agent distribution.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>How to Create Custom ViciDial Reports with SQL Queries</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Sat, 15 Aug 2026 03:30:03 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/how-to-create-custom-vicidial-reports-with-sql-queries-5hm5</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/how-to-create-custom-vicidial-reports-with-sql-queries-5hm5</guid>
      <description>&lt;h1&gt;
  
  
  How to Create Custom ViciDial Reports with SQL Queries
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master the art of building production-grade custom reports in ViciDial by writing optimized SQL queries against the asterisk database, complete with real examples, performance tuning, and troubleshooting strategies.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before diving into custom ViciDial reports, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A running ViciDial installation (v2.14 or later recommended)&lt;/li&gt;
&lt;li&gt;SSH access to your ViciDial server with sudo privileges&lt;/li&gt;
&lt;li&gt;MySQL/MariaDB client installed locally or access to the database server&lt;/li&gt;
&lt;li&gt;Basic SQL knowledge (SELECT, WHERE, JOIN, GROUP BY)&lt;/li&gt;
&lt;li&gt;Understanding of ViciDial's call flow and database structure&lt;/li&gt;
&lt;li&gt;Database credentials for the &lt;code&gt;asterisk&lt;/code&gt; database&lt;/li&gt;
&lt;li&gt;Text editor or IDE with SQL syntax highlighting (optional but recommended)&lt;/li&gt;
&lt;li&gt;Read access to &lt;code&gt;/var/log/asterisk/messages&lt;/code&gt; for debugging&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Verify your ViciDial installation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"USE asterisk; SHOW TABLES LIKE 'vicidial%';"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Understanding ViciDial Database Structure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Critical Tables for Reporting
&lt;/h3&gt;

&lt;p&gt;ViciDial stores call data across multiple interconnected tables. Understanding their relationships is fundamental to writing effective reports.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;vicidial_log&lt;/strong&gt; — The primary call record table. Every inbound/outbound call creates an entry here.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DESCRIBE&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vicidial_log&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;uniqueid&lt;/code&gt; — Unique call identifier (varchar 32)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;caller_id_number&lt;/code&gt; — Calling party number&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;caller_id_name&lt;/code&gt; — Calling party name&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;phone_number&lt;/code&gt; — Called party number&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;call_date&lt;/code&gt; — Call start timestamp&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;call_length&lt;/code&gt; — Duration in seconds&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;status&lt;/code&gt; — Final call status (SALE, NO ANSWER, BAD NUMBER, etc.)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;campaign_id&lt;/code&gt; — Associated campaign&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user&lt;/code&gt; — Agent username&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;list_id&lt;/code&gt; — DNC/contact list&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;vicidial_closer_log&lt;/strong&gt; — Bridge logs for calls transferred to agents.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DESCRIBE&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vicidial_closer_log&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key columns:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;uniqueid&lt;/code&gt; — Links to vicidial_log&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;user&lt;/code&gt; — Agent who answered&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;closer_called_number&lt;/code&gt; — Number dialed by agent&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;status&lt;/code&gt; — Agent-assigned disposition&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;talk_time&lt;/code&gt; — Seconds agent spent talking&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;call_date&lt;/code&gt; — When agent answered&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;vicidial_users&lt;/strong&gt; — Agent/user information.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DESCRIBE&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vicidial_users&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;vicidial_campaigns&lt;/strong&gt; — Campaign definitions and settings.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DESCRIBE&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;vicidial_list&lt;/strong&gt; — Contact records.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DESCRIBE&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vicidial_list&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Database Connection String
&lt;/h3&gt;

&lt;p&gt;Create a MySQL credentials file for secure, repeatable access:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; ~/.my.cnf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
[client]
user=root
password=your_password
host=localhost
database=asterisk
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;600 ~/.my.cnf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify connection:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT COUNT(*) as total_calls FROM vicidial_log WHERE call_date &amp;gt;= DATE_SUB(NOW(), INTERVAL 24 HOUR);"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Setting Up Your Reporting Environment
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a Dedicated Reporting Database User
&lt;/h3&gt;

&lt;p&gt;For production security, create a read-only user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;USER&lt;/span&gt; &lt;span class="s1"&gt;'vicidial_reports'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'secure_password_here'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'vicidial_reports'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test the new user:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; vicidial_reports &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT VERSION();"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Organize Your Queries
&lt;/h3&gt;

&lt;p&gt;Create a directory structure for managing report queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /home/vicidial_admin/reports/&lt;span class="o"&gt;{&lt;/span&gt;daily,weekly,monthly,custom&lt;span class="o"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /home/vicidial_admin/reports/outputs
&lt;span class="nb"&gt;chmod &lt;/span&gt;755 /home/vicidial_admin/reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Report Queries
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Daily Call Volume by Campaign
&lt;/h3&gt;

&lt;p&gt;This query aggregates all calls for the past 24 hours, grouped by campaign.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;conversion_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_length&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;avg_call_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_talk_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;first_call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;last_call&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;
    &lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SKIP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'QUEUE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_name&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;total_calls&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save this to a file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /home/vicidial_admin/reports/daily/daily_volume.sql &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
-- Daily Call Volume by Campaign
SELECT 
    c.campaign_name,
    c.campaign_id,
    COUNT(vl.uniqueid) as total_calls,
    SUM(CASE WHEN vl.status = 'SALE' THEN 1 ELSE 0 END) as sales,
    ROUND(SUM(CASE WHEN vl.status = 'SALE' THEN 1 ELSE 0 END) / COUNT(vl.uniqueid) * 100, 2) as conversion_rate,
    ROUND(AVG(vl.call_length), 2) as avg_call_length,
    SUM(vl.call_length) as total_talk_time,
    MIN(vl.call_date) as first_call,
    MAX(vl.call_date) as last_call
FROM 
    vicidial_log vl
    LEFT JOIN vicidial_campaigns c ON vl.campaign_id = c.campaign_id
WHERE 
    vl.call_date &amp;gt;= DATE_SUB(CURDATE(), INTERVAL 1 DAY)
    AND vl.call_date &amp;lt; CURDATE()
    AND vl.status NOT IN ('', 'SKIP', 'QUEUE')
GROUP BY 
    vl.campaign_id, c.campaign_name
ORDER BY 
    total_calls DESC;
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Execute the report:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &amp;lt; /home/vicidial_admin/reports/daily/daily_volume.sql &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /home/vicidial_admin/reports/outputs/daily_volume_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt;.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Performance Report
&lt;/h3&gt;

&lt;p&gt;Track individual agent metrics over a specific period.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;vu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;vu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;calls_handled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;talk_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_talk_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;talk_time&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;avg_talk_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales_percentage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;first_call&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;last_call&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;vicidial_closer_log&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;
    &lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; &lt;span class="n"&gt;vu&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;vu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'QUEUE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vu&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;full_name&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;calls_handled&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Disposition Breakdown
&lt;/h3&gt;

&lt;p&gt;Understand how calls are being disposed across your system.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;disposition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;percentage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;
    &lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Calls by Hour of Day
&lt;/h3&gt;

&lt;p&gt;Identify peak calling times and staffing patterns.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;HOUR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;hour_of_day&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;agents_active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_length&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;avg_call_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales_rate&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SKIP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'QUEUE'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;HOUR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;hour_of_day&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  DNC Compliance Report
&lt;/h3&gt;

&lt;p&gt;Monitor Do-Not-Call list compliance for regulatory requirements.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'DNC'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;dnc_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;unique_numbers_called&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'DNC'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;dnc_percentage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;campaigns_involved&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DNC'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'DNC PERM'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced Query Patterns
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Using Window Functions for Ranking
&lt;/h3&gt;

&lt;p&gt;Identify top-performing agents with ranking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;rank&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;calls_handled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;sales_percentage&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; 
        &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;calls_handled&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales_percentage&lt;/span&gt;
    &lt;span class="k"&gt;FROM&lt;/span&gt; 
        &lt;span class="n"&gt;vicidial_closer_log&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;
    &lt;span class="k"&gt;WHERE&lt;/span&gt; 
        &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
        &lt;span class="n"&gt;vcl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;
    &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
        &lt;span class="n"&gt;sales_percentage&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;ranked_agents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="n"&gt;rank&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;init&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Multi-Campaign Comparison
&lt;/h3&gt;

&lt;p&gt;Compare performance metrics across multiple campaigns simultaneously.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;conversion&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_length&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;avg_length&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;
    &lt;span class="k"&gt;LEFT&lt;/span&gt; &lt;span class="k"&gt;JOIN&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;30&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'CAMPAIGN1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'CAMPAIGN2'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'CAMPAIGN3'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;campaign_name&lt;/span&gt; &lt;span class="k"&gt;ASC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Contact List Activity Report
&lt;/h3&gt;

&lt;p&gt;Track activity on specific contact lists.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;unique_contacts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;contacts_converted&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_sales&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uniqueid&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;sales_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;first_call_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;last_call_date&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;vl&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;list_id&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; 
    &lt;span class="n"&gt;total_calls&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating Automated Reports
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Bash Script for Scheduled Reports
&lt;/h3&gt;

&lt;p&gt;Create a production-ready reporting script that runs via cron.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /home/vicidial_admin/reports/generate_reports.sh&lt;/span&gt;

&lt;span class="nv"&gt;REPORT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/home/vicidial_admin/reports"&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/home/vicidial_admin/reports/outputs"&lt;/span&gt;
&lt;span class="nv"&gt;BACKUP_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/home/vicidial_admin/reports/archive"&lt;/span&gt;
&lt;span class="nv"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d_%H%M%S&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/log/vicidial_reports.log"&lt;/span&gt;

&lt;span class="c"&gt;# Ensure directories exist&lt;/span&gt;
&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Function to log messages&lt;/span&gt;
log_message&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%d %H:%M:%S'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;] &lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

log_message &lt;span class="s2"&gt;"Starting ViciDial report generation"&lt;/span&gt;

&lt;span class="c"&gt;# Generate daily volume report&lt;/span&gt;
log_message &lt;span class="s2"&gt;"Generating daily volume report..."&lt;/span&gt;
mysql &lt;span class="nt"&gt;--defaults-extra-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/.my.cnf &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPORT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/daily/daily_volume.sql"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/daily_volume_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.csv"&lt;/span&gt; 2&amp;gt;&amp;gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;log_message &lt;span class="s2"&gt;"Daily volume report completed successfully"&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;log_message &lt;span class="s2"&gt;"ERROR: Daily volume report failed"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Generate agent performance report&lt;/span&gt;
log_message &lt;span class="s2"&gt;"Generating agent performance report..."&lt;/span&gt;
mysql &lt;span class="nt"&gt;--defaults-extra-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/.my.cnf &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPORT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/daily/agent_performance.sql"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/agent_performance_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.csv"&lt;/span&gt; 2&amp;gt;&amp;gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;log_message &lt;span class="s2"&gt;"Agent performance report completed successfully"&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;log_message &lt;span class="s2"&gt;"ERROR: Agent performance report failed"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Clean up old reports (keep 30 days)&lt;/span&gt;
log_message &lt;span class="s2"&gt;"Cleaning up old reports..."&lt;/span&gt;
find &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"*.csv"&lt;/span&gt; &lt;span class="nt"&gt;-mtime&lt;/span&gt; +30 &lt;span class="nt"&gt;-exec&lt;/span&gt; &lt;span class="nb"&gt;mv&lt;/span&gt; &lt;span class="o"&gt;{}&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\;&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;&amp;amp;1

log_message &lt;span class="s2"&gt;"Report generation completed"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make the script executable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /home/vicidial_admin/reports/generate_reports.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Schedule Reports via Cron
&lt;/h3&gt;

&lt;p&gt;Add to root's crontab to run daily at 6 AM:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Generate ViciDial reports daily at 6 AM
0 6 * * * /home/vicidial_admin/reports/generate_reports.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify cron job is set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;crontab &lt;span class="nt"&gt;-l&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;generate_reports
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Email Report Delivery
&lt;/h3&gt;

&lt;p&gt;Enhance the bash script to email reports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Add this to your generate_reports.sh script&lt;/span&gt;

&lt;span class="nv"&gt;REPORT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/home/vicidial_admin/reports"&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/home/vicidial_admin/reports/outputs"&lt;/span&gt;
&lt;span class="nv"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;EMAIL_TO&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"manager@company.com"&lt;/span&gt;
&lt;span class="nv"&gt;EMAIL_SUBJECT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"ViciDial Daily Report - &lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;HOSTNAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Generate reports first&lt;/span&gt;
mysql &lt;span class="nt"&gt;--defaults-extra-file&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;~/.my.cnf &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$REPORT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/daily/daily_volume.sql"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/daily_volume_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.csv"&lt;/span&gt;

&lt;span class="c"&gt;# Create email body&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/email_body.txt &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
ViciDial Daily Report
Generated: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;
Hostname: &lt;/span&gt;&lt;span class="nv"&gt;$HOSTNAME&lt;/span&gt;&lt;span class="sh"&gt;

Daily Call Volume Summary:
&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/daily_volume_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.csv"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="sh"&gt;

Full reports attached.
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Send email with attachment&lt;/span&gt;
mail &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EMAIL_SUBJECT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"From: vicidial@&lt;/span&gt;&lt;span class="nv"&gt;$HOSTNAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_DIR&lt;/span&gt;&lt;span class="s2"&gt;/daily_volume_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.csv"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
     &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$EMAIL_TO&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &amp;lt; /tmp/email_body.txt

&lt;span class="nb"&gt;rm&lt;/span&gt; /tmp/email_body.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Optimization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Index Strategy for Reporting Queries
&lt;/h3&gt;

&lt;p&gt;Check existing indexes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_closer_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add critical indexes for reporting if missing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- For call_date filtering (most common)&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_call_date&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- For campaign filtering&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_campaign_id&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- For user filtering&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_closer_log&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_closer_user&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Combined index for date range and campaign queries&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_campaign_date&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify indexes are created&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query Performance Testing
&lt;/h3&gt;

&lt;p&gt;Use EXPLAIN to analyze query execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;EXPLAIN&lt;/span&gt; 
&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_length&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_time&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; 
    &lt;span class="n"&gt;vicidial_log&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; 
    &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'CAMPAIGN1'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output should show:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Type: &lt;code&gt;range&lt;/code&gt; or &lt;code&gt;ref&lt;/code&gt; (not &lt;code&gt;ALL&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Rows: Should be reasonably small relative to table size&lt;/li&gt;
&lt;li&gt;Extra: Should not say "Using temporary" or "Using filesort"&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Archive Old Data
&lt;/h3&gt;

&lt;p&gt;For very large databases, archive records older than 1 year:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Archive reports to separate database for historical analysis&lt;/span&gt;

&lt;span class="nv"&gt;ARCHIVE_DB&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"asterisk_archive"&lt;/span&gt;
&lt;span class="nv"&gt;RETENTION_DAYS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;365

mysql &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
-- Create archive table if not exists
CREATE TABLE IF NOT EXISTS &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ARCHIVE_DB&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;.vicidial_log_archive LIKE asterisk.vicidial_log;

-- Copy old records to archive
INSERT INTO &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;ARCHIVE_DB&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;.vicidial_log_archive
SELECT * FROM asterisk.vicidial_log
WHERE call_date &amp;lt; DATE_SUB(NOW(), INTERVAL &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RETENTION_DAYS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt; DAY);

-- Delete archived records from main table
DELETE FROM asterisk.vicidial_log
WHERE call_date &amp;lt; DATE_SUB(NOW(), INTERVAL &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;RETENTION_DAYS&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="sh"&gt; DAY);

-- Optimize table to reclaim space
OPTIMIZE TABLE asterisk.vicidial_log;
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Integration with ViciDial Web Interface
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Custom Report Module Integration
&lt;/h3&gt;

&lt;p&gt;ViciDial allows custom reports via the admin interface. Place your report script in the correct directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /var/www/html/vicidial/admin/custom_reports.php &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
&amp;lt;?php
// Simple custom report viewer for ViciDial

&lt;/span&gt;&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="sh"&gt; = mysqli_connect('localhost', 'vicidial_reports', 'password', 'asterisk');

if (!&lt;/span&gt;&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="sh"&gt;) {
    die("Database connection failed: " . mysqli_connect_error());
}

// Sanitize input
&lt;/span&gt;&lt;span class="nv"&gt;$report_type&lt;/span&gt;&lt;span class="sh"&gt; = isset(&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="sh"&gt;['type']) ? mysqli_real_escape_string(&lt;/span&gt;&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="sh"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="sh"&gt;['type']) : 'daily_volume';
&lt;/span&gt;&lt;span class="nv"&gt;$days&lt;/span&gt;&lt;span class="sh"&gt; = isset(&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="sh"&gt;['days']) ? intval(&lt;/span&gt;&lt;span class="nv"&gt;$_GET&lt;/span&gt;&lt;span class="sh"&gt;['days']) : 1;

// Simple report queries
&lt;/span&gt;&lt;span class="nv"&gt;$queries&lt;/span&gt;&lt;span class="sh"&gt; = array(
    'daily_volume' =&amp;gt; "
        SELECT 
            c.campaign_name,
            COUNT(vl.uniqueid) as calls,
            SUM(CASE WHEN vl.status = 'SALE' THEN 1 ELSE 0 END) as sales
        FROM vicidial_log vl
        LEFT JOIN vicidial_campaigns c ON vl.campaign_id = c.campaign_id
        WHERE vl.call_date &amp;gt;= DATE_SUB(CURDATE(), INTERVAL &lt;/span&gt;&lt;span class="nv"&gt;$days&lt;/span&gt;&lt;span class="sh"&gt; DAY)
        GROUP BY vl.campaign_id
        ORDER BY calls DESC
    ",
    'agent_performance' =&amp;gt; "
        SELECT 
            vcl.user,
            COUNT(vcl.uniqueid) as calls,
            SUM(vcl.talk_time) as talk_time,
            COUNT(CASE WHEN vcl.status = 'SALE' THEN 1 END) as sales
        FROM vicidial_closer_log vcl
        WHERE vcl.call_date &amp;gt;= DATE_SUB(CURDATE(), INTERVAL &lt;/span&gt;&lt;span class="nv"&gt;$days&lt;/span&gt;&lt;span class="sh"&gt; DAY)
        GROUP BY vcl.user
        ORDER BY calls DESC
    "
);

if (isset(&lt;/span&gt;&lt;span class="nv"&gt;$queries&lt;/span&gt;&lt;span class="sh"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$report_type&lt;/span&gt;&lt;span class="sh"&gt;])) {
    &lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="sh"&gt; = mysqli_query(&lt;/span&gt;&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="sh"&gt;, &lt;/span&gt;&lt;span class="nv"&gt;$queries&lt;/span&gt;&lt;span class="sh"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$report_type&lt;/span&gt;&lt;span class="sh"&gt;]);

    echo "&amp;lt;table border='1'&amp;gt;";

    // Print header
    &lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="sh"&gt; = mysqli_fetch_assoc(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="sh"&gt;);
    echo "&amp;lt;tr&amp;gt;";
    foreach (&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="sh"&gt; as &lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="sh"&gt; =&amp;gt; &lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="sh"&gt;) {
        echo "&amp;lt;th&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$key&lt;/span&gt;&lt;span class="sh"&gt;&amp;lt;/th&amp;gt;";
    }
    echo "&amp;lt;/tr&amp;gt;";

    // Print rows
    echo "&amp;lt;tr&amp;gt;";
    foreach (&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="sh"&gt; as &lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="sh"&gt;) {
        echo "&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="sh"&gt;&amp;lt;/td&amp;gt;";
    }
    echo "&amp;lt;/tr&amp;gt;";

    while (&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="sh"&gt; = mysqli_fetch_assoc(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="sh"&gt;)) {
        echo "&amp;lt;tr&amp;gt;";
        foreach (&lt;/span&gt;&lt;span class="nv"&gt;$row&lt;/span&gt;&lt;span class="sh"&gt; as &lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="sh"&gt;) {
            echo "&amp;lt;td&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="sh"&gt;&amp;lt;/td&amp;gt;";
        }
        echo "&amp;lt;/tr&amp;gt;";
    }

    echo "&amp;lt;/table&amp;gt;";
}

mysqli_close(&lt;/span&gt;&lt;span class="nv"&gt;$db&lt;/span&gt;&lt;span class="sh"&gt;);
?&amp;gt;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;chmod &lt;/span&gt;644 /var/www/html/vicidial/admin/custom_reports.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Access the report at: &lt;code&gt;http://your-vicidial-server/vicidial/admin/custom_reports.php?type=daily_volume&amp;amp;days=7&lt;/code&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Database Connection Issues
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; "Can't connect to MySQL server"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check MySQL service status&lt;/span&gt;
systemctl status mysql

&lt;span class="c"&gt;# Verify credentials&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; vicidial_reports &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT 1;"&lt;/span&gt;

&lt;span class="c"&gt;# Check user permissions&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SHOW GRANTS FOR 'vicidial_reports'@'localhost';"&lt;/span&gt;

&lt;span class="c"&gt;# Review MySQL error log&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt; /var/log/mysql/error.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Slow Query Performance
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Report queries taking too long (&amp;gt;10 seconds)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable query logging&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SET GLOBAL slow_query_log = 'ON';"&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SET GLOBAL long_query_time = 5;"&lt;/span&gt;

&lt;span class="c"&gt;# Check slow query log&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt; /var/log/mysql/slow.log

&lt;span class="c"&gt;# Run EXPLAIN on slow queries&lt;/span&gt;
mysql &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
SET SESSION sql_mode='';
EXPLAIN SELECT ... FROM ... WHERE ...;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Create missing indexes based on EXPLAIN results&lt;/span&gt;
ALTER TABLE vicidial_log ADD INDEX idx_analysis &lt;span class="o"&gt;(&lt;/span&gt;campaign_id, call_date&lt;span class="o"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inconsistent Report Data
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Different results when running the same report twice&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Check for locking issues&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;OPEN&lt;/span&gt; &lt;span class="n"&gt;TABLES&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;in_use&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Check table integrity&lt;/span&gt;
&lt;span class="k"&gt;CHECK&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;REPAIR&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify data consistency&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  High Memory Usage During Report Generation
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Server runs out of memory when generating large reports&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Break report into smaller date ranges&lt;/span&gt;
&lt;span class="c"&gt;# Instead of 365 days at once, do monthly:&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;month &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..12&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;START_DATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2024-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%02d'&lt;/span&gt; &lt;span class="nv"&gt;$month&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-01"&lt;/span&gt;
    &lt;span class="nv"&gt;END_DATE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"2024-&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;printf&lt;/span&gt; &lt;span class="s1"&gt;'%02d'&lt;/span&gt; &lt;span class="k"&gt;$((&lt;/span&gt;month+1&lt;span class="k"&gt;))&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;-01"&lt;/span&gt;

    mysql &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
SELECT * FROM vicidial_log 
WHERE call_date &amp;gt;= '&lt;/span&gt;&lt;span class="nv"&gt;$START_DATE&lt;/span&gt;&lt;span class="sh"&gt;' 
  AND call_date &amp;lt; '&lt;/span&gt;&lt;span class="nv"&gt;$END_DATE&lt;/span&gt;&lt;span class="sh"&gt;'
INTO OUTFILE '/tmp/report_&lt;/span&gt;&lt;span class="nv"&gt;$month&lt;/span&gt;&lt;span class="sh"&gt;.csv';
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Missing Data in Reports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Problem:&lt;/strong&gt; Report shows fewer calls than expected&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Check for NULL campaigns&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify date range filter&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;MIN&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Check status filters in query&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;DISTINCT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Ensure no excluded statuses&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;CURDATE&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Creating custom ViciDial reports with SQL requires understanding the database schema, mastering JOIN operations, and implementing performance optimizations. Key takeaways:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Essential Skills:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Master the vicidial_log, vicidial_closer_log, and vicidial_users tables&lt;/li&gt;
&lt;li&gt;Use proper date filtering with call_date for accurate period-based reports&lt;/li&gt;
&lt;li&gt;Leverage GROUP BY and aggregate functions for summarization&lt;/li&gt;
&lt;li&gt;Implement indexes on frequently queried columns (campaign_id, call_date, user)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Production Best Practices:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Create dedicated read-only database users for reporting&lt;/li&gt;
&lt;li&gt;Schedule reports via cron for consistent delivery&lt;/li&gt;
&lt;li&gt;Monitor query performance with EXPLAIN and slow query logs&lt;/li&gt;
&lt;li&gt;Archive old data to maintain query speed&lt;/li&gt;
&lt;li&gt;Validate data consistency regularly&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Common Mistakes to Avoid:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Forgetting to filter out empty or test statuses&lt;/li&gt;
&lt;li&gt;Not joining with vicidial_campaigns/vicidial_users tables&lt;/li&gt;
&lt;li&gt;Running reports without date range filters (inefficient)&lt;/li&gt;
&lt;li&gt;Ignoring NULL values in campaign_id or user fields&lt;/li&gt;
&lt;li&gt;Failing to account for time zone differences in call_date&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Next Steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Start with pre-built queries from this guide&lt;/li&gt;
&lt;li&gt;Test queries on non-peak hours first&lt;/li&gt;
&lt;li&gt;Create backup indexes for high-frequency report queries&lt;/li&gt;
&lt;li&gt;Document your custom queries in version control&lt;/li&gt;
&lt;li&gt;Monitor execution time and optimize based on EXPLAIN analysis&lt;/li&gt;
&lt;li&gt;Integrate with ViciDial's admin interface for user accessibility&lt;/li&gt;
&lt;li&gt;Set up automated email delivery for stakeholder reports&lt;/li&gt;
&lt;li&gt;Establish data retention and archival policies&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;With these fundamentals, you can build enterprise-grade reporting solutions that give real-time insights into your ViciDial call center operations.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>How to Set Up ViciDial Auto-Dial (Predictive, Ratio &amp; Progressive)</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Fri, 14 Aug 2026 03:30:04 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/how-to-set-up-vicidial-auto-dial-predictive-ratio-progressive-240h</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/how-to-set-up-vicidial-auto-dial-predictive-ratio-progressive-240h</guid>
      <description>&lt;h1&gt;
  
  
  How to Set Up ViciDial Auto-Dial (Predictive, Ratio &amp;amp; Progressive)
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master ViciDial's three auto-dial modes with production-ready configurations, database tuning, and real-world troubleshooting for enterprise call centers&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before proceeding, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ViciDial 2.14+ installed and running (check via &lt;code&gt;asterisk -rx "core show version"&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;MySQL/MariaDB access to the asterisk database&lt;/li&gt;
&lt;li&gt;Asterisk 11+ or higher with DAHDI/SIP trunks configured&lt;/li&gt;
&lt;li&gt;Root or sudo access on the ViciDial server&lt;/li&gt;
&lt;li&gt;A working inbound/outbound carrier with available channels&lt;/li&gt;
&lt;li&gt;At least 3-5 agents trained and ready to test&lt;/li&gt;
&lt;li&gt;Backup of your asterisk database (&lt;code&gt;mysqldump asterisk &amp;gt; backup_$(date +%Y%m%d).sql&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding ViciDial Auto-Dial Modes
&lt;/h2&gt;

&lt;p&gt;ViciDial offers three fundamentally different calling strategies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Predictive Dialing&lt;/strong&gt;: System dials before agent is available. AI-driven pacing predicts agent availability and adjusts dial rate dynamically.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ratio-Based Dialing&lt;/strong&gt;: Fixed multiplier applied to available agents (e.g., 3:1 = 3 dials per agent). Simple, predictable, less sophisticated.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Progressive Dialing&lt;/strong&gt;: Agent initiates dial manually or via single-click. Lowest abandonment rates, highest agent idle time.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Each mode has different CPU, database, and channel requirements. Predictive uses the most resources but achieves highest contact rates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 1: Database Configuration &amp;amp; Prerequisites
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create Your Campaign
&lt;/h3&gt;

&lt;p&gt;Access the ViciDial admin interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SSH into your ViciDial server&lt;/span&gt;
ssh &lt;span class="nt"&gt;-i&lt;/span&gt; your_key.pem root@vicidial.example.com

&lt;span class="c"&gt;# Verify MySQL connectivity&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT * FROM vicidial_campaigns LIMIT 1;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Insert a new campaign via admin panel (/vicidial/admin.php) or via MySQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;campaign_description&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;dial_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;phone_number_format&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;dispo_group_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;campaign_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;auto_dial_level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;dial_timeout&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;call_volume_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;lead_recycle_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;drop_percentage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;local_call_time&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;min_ingroup_agents&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;scheduled_callbacks&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;test_call_flag&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="s1"&gt;'PREDICTIVE_01'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'Predictive Campaign Test'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'High-volume predictive outbound campaign'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'INBOUND'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'US'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'0.8'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'45'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'default'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'DISABLED'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'5'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'GMT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'ENABLED'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s1"&gt;'N'&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key field explanations:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dial_method&lt;/code&gt;: INBOUND (most common), BLENDED, CALLBACK&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;auto_dial_level&lt;/code&gt;: 0.1–1.0 (0.8 recommended for predictive; 0.3 for progressive)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;drop_percentage&lt;/code&gt;: Acceptable % of calls dropped due to no-agent availability (5-10% standard)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dial_timeout&lt;/code&gt;: Seconds to wait for answer before abandoning&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configure Dialing Parameters
&lt;/h3&gt;

&lt;p&gt;Update the vicidial_campaigns table with auto-dial specifics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;auto_dial_level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;dial_timeout&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;45&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;drop_percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;scheduled_callbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ENABLED'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'PREDICTIVE_01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the campaign is properly configured:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT campaign_id, campaign_name, dial_method, auto_dial_level, drop_percentage FROM vicidial_campaigns WHERE campaign_id = 'PREDICTIVE_01';"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 2: Asterisk SIP/Carrier Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Configure Outbound Carrier Trunks
&lt;/h3&gt;

&lt;p&gt;Edit the carrier configuration in &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;CARRIER_OUTBOUND_01&lt;/span&gt;](!)
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="m"&gt;123&lt;/span&gt;.&lt;span class="m"&gt;45&lt;/span&gt;.&lt;span class="m"&gt;67&lt;/span&gt;.&lt;span class="m"&gt;89&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;YourSecretPassword123&lt;/span&gt;
&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;vicidial&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="m"&gt;123&lt;/span&gt;.&lt;span class="m"&gt;45&lt;/span&gt;.&lt;span class="m"&gt;67&lt;/span&gt;.&lt;span class="m"&gt;89&lt;/span&gt;
&lt;span class="n"&gt;dtmfmode&lt;/span&gt;=&lt;span class="n"&gt;rfc2833&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;,&lt;span class="n"&gt;alaw&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;internal&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualify_freq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;maxcallbitrate&lt;/span&gt;=&lt;span class="m"&gt;128&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;canreinvite&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;progressinband&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a production-safe carrier entry:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;carrier_sirius&lt;/span&gt;](&lt;span class="n"&gt;CARRIER_OUTBOUND_01&lt;/span&gt;)
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="n"&gt;carrier&lt;/span&gt;.&lt;span class="n"&gt;sirius&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;SiriusCarrierSecret999&lt;/span&gt;
&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;vicidial_client_001&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="n"&gt;carrier&lt;/span&gt;.&lt;span class="n"&gt;sirius&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Dial Plan Extensions
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt; to add outbound dialing routes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;internal&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;ViciDial&lt;/span&gt; &lt;span class="n"&gt;Outbound&lt;/span&gt; - ${&lt;span class="n"&gt;EXTEN&lt;/span&gt;})
&lt;span class="n"&gt;same&lt;/span&gt; =&amp;gt; &lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;CHANNEL&lt;/span&gt;(&lt;span class="n"&gt;hangup_handler_push&lt;/span&gt;)=&lt;span class="n"&gt;hangup&lt;/span&gt;,&lt;span class="n"&gt;s&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;)
&lt;span class="n"&gt;same&lt;/span&gt; =&amp;gt; &lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;}@&lt;span class="n"&gt;carrier_sirius&lt;/span&gt;,&lt;span class="m"&gt;45&lt;/span&gt;,&lt;span class="n"&gt;TtKk&lt;/span&gt;)
&lt;span class="n"&gt;same&lt;/span&gt; =&amp;gt; &lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;span class="n"&gt;same&lt;/span&gt; =&amp;gt; &lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Busy&lt;/span&gt;()
&lt;span class="n"&gt;same&lt;/span&gt; =&amp;gt; &lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Unavailable&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Load and Verify Asterisk Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Backup current config&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; /etc/asterisk/extensions-vicidial.conf /etc/asterisk/extensions-vicidial.conf.backup

&lt;span class="c"&gt;# Reload Asterisk dialplan&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan reload"&lt;/span&gt;

&lt;span class="c"&gt;# Check for syntax errors&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan show from-internal"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Verify carrier registration&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;carrier_sirius
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output should show your carrier with UNREACHABLE or OK status (OK is ideal):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;carrier_sirius/1234567890    123.45.67.89:5060      D   yes          yes     OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 3: Predictive Dialing Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Understanding Predictive Algorithm
&lt;/h3&gt;

&lt;p&gt;ViciDial's predictive dialer uses a dynamic pacing algorithm. The system:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Monitors agent availability in real-time&lt;/li&gt;
&lt;li&gt;Dials calls ahead of agent availability&lt;/li&gt;
&lt;li&gt;Adjusts dial rate based on answer rates, talk time, and wrap-up time&lt;/li&gt;
&lt;li&gt;Aims to minimize agent idle time while staying within drop percentage limits&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Set Campaign to Predictive Mode
&lt;/h3&gt;

&lt;p&gt;Access /vicidial/admin.php → Campaigns → Select your campaign → Edit&lt;/p&gt;

&lt;p&gt;Or update via SQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; 
  &lt;span class="n"&gt;dial_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'INBOUND'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;auto_dial_level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;85&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;drop_percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;scheduled_callbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ENABLED'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;lead_recycle_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'DISABLED'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;pause_dialing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'N'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'PREDICTIVE_01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Predictive Parameters in vicidial_settings
&lt;/h3&gt;

&lt;p&gt;Edit the ViciDial system settings table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_settings&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; 
  &lt;span class="n"&gt;predictive_dialer_flag&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;predictive_answer_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'45'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;predictive_drop_rate_threshold&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'3'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;predictive_cpu_limit&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'90'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;outbound_autodial&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;setting_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ViciDial'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Parameter definitions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;predictive_dialer_flag&lt;/code&gt;: 1 = enable, 0 = disable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;predictive_answer_rate&lt;/code&gt;: Expected % of calls that connect (e.g., 45%)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;predictive_drop_rate_threshold&lt;/code&gt;: Pause dialing if drop rate exceeds this %&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;predictive_cpu_limit&lt;/code&gt;: CPU threshold before throttling dials&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configure the Predictive Dialer Service
&lt;/h3&gt;

&lt;p&gt;The ViciDial Predictive Dialer runs as a background service. Check if it's active:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if vicidial_dialer.pl is running&lt;/span&gt;
ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;vicidial_dialer.pl | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt;

&lt;span class="c"&gt;# If not running, start it manually&lt;/span&gt;
/usr/share/astguiclient/vicidial_dialer.pl &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /var/log/asterisk/vicidial_dialer.log 2&amp;gt;&amp;amp;1 &amp;amp;

&lt;span class="c"&gt;# Make permanent via cron (check root crontab)&lt;/span&gt;
crontab &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="c"&gt;# Add this line to restart dialer if it crashes:&lt;/span&gt;
&lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/share/astguiclient/check_vicidial_process.sh &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create Campaign-Specific Lead Lists
&lt;/h3&gt;

&lt;p&gt;Prepare your phone number list. Insert leads into the vicidial_list table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="n"&gt;lead_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;lead_phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;lead_phone_number_2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;last_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;vendor_lead_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;phone_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;phone_number_formatted&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'5551234567'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'John'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Doe'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john@example.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PREDICTIVE_01'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'CODE001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'555'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'555-123-4567'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'5559876543'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Jane'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Smith'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'jane@example.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PREDICTIVE_01'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'CODE002'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'555'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'555-987-6543'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'5552223333'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Bob'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Johnson'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'bob@example.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'PREDICTIVE_01'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'CODE003'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'555'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'555-222-3333'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify insertion&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'PREDICTIVE_01'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitor Predictive Dialing
&lt;/h3&gt;

&lt;p&gt;In real-time, check the dialer status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Monitor dialer queue&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show channels concise"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;

&lt;span class="c"&gt;# Check dial queue depth&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT COUNT(*) as pending_dials FROM vicidial_list WHERE campaign_id = 'PREDICTIVE_01' AND status IN ('NEW', 'QUEUE');"&lt;/span&gt;

&lt;span class="c"&gt;# Monitor predictive drops&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT call_result, COUNT(*) as count FROM vicidial_log WHERE campaign_id = 'PREDICTIVE_01' AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 1 HOUR) GROUP BY call_result;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 4: Ratio-Based Dialing Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Understanding Ratio Dialing
&lt;/h3&gt;

&lt;p&gt;Ratio (or Power) dialing maintains a fixed multiplier between agents and dials:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;3:1 ratio&lt;/strong&gt;: For every 1 available agent, system dials 3 calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;2:1 ratio&lt;/strong&gt;: More conservative; 2 dials per available agent&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;5:1 ratio&lt;/strong&gt;: Aggressive; higher abandonment but maximum throughput&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Formula&lt;/strong&gt;: Dials Per Minute = (Available Agents) × (Ratio) × (Calls Per Agent Per Minute)&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure Campaign for Ratio Dialing
&lt;/h3&gt;

&lt;p&gt;Set the auto_dial_level to 0.5 for a moderate ratio approach:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; 
  &lt;span class="n"&gt;dial_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'INBOUND'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;auto_dial_level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;drop_percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;scheduled_callbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ENABLED'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;pause_dialing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'N'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'RATIO_01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the ViciDial admin panel, under "Dialer Settings," configure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dial Ratio&lt;/strong&gt;: 3:1&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dial Timeout&lt;/strong&gt;: 45 seconds&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Drop Percentage Threshold&lt;/strong&gt;: 12%&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Adjust the Dialing Queue Script
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/usr/share/astguiclient/vicidial_dialer.pl&lt;/code&gt; (or create a wrapper):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Around line 850, locate the ratio calculation:&lt;/span&gt;
&lt;span class="c1"&gt;# Example modification for stricter ratio control&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$available_agents&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$dbh&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="nv"&gt;selectrow_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="p"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;SELECT COUNT(*) FROM vicidial_log WHERE campaign_id='&lt;/span&gt;&lt;span class="si"&gt;$campaign_id&lt;/span&gt;&lt;span class="s2"&gt;' 
   AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 10 SECOND)
   AND status IN ('QUEUE', 'INCALL')&lt;/span&gt;&lt;span class="p"&gt;"&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$ratio&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;# Set your ratio here&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$dials_to_queue&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;$available_agents&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$ratio&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;# Queue dials accordingly&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="nv"&gt;$dials_to_queue&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;queue_dial_for_agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$campaign_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitor Ratio Dialing Performance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check current agent count&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
  SELECT 
    COUNT(DISTINCT user) as active_agents,
    COUNT(*) as total_sessions
  FROM vicidial_log 
  WHERE campaign_id = 'RATIO_01' 
  AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 5 MINUTE)
  AND status IN ('QUEUE', 'INCALL');
"&lt;/span&gt;

&lt;span class="c"&gt;# Calculate real-time dial rate&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
  SELECT 
    COUNT(*) as calls_last_minute
  FROM vicidial_log 
  WHERE campaign_id = 'RATIO_01' 
  AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 1 MINUTE);
"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 5: Progressive Dialing Setup
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Understanding Progressive Dialing
&lt;/h3&gt;

&lt;p&gt;Progressive dialing is the most conservative:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Agent clicks &lt;strong&gt;DIAL&lt;/strong&gt; button manually (or via macro)&lt;/li&gt;
&lt;li&gt;One call per button click&lt;/li&gt;
&lt;li&gt;Zero abandon rate (no automatic dialing)&lt;/li&gt;
&lt;li&gt;Best for new campaigns or compliance-heavy environments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Configure Campaign for Progressive Mode
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; 
  &lt;span class="n"&gt;dial_method&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'INBOUND'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;auto_dial_level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;drop_percentage&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;scheduled_callbacks&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ENABLED'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;pause_dialing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'N'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'PROGRESSIVE_01'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Configure Agent Macro for One-Click Dialing
&lt;/h3&gt;

&lt;p&gt;Edit the agent's hotkey configuration in &lt;code&gt;/agc/vicidial.php&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;Agent users can assign a dial macro. In ViciDial admin, under "User Settings," set:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Dial Prefix: 0  (Agent dials 0 + number, or auto-fills from lead)
Dial Method: PROGRESSIVE
Auto Dial: Disabled
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or configure via database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; 
  &lt;span class="n"&gt;auto_dial_mode&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'PROGRESSIVE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;auto_dial_level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;auto_call_override&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'OFF'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent_001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Enable Manual Dial Button in Agent Screen
&lt;/h3&gt;

&lt;p&gt;The standard ViciDial agent screen (/agc/vicidial.php) already includes a DIAL button. Ensure it's enabled:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in as an agent&lt;/li&gt;
&lt;li&gt;Lead information populates from the list&lt;/li&gt;
&lt;li&gt;Agent clicks &lt;strong&gt;DIAL&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Call connects to that single lead&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;No additional configuration is required for basic progressive dialing.&lt;/p&gt;

&lt;h2&gt;
  
  
  Section 6: Performance Tuning &amp;amp; Optimization
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Database Query Optimization
&lt;/h3&gt;

&lt;p&gt;ViciDial relies on frequent database queries. Optimize with proper indexing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Check existing indexes&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Add performance indexes if missing&lt;/span&gt;
&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_campaign_status&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_phone_number&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;lead_phone_number&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_call_date&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;ALTER&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; 
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_campaign_call_date&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_status_date&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;span class="k"&gt;ADD&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_user_date&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Optimize tables after adding indexes&lt;/span&gt;
&lt;span class="n"&gt;OPTIMIZE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;OPTIMIZE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;OPTIMIZE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_closer_log&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Asterisk Channel Configuration
&lt;/h3&gt;

&lt;p&gt;Increase available channels based on your trunking:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;; &lt;span class="n"&gt;In&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;conf&lt;/span&gt;
[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;maxforwards&lt;/span&gt;=&lt;span class="m"&gt;20&lt;/span&gt;
&lt;span class="n"&gt;udpbindaddr&lt;/span&gt;=&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;tcpenable&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;tcpbindaddr&lt;/span&gt;=&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;tlsenable&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;srvlookup&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;pedantic&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;maxcallbitrate&lt;/span&gt;=&lt;span class="m"&gt;256000&lt;/span&gt;
&lt;span class="n"&gt;autocreatepeer&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;relaxdtmf&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;rtpholdtimeout&lt;/span&gt;=&lt;span class="m"&gt;300&lt;/span&gt;
&lt;span class="n"&gt;rtpkeepalive&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;rtptimeout&lt;/span&gt;=&lt;span class="m"&gt;7200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CPU and Memory Limits
&lt;/h3&gt;

&lt;p&gt;Monitor resource usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Real-time system monitor&lt;/span&gt;
top &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;pidof asterisk&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Check memory usage&lt;/span&gt;
free &lt;span class="nt"&gt;-h&lt;/span&gt;

&lt;span class="c"&gt;# Limit ViciDial processes if needed&lt;/span&gt;
&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-m&lt;/span&gt; 2097152  &lt;span class="c"&gt;# 2GB memory limit&lt;/span&gt;
&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 65536    &lt;span class="c"&gt;# 65K file descriptors&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Optimize vicidial_dialer.pl Performance
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/usr/share/astguiclient/vicidial_dialer.pl&lt;/code&gt; to reduce query frequency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight perl"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Around line 250, adjust loop sleep interval&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$loop_sleep&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;# 500ms between dial checks (higher = less CPU)&lt;/span&gt;

&lt;span class="c1"&gt;# Reduce the number of campaigns processed per cycle&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$campaigns_per_cycle&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;# Increase batch dial size for efficiency&lt;/span&gt;
&lt;span class="k"&gt;my&lt;/span&gt; &lt;span class="nv"&gt;$dial_batch_size&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;50&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Section 7: Troubleshooting Common Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue 1: Dialer Not Making Calls
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Campaign active but no calls initiated.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if dialer process is running&lt;/span&gt;
ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;vicidial_dialer.pl

&lt;span class="c"&gt;# Check error logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"dial&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;error"&lt;/span&gt;

&lt;span class="c"&gt;# Verify database connection&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT COUNT(*) FROM vicidial_list WHERE campaign_id='PREDICTIVE_01' AND status='NEW';"&lt;/span&gt;

&lt;span class="c"&gt;# Check Asterisk core&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show channels concise"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restart the dialer: &lt;code&gt;killall vicidial_dialer.pl &amp;amp;&amp;amp; sleep 2 &amp;amp;&amp;amp; /usr/share/astguiclient/vicidial_dialer.pl &amp;amp;&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Verify carrier registration: &lt;code&gt;asterisk -rx "sip show peers"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check campaign status in database: &lt;code&gt;UPDATE vicidial_campaigns SET pause_dialing='N' WHERE campaign_id='PREDICTIVE_01';&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue 2: High Call Drop Rate
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Drop percentage exceeding threshold; caller disconnect before agent connects.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check drop rate by call result&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
  SELECT 
    call_result,
    COUNT(*) as count,
    ROUND(COUNT(*) / (SELECT COUNT(*) FROM vicidial_log WHERE campaign_id='PREDICTIVE_01' AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 1 HOUR)) * 100, 2) as percentage
  FROM vicidial_log 
  WHERE campaign_id='PREDICTIVE_01' 
  AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 1 HOUR)
  GROUP BY call_result;
"&lt;/span&gt;

&lt;span class="c"&gt;# Check agent availability&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT user, COUNT(*) FROM vicidial_log WHERE campaign_id='PREDICTIVE_01' AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 1 HOUR) GROUP BY user;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce &lt;code&gt;auto_dial_level&lt;/code&gt; from 0.85 to 0.70&lt;/li&gt;
&lt;li&gt;Increase &lt;code&gt;drop_percentage&lt;/code&gt; threshold temporarily&lt;/li&gt;
&lt;li&gt;Add more agents to the campaign&lt;/li&gt;
&lt;li&gt;Check agent call handling times: &lt;code&gt;SELECT user, AVG(LENGTH_OF_CALL) FROM vicidial_log GROUP BY user;&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue 3: SIP Carrier Errors / Registration Failures
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Carrier shows UNREACHABLE; calls fail with SIP 503.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check SIP registration&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show registry"&lt;/span&gt;

&lt;span class="c"&gt;# Test carrier connectivity&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peer carrier_sirius"&lt;/span&gt;

&lt;span class="c"&gt;# Check carrier logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"sirius&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;carrier"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify carrier IP and credentials: &lt;code&gt;cat /etc/asterisk/sip-vicidial.conf | grep -A5 carrier_sirius&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Check network connectivity: &lt;code&gt;ping -c 5 carrier.sirius.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Restart SIP channel driver: &lt;code&gt;asterisk -rx "module reload res_sip"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue 4: Agent Screen Not Showing Leads
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Agent sees blank lead information despite calls in queue.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check lead list status&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT COUNT(*) FROM vicidial_list WHERE campaign_id='PREDICTIVE_01' AND status IN ('NEW', 'QUEUE');"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Check user campaign assignment&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT user, campaign_id FROM vicidial_users WHERE user='agent_001';"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Verify vicidial.php logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt; /var/log/apache2/error.log | &lt;span class="nb"&gt;grep &lt;/span&gt;vicidial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Assign user to campaign: &lt;code&gt;UPDATE vicidial_users SET campaign_id='PREDICTIVE_01' WHERE user='agent_001';&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Reload agent screen (Ctrl+R or refresh browser)&lt;/li&gt;
&lt;li&gt;Clear browser cache and cookies&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue 5: Calls Dialing to Wrong Number or Format
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms&lt;/strong&gt;: Calls connecting to incomplete or malformed numbers.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check last 10 call attempts&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
  SELECT 
    lead_id,
    lead_phone_number,
    phone_number_formatted,
    call_result
  FROM vicidial_log 
  WHERE campaign_id='PREDICTIVE_01' 
  ORDER BY call_date DESC LIMIT 10;
"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c"&gt;# Check dial plan&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan show from-internal"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Verify phone_number_format in campaign: Should be 'US' or 'INTL'&lt;/li&gt;
&lt;li&gt;Ensure lead phone numbers in vicidial_list don't include non-numeric characters (except +)&lt;/li&gt;
&lt;li&gt;Check extensions-vicidial.conf dial pattern: &lt;code&gt;exten =&amp;gt; _1NXXNXXXXXX&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Section 8: Production Monitoring &amp;amp; Maintenance
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Real-Time Dashboard Query
&lt;/h3&gt;

&lt;p&gt;Create a monitoring script to check campaign health:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /usr/local/bin/vicidial_monitor.sh&lt;/span&gt;

&lt;span class="nv"&gt;CAMPAIGN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"PREDICTIVE_01"&lt;/span&gt;
&lt;span class="nv"&gt;INTERVAL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;60

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== ViciDial Campaign Status: &lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt; ==="&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Time: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

  mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
    SELECT 
      'Active Agents' as metric, COUNT(DISTINCT user) as value 
    FROM vicidial_log 
    WHERE campaign_id='&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt;' 
    AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 5 MINUTE)
    AND status IN ('QUEUE', 'INCALL')
    UNION ALL
    SELECT 
      'Channels In Use', COUNT(*) 
    FROM vicidial_log 
    WHERE campaign_id='&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt;' 
    AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 5 MINUTE)
    UNION ALL
    SELECT 
      'Leads Pending', COUNT(*) 
    FROM vicidial_list 
    WHERE campaign_id='&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt;' AND status='NEW'
    UNION ALL
    SELECT 
      'Avg Talk Time (sec)', ROUND(AVG(LENGTH_OF_CALL)) 
    FROM vicidial_log 
    WHERE campaign_id='&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt;' 
    AND call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 1 HOUR)
    AND call_result='SALE';
  "&lt;/span&gt;

  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
  &lt;span class="nb"&gt;sleep&lt;/span&gt; &lt;span class="nv"&gt;$INTERVAL&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/vicidial_monitor.sh
/usr/local/bin/vicidial_monitor.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Regular Database Maintenance
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /usr/local/bin/vicidial_maintenance.sh&lt;/span&gt;

&lt;span class="c"&gt;# Backup database daily&lt;/span&gt;
mysqldump &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /backups/asterisk_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt;.sql

&lt;span class="c"&gt;# Purge old logs (keep 90 days)&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
  DELETE FROM vicidial_log WHERE call_date &amp;lt; DATE_SUB(NOW(), INTERVAL 90 DAY);
  DELETE FROM vicidial_closer_log WHERE call_date &amp;lt; DATE_SUB(NOW(), INTERVAL 90 DAY);
  OPTIMIZE TABLE vicidial_log;
  OPTIMIZE TABLE vicidial_closer_log;
"&lt;/span&gt;

&lt;span class="c"&gt;# Report on campaign performance&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
  SELECT 
    campaign_id,
    DATE(call_date) as date,
    COUNT(*) as total_calls,
    SUM(CASE WHEN call_result='SALE' THEN 1 ELSE 0 END) as sales,
    SUM(CASE WHEN call_result='DROPPED' THEN 1 ELSE 0 END) as dropped,
    ROUND(SUM(CASE WHEN call_result='DROPPED' THEN 1 ELSE 0 END) / COUNT(*) * 100, 2) as drop_rate_percent
  FROM vicidial_log
  WHERE call_date &amp;gt; DATE_SUB(NOW(), INTERVAL 7 DAY)
  GROUP BY campaign_id, DATE(call_date)
  ORDER BY campaign_id, date DESC;
"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /var/log/vicidial_daily_report.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Schedule in crontab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;

&lt;span class="c"&gt;# Add:&lt;/span&gt;
0 2 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/local/bin/vicidial_maintenance.sh &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;This tutorial covered the complete setup and tuning of ViciDial's three auto-dial modes:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Predictive Dialing&lt;/strong&gt; provides the highest contact rate and throughput by predicting agent availability and dialing ahead. Ideal for high-volume campaigns where some call drops are acceptable. Requires careful monitoring of drop rates and CPU usage.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Ratio-Based Dialing&lt;/strong&gt; maintains fixed dial multipliers (e.g., 3:1) per available agent. More predictable than predictive; suitable for mid-range campaigns. Requires less tuning but achieves lower contact rates than predictive.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Progressive Dialing&lt;/strong&gt; offers zero abandonment by requiring manual agent dial actions. Best for compliance-heavy environments and new campaigns. Maximizes agent control but minimizes throughput.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Key implementation steps:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Create campaigns and leads in the asterisk database&lt;/li&gt;
&lt;li&gt;Configure SIP carriers and Asterisk dialplan&lt;/li&gt;
&lt;li&gt;Enable the vicidial_dialer.pl background service&lt;/li&gt;
&lt;li&gt;Set auto_dial_level, drop_percentage, and dial_timeout per mode&lt;/li&gt;
&lt;li&gt;Optimize database indexes and Asterisk channel limits&lt;/li&gt;
&lt;li&gt;Monitor via SQL queries, Asterisk CLI, and real-time dashboards&lt;/li&gt;
&lt;li&gt;Troubleshoot using logs, database diagnostics, and SIP peer status checks&lt;/li&gt;
&lt;li&gt;Maintain via regular backups, log rotation, and performance reports&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Production deployments benefit from starting conservative (lower dial rates, higher drop thresholds) and gradually increasing intensity while monitoring agent satisfaction, call quality, and network capacity. Always maintain backups and test configuration changes in a staging environment first.&lt;/p&gt;

&lt;p&gt;For enterprise setups, consider implementing load balancing across multiple ViciDial servers and using dedicated trunk capacity with your carrier to ensure reliable, scalable operation.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>How to Upload a Lead List to ViciDial — CSV Format &amp; Mapping</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Thu, 13 Aug 2026 03:30:03 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/how-to-upload-a-lead-list-to-vicidial-csv-format-mapping-14c3</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/how-to-upload-a-lead-list-to-vicidial-csv-format-mapping-14c3</guid>
      <description>&lt;h1&gt;
  
  
  How to Upload a Lead List to ViciDial — CSV Format &amp;amp; Mapping
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master the complete process of importing lead lists into ViciDial with proper CSV formatting, field mapping, and validation techniques to avoid common import failures in production environments.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before uploading a lead list to ViciDial, ensure you have the following:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ViciDial installation&lt;/strong&gt; (tested on 2.14.x and later)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Admin access&lt;/strong&gt; to the web interface (/vicidial/admin.php)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database credentials&lt;/strong&gt; for the asterisk database&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sufficient disk space&lt;/strong&gt; in /var/spool/vicidial/LEADS_IN/ (typically 5GB+ for large lists)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Linux command-line access&lt;/strong&gt; to the ViciDial server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Campaign already created&lt;/strong&gt; in ViciDial (required before list assignment)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;MySQL/MariaDB client&lt;/strong&gt; installed on your local machine (if importing via SSH tunnel)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic understanding&lt;/strong&gt; of CSV format and field delimiters&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding ViciDial Lead List Structure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Core Lead Tables
&lt;/h3&gt;

&lt;p&gt;ViciDial stores lead data primarily in two tables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Main lead table&lt;/span&gt;
&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;

&lt;span class="c1"&gt;-- This shows the structure containing:&lt;/span&gt;
&lt;span class="c1"&gt;-- lead_id (primary key, auto-increment)&lt;/span&gt;
&lt;span class="c1"&gt;-- phone_number (VARCHAR 20)&lt;/span&gt;
&lt;span class="c1"&gt;-- first_name, last_name, address, city, state, postal_code&lt;/span&gt;
&lt;span class="c1"&gt;-- email, vendor_lead_code, source_id&lt;/span&gt;
&lt;span class="c1"&gt;-- list_id (foreign key to campaign list)&lt;/span&gt;
&lt;span class="c1"&gt;-- status (NEW, ACTIVE, etc.)&lt;/span&gt;
&lt;span class="c1"&gt;-- gmt_offset_now (for timezone handling)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The most critical fields for import are:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;phone_number&lt;/strong&gt; – Required; primary dialing field&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;list_id&lt;/strong&gt; – Links lead to campaign&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;first_name, last_name&lt;/strong&gt; – Optional but recommended for agent context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;email&lt;/strong&gt; – Optional but valuable for callback/document delivery&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;vendor_lead_code&lt;/strong&gt; – Unique external identifier; prevents duplicates&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;source_id&lt;/strong&gt; – Tracks lead source for compliance/analytics&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;gmt_offset_now&lt;/strong&gt; – Critical for timezone-aware calling windows&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  List Management in ViciDial
&lt;/h3&gt;

&lt;p&gt;Campaigns in ViciDial are containers with associated lists. Each campaign can have multiple lists, and each list contains leads.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- View existing campaigns&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dial_method&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- View lists under a campaign&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lead_count&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_lists&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Preparing Your CSV File
&lt;/h2&gt;

&lt;h3&gt;
  
  
  CSV Format Specifications
&lt;/h3&gt;

&lt;p&gt;ViciDial expects a specific CSV structure with proper field ordering and encoding.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;phone_number,first_name,last_name,email,vendor_lead_code,source_id,gmt_offset_now
5551234567,John,Doe,john@example.com,VND-123456,WEB,America/New_York
5559876543,Jane,Smith,jane@example.com,VND-123457,PHONE,America/Chicago
5559998888,Bob,Johnson,bob@example.com,VND-123458,REFERRAL,America/Los_Angeles
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Required vs. Optional Fields
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Required fields:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;phone_number&lt;/code&gt; – E.164 or 10-digit format (ViciDial accepts both)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Strongly recommended:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;first_name&lt;/code&gt; – Improves agent interaction quality&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;vendor_lead_code&lt;/code&gt; – Prevents duplicate imports&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;gmt_offset_now&lt;/code&gt; – Essential for respecting TCPA calling windows&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Optional but useful:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;last_name&lt;/code&gt;, &lt;code&gt;email&lt;/code&gt;, &lt;code&gt;address&lt;/code&gt;, &lt;code&gt;city&lt;/code&gt;, &lt;code&gt;state&lt;/code&gt;, &lt;code&gt;postal_code&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;source_id&lt;/code&gt; – Track which source generated the lead&lt;/li&gt;
&lt;li&gt;Custom fields (if your ViciDial instance uses extended schema)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  CSV Field Mapping Reference
&lt;/h3&gt;

&lt;p&gt;Here's the complete list of importable fields and their SQL column equivalents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight markdown"&gt;&lt;code&gt;CSV Field Name          | SQL Table Column    | Data Type    | Max Length
phone_number            | phone_number        | VARCHAR(20)  | 20
first_name              | first_name          | VARCHAR(50)  | 50
last_name               | last_name           | VARCHAR(50)  | 50
middle_initial          | middle_initial      | VARCHAR(1)   | 1
address                 | address             | VARCHAR(100) | 100
city                    | city                | VARCHAR(50)  | 50
state                   | state               | VARCHAR(2)   | 2
postal_code             | postal_code         | VARCHAR(10)  | 10
country_code            | country_code        | VARCHAR(3)   | 3
email                   | email               | VARCHAR(100) | 100
vendor_lead_code        | vendor_lead_code    | VARCHAR(20)  | 20
source_id               | source_id           | VARCHAR(50)  | 50
gmt_offset_now          | gmt_offset_now      | VARCHAR(10)  | 10
phone_code              | phone_code          | VARCHAR(20)  | 20
lead_source_id          | lead_source_id      | VARCHAR(20)  | 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  CSV Validation Rules
&lt;/h3&gt;

&lt;p&gt;Before uploading, validate your CSV meets these requirements:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;No header row&lt;/strong&gt; – ViciDial list upload expects data rows only (headers are optional in UI but not recommended)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consistent field count&lt;/strong&gt; – Every row must have the same number of columns&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Proper encoding&lt;/strong&gt; – UTF-8 without BOM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Phone number format&lt;/strong&gt; – 10+ digits, no spaces/dashes in raw CSV (formatting applied on import)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No embedded newlines&lt;/strong&gt; – Use proper CSV escaping if fields contain commas&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File size limits&lt;/strong&gt; – Practical limit 50MB per file; split larger lists&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Creating a Validation Script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# validate_csv.sh - Pre-import CSV validation&lt;/span&gt;

&lt;span class="nv"&gt;CSV_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ERROR: File not found: &lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Check file encoding&lt;/span&gt;
&lt;span class="nv"&gt;FILE_ENCODING&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;file &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;--mime-encoding&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$FILE_ENCODING&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"utf-8"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WARNING: File encoding is &lt;/span&gt;&lt;span class="nv"&gt;$FILE_ENCODING&lt;/span&gt;&lt;span class="s2"&gt;, expected utf-8"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Count lines&lt;/span&gt;
&lt;span class="nv"&gt;LINE_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Total lines: &lt;/span&gt;&lt;span class="nv"&gt;$LINE_COUNT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Check for consistent field count (assuming comma-delimited)&lt;/span&gt;
&lt;span class="nv"&gt;FIRST_LINE_FIELDS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="s1"&gt;'{print NF}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Expected fields per row: &lt;/span&gt;&lt;span class="nv"&gt;$FIRST_LINE_FIELDS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Validate all rows have same field count&lt;/span&gt;
&lt;span class="nv"&gt;INVALID_ROWS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;expected&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$FIRST_LINE_FIELDS&lt;/span&gt; &lt;span class="s1"&gt;'{
    if (NF != expected) print NR": expected "$FIRST_LINE_FIELDS", got "NF
}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INVALID_ROWS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ERROR: Found rows with inconsistent field counts:"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INVALID_ROWS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Extract and validate phone numbers (column 1)&lt;/span&gt;
&lt;span class="nv"&gt;INVALID_PHONES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="s1"&gt;'{
    gsub(/[^0-9]/, "", $1)
    if (length($1) &amp;lt; 10) print NR": invalid phone "$1
}'&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INVALID_PHONES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WARNING: Found potentially invalid phone numbers:"&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INVALID_PHONES&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Validation complete!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x validate_csv.sh
./validate_csv.sh leads.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Uploading via Web Interface
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step-by-Step Web Upload
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Log into ViciDial Admin Interface:&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;   https://your-vicidial-server/vicidial/admin.php
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Navigate to List Management:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Campaigns&lt;/strong&gt; → &lt;strong&gt;Lists&lt;/strong&gt; (or &lt;strong&gt;Leads&lt;/strong&gt; in newer versions)&lt;/li&gt;
&lt;li&gt;Select the target campaign from the dropdown&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Create New List (if needed):&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Click &lt;strong&gt;Create List&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Enter list name (e.g., "Q4_2024_Leads")&lt;/li&gt;
&lt;li&gt;Set list priority (higher = called first)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Add List&lt;/strong&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Upload Leads to List:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Select the list from the dropdown&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;Upload Leads&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Choose CSV file from local machine&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Important:&lt;/strong&gt; Configure field mapping (see next section)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Field Mapping Configuration
&lt;/h3&gt;

&lt;p&gt;When you upload a CSV, ViciDial prompts you to map columns to database fields.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;ViciDial Upload Field Mapping Dialog:

CSV Column 1 → phone_number (REQUIRED)
CSV Column 2 → first_name
CSV Column 3 → last_name
CSV Column 4 → email
CSV Column 5 → vendor_lead_code
CSV Column 6 → source_id
CSV Column 7 → gmt_offset_now

[Checkbox] Skip first row as header
[Checkbox] Replace existing leads
[Checkbox] Auto-detect duplicates by phone_number

[UPLOAD LEADS]
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical mapping tips:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Leave unused columns unmapped (set to "— ignore —")&lt;/li&gt;
&lt;li&gt;Ensure phone_number is always mapped to Column 1&lt;/li&gt;
&lt;li&gt;If your CSV has a header row, check "Skip first row as header"&lt;/li&gt;
&lt;li&gt;Leave "Replace existing leads" unchecked unless you're refreshing the entire list&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Command-Line Upload Method
&lt;/h2&gt;

&lt;p&gt;For production environments and large-scale imports, use the CLI approach which is faster and more scriptable.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using the ViciDial Import Script
&lt;/h3&gt;

&lt;p&gt;ViciDial includes a Perl script for direct database imports:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Location of import script&lt;/span&gt;
/usr/share/astguiclient/VICIDIAL_add_lead_list.pl

&lt;span class="c"&gt;# Basic syntax&lt;/span&gt;
perl /usr/share/astguiclient/VICIDIAL_add_lead_list.pl &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--listname&lt;/span&gt; &lt;span class="s2"&gt;"Q4_2024_Leads"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--campaign&lt;/span&gt; &lt;span class="s2"&gt;"TEST_CAMPAIGN"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="s2"&gt;"leads.csv"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--phonefield&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--firstnamefield&lt;/span&gt; 2 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--lastnamefield&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--emailfield&lt;/span&gt; 4 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--vendorfield&lt;/span&gt; 5 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--sourcefield&lt;/span&gt; 6 &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;--tzfield&lt;/span&gt; 7
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Complete CLI Import Example
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# import_leads.sh - Production lead import script&lt;/span&gt;

&lt;span class="nv"&gt;CAMPAIGN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"TEST_CAMPAIGN"&lt;/span&gt;
&lt;span class="nv"&gt;LIST_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;_import"&lt;/span&gt;
&lt;span class="nv"&gt;CSV_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"leads.csv"&lt;/span&gt;
&lt;span class="nv"&gt;DB_HOST&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"localhost"&lt;/span&gt;
&lt;span class="nv"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cron"&lt;/span&gt;
&lt;span class="nv"&gt;DB_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1234"&lt;/span&gt;
&lt;span class="nv"&gt;DB_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"asterisk"&lt;/span&gt;

&lt;span class="c"&gt;# Validate file&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ERROR: CSV file not found: &lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Count leads&lt;/span&gt;
&lt;span class="nv"&gt;LEAD_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Importing &lt;/span&gt;&lt;span class="nv"&gt;$LEAD_COUNT&lt;/span&gt;&lt;span class="s2"&gt; leads to campaign: &lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Run import&lt;/span&gt;
perl /usr/share/astguiclient/VICIDIAL_add_lead_list.pl &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--listname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LIST_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--campaign&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--phonefield&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--firstnamefield&lt;/span&gt; 2 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--lastnamefield&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--emailfield&lt;/span&gt; 4 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--vendorfield&lt;/span&gt; 5 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--sourcefield&lt;/span&gt; 6 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--tzfield&lt;/span&gt; 7 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dbhost&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_HOST&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dbuser&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_USER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dbpass&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_PASS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dbname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--active&lt;/span&gt; &lt;span class="s2"&gt;"Y"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--skipdup&lt;/span&gt; &lt;span class="s2"&gt;"Y"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tee &lt;/span&gt;import_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;.log

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Import complete. Check log for details."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Direct MySQL Import
&lt;/h3&gt;

&lt;p&gt;For advanced users, direct SQL insertion can be faster for very large lists (10M+ leads):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# direct_sql_import.sh - Ultra-high-volume import&lt;/span&gt;

&lt;span class="nv"&gt;CSV_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;CAMPAIGN_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"TEST_CAMPAIGN"&lt;/span&gt;
&lt;span class="nv"&gt;LIST_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"9001"&lt;/span&gt;

&lt;span class="c"&gt;# Create staging table&lt;/span&gt;
mysql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
CREATE TEMPORARY TABLE vicidial_list_staging LIKE vicidial_list;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Load CSV into staging table&lt;/span&gt;
mysql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
LOAD DATA LOCAL INFILE '&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="sh"&gt;'
INTO TABLE vicidial_list_staging
FIELDS TERMINATED BY ','
LINES TERMINATED BY '&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="sh"&gt;'
(phone_number, first_name, last_name, email, vendor_lead_code, source_id, gmt_offset_now);
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Insert from staging to production, skipping duplicates&lt;/span&gt;
mysql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
INSERT INTO vicidial_list 
  (phone_number, first_name, last_name, email, vendor_lead_code, 
   source_id, gmt_offset_now, list_id, campaign_id, status, entry_date)
SELECT 
  phone_number, first_name, last_name, email, vendor_lead_code,
  source_id, gmt_offset_now, &lt;/span&gt;&lt;span class="nv"&gt;$LIST_ID&lt;/span&gt;&lt;span class="sh"&gt;, '&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN_ID&lt;/span&gt;&lt;span class="sh"&gt;', 'NEW', NOW()
FROM vicidial_list_staging
WHERE phone_number NOT IN (
  SELECT phone_number FROM vicidial_list WHERE list_id = &lt;/span&gt;&lt;span class="nv"&gt;$LIST_ID&lt;/span&gt;&lt;span class="sh"&gt;
)
AND phone_number IS NOT NULL
AND LENGTH(REPLACE(phone_number, REGEXP_SUBSTR(phone_number, '[^0-9]'), '')) &amp;gt;= 10;

-- Update lead count
UPDATE vicidial_lists 
SET lead_count = (SELECT COUNT(*) FROM vicidial_list WHERE list_id = &lt;/span&gt;&lt;span class="nv"&gt;$LIST_ID&lt;/span&gt;&lt;span class="sh"&gt;)
WHERE list_id = &lt;/span&gt;&lt;span class="nv"&gt;$LIST_ID&lt;/span&gt;&lt;span class="sh"&gt;;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Import complete."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Handling Timezones (Critical for TCPA Compliance)
&lt;/h2&gt;

&lt;p&gt;ViciDial respects Do Not Call (DNC) regulations and time-of-day restrictions based on the &lt;code&gt;gmt_offset_now&lt;/code&gt; field.&lt;/p&gt;

&lt;h3&gt;
  
  
  Timezone Values Reference
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;phone_number,first_name,last_name,gmt_offset_now
5551234567,John,Doe,America/New_York
5559876543,Jane,Smith,America/Chicago
5559998888,Bob,Johnson,America/Denver
5551112222,Alice,Brown,America/Los_Angeles
5551113333,Charlie,Davis,America/Anchorage
5551114444,Diana,Evans,Pacific/Honolulu
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Extracting Timezone from Phone Area Code
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# area_code_timezone.sh - Auto-detect timezone from area code&lt;/span&gt;

&lt;span class="c"&gt;# Create mapping file&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; area_code_tz.txt &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
201|America/New_York
202|America/New_York
203|America/New_York
212|America/New_York
# ... (continue for all area codes)
213|America/Los_Angeles
415|America/Los_Angeles
619|America/Los_Angeles
702|America/Los_Angeles
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Process CSV with timezone detection&lt;/span&gt;
&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="s1"&gt;'{
    area_code = substr($1, 1, 3)
    cmd = "grep \"^" area_code "|\" area_code_tz.txt | cut -d\"|\" -f2"
    cmd | getline timezone
    close(cmd)
    if (timezone == "") timezone = "America/Chicago"  # default
    print $0 "," timezone
}'&lt;/span&gt; input_leads.csv &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; leads_with_tz.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Duplicate Handling and Lead Deduplication
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Preventing Duplicate Imports
&lt;/h3&gt;

&lt;p&gt;ViciDial's &lt;code&gt;vendor_lead_code&lt;/code&gt; field is your primary defense against duplicates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Before importing, deduplicate by vendor_lead_code&lt;/span&gt;
&lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="nt"&gt;-k5&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; leads.csv &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; leads_dedup.csv

&lt;span class="c"&gt;# Or using awk&lt;/span&gt;
&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="s1"&gt;'!seen[$5]++'&lt;/span&gt; leads.csv &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; leads_dedup.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Checking for Existing Leads
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Find leads already in the system by vendor_lead_code&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vendor_lead_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;vendor_lead_code&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;vendor_lead_code&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;new_import_list&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Find potential phone duplicates&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; 
&lt;span class="k"&gt;HAVING&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Automated Deduplication Script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# deduplicate_leads.sh&lt;/span&gt;

&lt;span class="nv"&gt;INPUT_CSV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT_CSV&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;INPUT_CSV&lt;/span&gt;&lt;span class="p"&gt;%.csv&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_dedup.csv"&lt;/span&gt;

&lt;span class="c"&gt;# Extract headers (if present)&lt;/span&gt;
&lt;span class="nv"&gt;HEADERS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INPUT_CSV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Remove duplicates, preserve first occurrence&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$HEADERS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; +2 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INPUT_CSV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="nt"&gt;-k5&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_CSV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nv"&gt;ORIGINAL_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; +2 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$INPUT_CSV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;DEDUP_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; +2 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_CSV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;REMOVED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;ORIGINAL_COUNT &lt;span class="o"&gt;-&lt;/span&gt; DEDUP_COUNT&lt;span class="k"&gt;))&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Original leads: &lt;/span&gt;&lt;span class="nv"&gt;$ORIGINAL_COUNT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"After dedup: &lt;/span&gt;&lt;span class="nv"&gt;$DEDUP_COUNT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Removed duplicates: &lt;/span&gt;&lt;span class="nv"&gt;$REMOVED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Output: &lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT_CSV&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Monitoring Upload Progress
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Checking Upload Status via Database
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Monitor ongoing import&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;lead_count&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;last_update_date&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_lists&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;MAX&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_lists&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Check lead distribution&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Check for import errors&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real-Time Import Monitoring
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# monitor_import.sh - Watch import progress&lt;/span&gt;

&lt;span class="nv"&gt;LIST_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"9001"&lt;/span&gt;
&lt;span class="nv"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cron"&lt;/span&gt;
&lt;span class="nv"&gt;DB_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1234"&lt;/span&gt;
&lt;span class="nv"&gt;DB_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"asterisk"&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;CURRENT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;mysql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_USER&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_PASS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$DB_NAME&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;-sN&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT COUNT(*) FROM vicidial_list WHERE list_id = &lt;/span&gt;&lt;span class="nv"&gt;$LIST_ID&lt;/span&gt;&lt;span class="s2"&gt;;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="nv"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%d %H:%M:%S'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;] Leads in list: &lt;/span&gt;&lt;span class="nv"&gt;$CURRENT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="nb"&gt;sleep &lt;/span&gt;10
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting Common Import Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue: "File Not Found" or Permission Denied
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; CSV file not in expected directory or incorrect permissions&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ensure file is readable&lt;/span&gt;
&lt;span class="nb"&gt;chmod &lt;/span&gt;644 leads.csv

&lt;span class="c"&gt;# Copy to ViciDial's standard upload directory&lt;/span&gt;
&lt;span class="nb"&gt;cp &lt;/span&gt;leads.csv /var/spool/vicidial/LEADS_IN/

&lt;span class="c"&gt;# Verify permissions&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /var/spool/vicidial/LEADS_IN/ | &lt;span class="nb"&gt;grep &lt;/span&gt;leads.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: "Invalid Phone Number Format"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Phone numbers contain non-numeric characters or are too short&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# clean_phones.sh&lt;/span&gt;

&lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="s1"&gt;'s/[^0-9,\n]//g'&lt;/span&gt; leads.csv &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; leads_clean.csv

&lt;span class="c"&gt;# Verify minimum 10 digits&lt;/span&gt;
&lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="s1"&gt;'{
    gsub(/[^0-9]/, "", $1)
    if (length($1) &amp;gt;= 10) print $0
}'&lt;/span&gt; leads_clean.csv &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; leads_valid.csv
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: "Field Mapping Mismatch" or Blank Imports
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Incorrect field mapping or CSV column order mismatch&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Verify your CSV columns match your mapping:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Show first row with column numbers&lt;/span&gt;
&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt; leads.csv | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-F&lt;/span&gt;&lt;span class="s1"&gt;','&lt;/span&gt; &lt;span class="s1"&gt;'{for(i=1;i&amp;lt;=NF;i++) print i": "$i}'&lt;/span&gt;

&lt;span class="c"&gt;# Expected output should match your mapping:&lt;/span&gt;
&lt;span class="c"&gt;# 1: phone_number&lt;/span&gt;
&lt;span class="c"&gt;# 2: first_name&lt;/span&gt;
&lt;span class="c"&gt;# 3: last_name&lt;/span&gt;
&lt;span class="c"&gt;# etc.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Duplicate Leads Being Imported
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; &lt;code&gt;vendor_lead_code&lt;/code&gt; not set or duplicate checking disabled&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if vendor_lead_code is unique&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"SELECT vendor_lead_code, COUNT(*) FROM vicidial_list 
   WHERE list_id = 9001 AND vendor_lead_code IS NOT NULL 
   GROUP BY vendor_lead_code HAVING COUNT(*) &amp;gt; 1 LIMIT 20;"&lt;/span&gt;

&lt;span class="c"&gt;# Enable duplicate checking in future imports via web UI:&lt;/span&gt;
&lt;span class="c"&gt;# Check: [X] Auto-detect duplicates by phone_number&lt;/span&gt;
&lt;span class="c"&gt;# Or use CLI: --skipdup "Y"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Out of Memory During Large Import
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Importing massive lists (&amp;gt;50M leads) with insufficient RAM&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# batch_import.sh - Split large files into chunks&lt;/span&gt;

&lt;span class="nv"&gt;CSV_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;CHUNK_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;100000
&lt;span class="nv"&gt;CAMPAIGN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"TEST_CAMPAIGN"&lt;/span&gt;

&lt;span class="nv"&gt;TOTAL_LINES&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;CHUNKS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt;&lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$TOTAL_LINES&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="nv"&gt;$CHUNK_SIZE&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="k"&gt;))&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Splitting &lt;/span&gt;&lt;span class="nv"&gt;$TOTAL_LINES&lt;/span&gt;&lt;span class="s2"&gt; lines into &lt;/span&gt;&lt;span class="nv"&gt;$CHUNKS&lt;/span&gt;&lt;span class="s2"&gt; chunks of &lt;/span&gt;&lt;span class="nv"&gt;$CHUNK_SIZE&lt;/span&gt;&lt;span class="s2"&gt;..."&lt;/span&gt;

&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;seq &lt;/span&gt;1 &lt;span class="nv"&gt;$CHUNKS&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;START&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="o"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$CHUNK_SIZE&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;
    &lt;span class="nv"&gt;END&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;$((&lt;/span&gt; &lt;span class="nv"&gt;$i&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;$CHUNK_SIZE&lt;/span&gt; &lt;span class="k"&gt;))&lt;/span&gt;

    &lt;span class="nv"&gt;CHUNK_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"chunk_&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.csv"&lt;/span&gt;
    &lt;span class="nb"&gt;sed&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;START&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;END&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;p"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CHUNK_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Importing chunk &lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="nv"&gt;$CHUNK_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    perl /usr/share/astguiclient/VICIDIAL_add_lead_list.pl &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--listname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CAMPAIGN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;_chunk_&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--campaign&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CHUNK_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--phonefield&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--firstnamefield&lt;/span&gt; 2 &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--lastnamefield&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--dbhost&lt;/span&gt; localhost &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--dbuser&lt;/span&gt; cron &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--dbpass&lt;/span&gt; 1234 &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--dbname&lt;/span&gt; asterisk &lt;span class="se"&gt;\&lt;/span&gt;
        &lt;span class="nt"&gt;--active&lt;/span&gt; &lt;span class="s2"&gt;"Y"&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tee&lt;/span&gt; &lt;span class="s2"&gt;"import_chunk_&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;i&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.log"&lt;/span&gt;

    &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CHUNK_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

    &lt;span class="nb"&gt;sleep &lt;/span&gt;5  &lt;span class="c"&gt;# Prevent database strain&lt;/span&gt;
&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"All chunks imported."&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Leads Show "NEW" Status But Don't Dial
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Campaign not active or dialers not running&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verify campaign is active&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"SELECT campaign_id, campaign_name, active FROM vicidial_campaigns 
   WHERE campaign_id = 'TEST_CAMPAIGN';"&lt;/span&gt;

&lt;span class="c"&gt;# Check if dialers are running&lt;/span&gt;
ps aux | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"vicidial_dial|[p]erl.*dial"&lt;/span&gt;

&lt;span class="c"&gt;# Start ViciDial daemons if stopped&lt;/span&gt;
systemctl restart vicidial

&lt;span class="c"&gt;# Check for dialer errors in logs&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; dial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Slow Import Speed
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Single-threaded import, high disk I/O, or database lock contention&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check database performance&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SHOW PROCESSLIST;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; vicidial

&lt;span class="c"&gt;# Optimize table before import&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"OPTIMIZE TABLE vicidial_list;"&lt;/span&gt;

&lt;span class="c"&gt;# Increase insert buffer during import&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
SET SESSION insert_delayed_insert_limit=100000;
SET SESSION bulk_insert_buffer_size=16000000;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Use parallel import with multiple chunks&lt;/span&gt;
&lt;span class="c"&gt;# (See batch_import.sh above)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Database Verification After Import
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Post-Import Validation Queries
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Count total leads imported&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_leads&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify required fields populated&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; 
    &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;missing_phone&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;missing_first&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;vendor_lead_code&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;missing_vendor_code&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Check status distribution&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; 
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify timezone distribution&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;gmt_offset_now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;gmt_offset_now&lt;/span&gt; 
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Find any malformed phone numbers&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt; 
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;LENGTH&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;REPLACE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;REGEXP_SUBSTR&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'[^0-9]'&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="s1"&gt;''&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt; 
     &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify list_id assignment&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;lead_count&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_lists&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;9001&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Production Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pre-Import Checklist
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# pre_import_checklist.sh&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== ViciDial Pre-Import Checklist ==="&lt;/span&gt;

&lt;span class="c"&gt;# 1. Backup database&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ ] Backup database"&lt;/span&gt;
mysqldump &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; backup_&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;.sql

&lt;span class="c"&gt;# 2. Validate CSV&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ ] Validate CSV format and encoding"&lt;/span&gt;
file &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;--mime-encoding&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Check campaign exists&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ ] Verify campaign exists"&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="nt"&gt;-sN&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"SELECT campaign_id FROM vicidial_campaigns WHERE campaign_id = 'TEST_CAMPAIGN';"&lt;/span&gt;

&lt;span class="c"&gt;# 4. Check disk space&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ ] Check available disk space"&lt;/span&gt;
&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; /var/spool/vicidial/

&lt;span class="c"&gt;# 5. Check database connection&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ ] Test database connection"&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT COUNT(*) FROM vicidial_list LIMIT 1;"&lt;/span&gt;

&lt;span class="c"&gt;# 6. Verify daemons running&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[ ] Verify ViciDial daemons running"&lt;/span&gt;
ps aux | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"vicidial_dial|vicidial_agent"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nb"&gt;grep

echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Checklist Complete ==="&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Backup Strategy
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# backup_before_import.sh&lt;/span&gt;

&lt;span class="nv"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d_%H%M%S&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;BACKUP_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/backups/vicidial"&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Creating database backup: &lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_DIR&lt;/span&gt;&lt;span class="s2"&gt;/asterisk_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.sql.gz"&lt;/span&gt;
mysqldump &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; &lt;span class="nt"&gt;--single-transaction&lt;/span&gt; &lt;span class="nt"&gt;--quick&lt;/span&gt; asterisk | &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nb"&gt;gzip&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_DIR&lt;/span&gt;&lt;span class="s2"&gt;/asterisk_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.sql.gz"&lt;/span&gt;

&lt;span class="c"&gt;# Verify backup&lt;/span&gt;
&lt;span class="nb"&gt;gunzip&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_DIR&lt;/span&gt;&lt;span class="s2"&gt;/asterisk_&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.sql.gz"&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Backup verified successfully"&lt;/span&gt;
&lt;span class="k"&gt;else
    &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ERROR: Backup verification failed!"&lt;/span&gt;
    &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Keep only last 10 backups&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$BACKUP_DIR&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;/asterisk_&lt;span class="k"&gt;*&lt;/span&gt;.sql.gz | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; +11 | xargs &lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Logging and Audit Trail
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# import_with_audit.sh&lt;/span&gt;

&lt;span class="nv"&gt;IMPORT_LOG&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/log/vicidial/lead_imports.log"&lt;/span&gt;
&lt;span class="nv"&gt;CSV_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nv"&gt;CAMPAIGN&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"TEST_CAMPAIGN"&lt;/span&gt;

&lt;span class="c"&gt;# Log import start&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%d %H:%M:%S'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;] Starting import: &lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IMPORT_LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Get file metadata&lt;/span&gt;
&lt;span class="nv"&gt;FILE_SIZE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;du&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;cut&lt;/span&gt; &lt;span class="nt"&gt;-f1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;FILE_HASH&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;md5sum&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
&lt;span class="nv"&gt;LEAD_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt; &amp;lt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%d %H:%M:%S'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;] File: &lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt; | Size: &lt;/span&gt;&lt;span class="nv"&gt;$FILE_SIZE&lt;/span&gt;&lt;span class="s2"&gt; | Leads: &lt;/span&gt;&lt;span class="nv"&gt;$LEAD_COUNT&lt;/span&gt;&lt;span class="s2"&gt; | MD5: &lt;/span&gt;&lt;span class="nv"&gt;$FILE_HASH&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IMPORT_LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Run import with error capturing&lt;/span&gt;
perl /usr/share/astguiclient/VICIDIAL_add_lead_list.pl &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--listname&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CAMPAIGN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;_&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--campaign&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--file&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$CSV_FILE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--phonefield&lt;/span&gt; 1 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--firstnamefield&lt;/span&gt; 2 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--lastnamefield&lt;/span&gt; 3 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--emailfield&lt;/span&gt; 4 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--vendorfield&lt;/span&gt; 5 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--sourcefield&lt;/span&gt; 6 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--tzfield&lt;/span&gt; 7 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dbhost&lt;/span&gt; localhost &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dbuser&lt;/span&gt; cron &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dbpass&lt;/span&gt; 1234 &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--dbname&lt;/span&gt; asterisk &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="nt"&gt;--active&lt;/span&gt; &lt;span class="s2"&gt;"Y"&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tee&lt;/span&gt; &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IMPORT_LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c"&gt;# Log completion&lt;/span&gt;
&lt;span class="nv"&gt;FINAL_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p1234&lt;/span&gt; asterisk &lt;span class="nt"&gt;-sN&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
    &lt;span class="s2"&gt;"SELECT COUNT(*) FROM vicidial_list WHERE list_id = (SELECT MAX(list_id) FROM vicidial_lists);"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%d %H:%M:%S'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;] Import complete. Final lead count: &lt;/span&gt;&lt;span class="nv"&gt;$FINAL_COUNT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$IMPORT_LOG&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Uploading lead lists to ViciDial requires careful attention to CSV formatting, field mapping, and validation. The key steps are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Prepare your CSV&lt;/strong&gt; with proper encoding (UTF-8), consistent field counts, and valid phone numbers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Map fields correctly&lt;/strong&gt;, ensuring phone_number is primary and vendor_lead_code is set for duplicate detection&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Set timezones&lt;/strong&gt; (gmt_offset_now) for TCPA compliance and proper calling windows&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Choose your upload method&lt;/strong&gt; — web UI for small lists, CLI for production/large-scale imports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate after import&lt;/strong&gt; using database queries to ensure data integrity&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Implement safeguards&lt;/strong&gt; with backups, deduplication, and audit logging for production reliability&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For optimal results in production environments:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Always deduplicate leads before import using &lt;code&gt;vendor_lead_code&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Split very large lists (&amp;gt;50M leads) into chunks to avoid memory issues&lt;/li&gt;
&lt;li&gt;Test imports with a small sample first before running full campaigns&lt;/li&gt;
&lt;li&gt;Monitor upload progress with real-time database queries&lt;/li&gt;
&lt;li&gt;Keep comprehensive logs and backups for compliance and troubleshooting&lt;/li&gt;
&lt;li&gt;Use the CLI/Perl scripts for scriptable, repeatable imports rather than relying on the web UI&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;With these practices, you can reliably and efficiently manage lead lists at any scale in ViciDial production environments.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>How to Change Campaign Dial Speed in ViciDial</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Wed, 12 Aug 2026 03:30:03 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/how-to-change-campaign-dial-speed-in-vicidial-p4n</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/how-to-change-campaign-dial-speed-in-vicidial-p4n</guid>
      <description>&lt;h1&gt;
  
  
  How to Change Campaign Dial Speed in ViciDial
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master dial speed adjustments for ViciDial campaigns to optimize agent productivity, improve call connection rates, and reduce idle time in your production Asterisk environment.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before modifying campaign dial speed settings, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Root or sudo access to your ViciDial server&lt;/li&gt;
&lt;li&gt;Access to the ViciDial admin panel with administrative privileges&lt;/li&gt;
&lt;li&gt;MySQL/MariaDB client access to the asterisk database&lt;/li&gt;
&lt;li&gt;Familiarity with basic ViciDial campaign configuration&lt;/li&gt;
&lt;li&gt;Understanding of your current calling volume and agent count&lt;/li&gt;
&lt;li&gt;Recent backup of your ViciDial database&lt;/li&gt;
&lt;li&gt;Knowledge of your Asterisk version (tested on 11.x, 13.x, 16.x, 18.x)&lt;/li&gt;
&lt;li&gt;Access to server command line via SSH or direct console&lt;/li&gt;
&lt;li&gt;At least one active campaign already created&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding Campaign Dial Speed in ViciDial
&lt;/h2&gt;

&lt;p&gt;Dial speed (also called "dial ratio" or "calls per agent") determines how many calls ViciDial will attempt to place for each available agent in a campaign. This setting is critical for both inbound and outbound calling operations.&lt;/p&gt;

&lt;h3&gt;
  
  
  What Dial Speed Controls
&lt;/h3&gt;

&lt;p&gt;The dial speed parameter governs:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Number of simultaneous calls attempted per agent&lt;/li&gt;
&lt;li&gt;Queue management and call distribution&lt;/li&gt;
&lt;li&gt;Agent idle time and workload balance&lt;/li&gt;
&lt;li&gt;System resource consumption on your Asterisk server&lt;/li&gt;
&lt;li&gt;Connection rates and answer supervision quality&lt;/li&gt;
&lt;li&gt;Overall dialing efficiency and campaign profitability&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Common Dial Speed Values
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1.0 - 1.2 (Conservative)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;One call per agent, minimal preview time&lt;/li&gt;
&lt;li&gt;Best for complex calls requiring agent preparation&lt;/li&gt;
&lt;li&gt;Lower abandonment rates&lt;/li&gt;
&lt;li&gt;Reduced system load&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.3 - 1.5 (Moderate)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Standard for most outbound campaigns&lt;/li&gt;
&lt;li&gt;Balanced productivity and call quality&lt;/li&gt;
&lt;li&gt;Typical industry standard&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;1.6 - 2.5 (Aggressive)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Multiple calls queued per agent&lt;/li&gt;
&lt;li&gt;Higher connection rates but increased abandonment&lt;/li&gt;
&lt;li&gt;Requires experienced agents&lt;/li&gt;
&lt;li&gt;Higher system resource usage&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;2.5+ (Power dialing)&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Maximum throughput mode&lt;/li&gt;
&lt;li&gt;Primarily for high-volume, simple messaging&lt;/li&gt;
&lt;li&gt;Risk of high abandonment rates&lt;/li&gt;
&lt;li&gt;Only for compliant campaigns&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Accessing the Admin Panel
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Via Web Interface
&lt;/h3&gt;

&lt;p&gt;Launch your browser and navigate to your ViciDial admin URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;http://your-vicidial-ip/vicidial/admin.php
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log in with your administrator credentials (typically the &lt;code&gt;cron&lt;/code&gt; user or administrative account).&lt;/p&gt;

&lt;p&gt;Click on &lt;strong&gt;Campaigns&lt;/strong&gt; from the main menu, then select your target campaign from the list.&lt;/p&gt;

&lt;h3&gt;
  
  
  Locating the Dial Speed Setting
&lt;/h3&gt;

&lt;p&gt;In the Campaign Edit screen, locate the &lt;strong&gt;Dial Speed&lt;/strong&gt; field. In most ViciDial versions, this appears in the main campaign settings section, often labeled:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Dial Speed&lt;/li&gt;
&lt;li&gt;Calls Per Agent&lt;/li&gt;
&lt;li&gt;Dial Ratio&lt;/li&gt;
&lt;li&gt;Agent Dial Speed&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The field typically accepts decimal values between 0.1 and 5.0.&lt;/p&gt;

&lt;h2&gt;
  
  
  Method 1: Changing Dial Speed via Web Admin Panel
&lt;/h2&gt;

&lt;p&gt;This is the most user-friendly approach for most administrators.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step-by-Step Process
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Campaigns&lt;/strong&gt; → Select Your Campaign&lt;/li&gt;
&lt;li&gt;Scroll to the campaign configuration section&lt;/li&gt;
&lt;li&gt;Locate the &lt;strong&gt;Dial Speed&lt;/strong&gt; field&lt;/li&gt;
&lt;li&gt;Enter your desired dial speed value (e.g., 1.5)&lt;/li&gt;
&lt;li&gt;Click &lt;strong&gt;SAVE&lt;/strong&gt; or &lt;strong&gt;UPDATE&lt;/strong&gt; button&lt;/li&gt;
&lt;li&gt;Confirm the change was applied&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Example Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Campaign: SALES_OUTBOUND_Q2
Current Dial Speed: 1.2
New Dial Speed: 1.8
Active Agents: 25
Expected simultaneous calls: 45 (25 agents × 1.8)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Immediate Effects
&lt;/h3&gt;

&lt;p&gt;Once saved:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The new dial speed takes effect within 1-2 minutes&lt;/li&gt;
&lt;li&gt;Existing calls continue on previous settings&lt;/li&gt;
&lt;li&gt;New outbound calls follow the new dial speed&lt;/li&gt;
&lt;li&gt;No service interruption occurs&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Method 2: Direct Database Modification
&lt;/h2&gt;

&lt;p&gt;For bulk changes or scripted deployments, you can modify the ViciDial database directly.&lt;/p&gt;

&lt;h3&gt;
  
  
  Identifying the Campaign
&lt;/h3&gt;

&lt;p&gt;First, confirm your campaign ID:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALES_OUTBOUND_Q2'&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="o"&gt;***************************&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt; &lt;span class="k"&gt;row&lt;/span&gt; &lt;span class="o"&gt;***************************&lt;/span&gt;
&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1001&lt;/span&gt;
&lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;SALES_OUTBOUND_Q2&lt;/span&gt;
&lt;span class="n"&gt;dial_speed&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Updating Dial Speed via SQL
&lt;/h3&gt;

&lt;p&gt;Connect to the asterisk database and execute:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;8&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Batch Updates for Multiple Campaigns
&lt;/h3&gt;

&lt;p&gt;To update multiple campaigns at once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1002'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1003'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1004'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Reverting a Change
&lt;/h3&gt;

&lt;p&gt;Always preserve the original value:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Method 3: API-Based Modification
&lt;/h2&gt;

&lt;p&gt;For integration with external systems or automated workflows:&lt;/p&gt;

&lt;h3&gt;
  
  
  ViciDial API Endpoint
&lt;/h3&gt;

&lt;p&gt;ViciDial exposes campaign modification through its API. Example request:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://your-vicidial-ip/vicidial/non_agent_api.php &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"user=admin_username"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"pass=admin_password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"campaign_id=1001"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"campaign_name=SALES_OUTBOUND_Q2"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"dial_speed=1.8"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"format=json"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Expected Response
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"response"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"CAMPAIGN UPDATED"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"campaign_id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1001"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"dial_speed"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"1.8"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Error Handling
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;RESPONSE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="nt"&gt;-X&lt;/span&gt; POST http://your-vicidial-ip/vicidial/non_agent_api.php &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"user=admin_username"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"pass=admin_password"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"campaign_id=1001"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"dial_speed=1.8"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s2"&gt;"format=json"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RESPONSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"CAMPAIGN UPDATED"&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$?&lt;/span&gt; &lt;span class="nt"&gt;-eq&lt;/span&gt; 0 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Success: Dial speed updated"&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Error: Update failed"&lt;/span&gt;
  &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$RESPONSE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Monitoring Impact of Dial Speed Changes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Real-Time Call Monitoring
&lt;/h3&gt;

&lt;p&gt;Monitor the immediate effects using Asterisk CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show channels"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sample output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;Channel              State   Application Data
SIP/1234-00000abc    Up      AppDial
SIP/1235-00000abd    Up      AppDial
SIP/1236-00000abe    Up      VoiceMail
--- 47 active channels
--- 3 active calls
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ViciDial Log Analysis
&lt;/h3&gt;

&lt;p&gt;Check the vicidial_log table for real-time statistics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
  &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ANSWER'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;answered_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ANSWER'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;answer_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;LENGTH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;avg_call_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;LENGTH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_talk_time&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;HOUR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  System Resource Monitoring
&lt;/h3&gt;

&lt;p&gt;Monitor CPU, memory, and disk I/O during and after changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;top &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check Asterisk process specifically:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; asterisk | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor database connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SHOW PROCESSLIST;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; vicidial
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Idle Time Tracking
&lt;/h3&gt;

&lt;p&gt;Query for agent idle statistics:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
  &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_logins&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;logout_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="n"&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;login_time&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;avg_session_length&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'IDLE'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="n"&gt;idle_sec&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_idle_seconds&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_agent_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;login_time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="n"&gt;HOUR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;total_idle_seconds&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;15&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Performance Tuning Considerations
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Database Connection Limits
&lt;/h3&gt;

&lt;p&gt;Verify your MySQL max connections setting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SHOW VARIABLES LIKE 'max_connections';"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For high dial speeds (&amp;gt;2.0), ensure adequate connections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SET GLOBAL max_connections = 500;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make permanent in &lt;code&gt;/etc/mysql/my.cnf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mysqld]&lt;/span&gt;
&lt;span class="py"&gt;max_connections&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;500&lt;/span&gt;
&lt;span class="py"&gt;max_allowed_packet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;64M&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Asterisk Channel Limits
&lt;/h3&gt;

&lt;p&gt;Check current SIP channel limits in &lt;code&gt;/etc/asterisk/sip.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;maxcallbitrate&lt;/span&gt; = &lt;span class="m"&gt;384000&lt;/span&gt;
&lt;span class="n"&gt;dtmfmode&lt;/span&gt; = &lt;span class="n"&gt;rfc2833&lt;/span&gt;
&lt;span class="n"&gt;rtptimeout&lt;/span&gt; = &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;rtpholdtimeout&lt;/span&gt; = &lt;span class="m"&gt;300&lt;/span&gt;
&lt;span class="n"&gt;sipdebug&lt;/span&gt; = &lt;span class="n"&gt;no&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For high-volume campaigns, modify &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;.,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Vicidial&lt;/span&gt; &lt;span class="n"&gt;outbound&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; - ${&lt;span class="n"&gt;CALLERID&lt;/span&gt;(&lt;span class="n"&gt;num&lt;/span&gt;)})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;CHANNEL_LIMIT&lt;/span&gt;=&lt;span class="m"&gt;50&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;}@&lt;span class="n"&gt;carrier&lt;/span&gt;,&lt;span class="m"&gt;180&lt;/span&gt;,&lt;span class="n"&gt;L&lt;/span&gt;(${&lt;span class="n"&gt;CHANNEL_LIMIT&lt;/span&gt;}):&lt;span class="m"&gt;10000&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Asterisk Configuration Reload
&lt;/h3&gt;

&lt;p&gt;After modifying Asterisk configs, reload without dropping calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"module reload chan_sip.so"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or completely reload dialplan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced: Campaign Dial Speed Scheduling
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Time-Based Dial Speed Adjustment
&lt;/h3&gt;

&lt;p&gt;Create a scheduled script to adjust dial speed based on time of day:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /usr/local/bin/adjust_dial_speed.sh&lt;/span&gt;

&lt;span class="nv"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cron"&lt;/span&gt;
&lt;span class="nv"&gt;DB_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"yourpassword"&lt;/span&gt;
&lt;span class="nv"&gt;DB_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"asterisk"&lt;/span&gt;
&lt;span class="nv"&gt;CAMPAIGN_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1001"&lt;/span&gt;

&lt;span class="nv"&gt;HOUR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%H&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Morning (9-12): Conservative&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$HOUR&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 9 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$HOUR&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 12 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;DIAL_SPEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.2"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Afternoon (12-17): Moderate&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$HOUR&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 12 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$HOUR&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 17 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;DIAL_SPEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.5"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Evening (17-21): Aggressive&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$HOUR&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 17 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$HOUR&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 21 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;DIAL_SPEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.8"&lt;/span&gt;
&lt;span class="k"&gt;fi&lt;/span&gt;

&lt;span class="c"&gt;# Late night (21+): Conservative&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$HOUR&lt;/span&gt; &lt;span class="nt"&gt;-ge&lt;/span&gt; 21 &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$HOUR&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 9 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;DIAL_SPEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nv"&gt;$DB_USER&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="nv"&gt;$DB_PASS&lt;/span&gt; &lt;span class="nv"&gt;$DB_NAME&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"UPDATE vicidial_campaigns SET dial_speed = &lt;/span&gt;&lt;span class="nv"&gt;$DIAL_SPEED&lt;/span&gt;&lt;span class="s2"&gt; WHERE campaign_id = '&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN_ID&lt;/span&gt;&lt;span class="s2"&gt;';"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;: Campaign &lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN_ID&lt;/span&gt;&lt;span class="s2"&gt; dial speed set to &lt;/span&gt;&lt;span class="nv"&gt;$DIAL_SPEED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/vicidial_dial_speed.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add to crontab for automatic execution:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;crontab &lt;span class="nt"&gt;-e&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add the line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;0 9,12,17,21 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/local/bin/adjust_dial_speed.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Count-Based Dynamic Adjustment
&lt;/h3&gt;

&lt;p&gt;Adjust dial speed based on currently logged-in agents:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /usr/local/bin/dynamic_dial_speed.sh&lt;/span&gt;

&lt;span class="nv"&gt;DB_USER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"cron"&lt;/span&gt;
&lt;span class="nv"&gt;DB_PASS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"yourpassword"&lt;/span&gt;
&lt;span class="nv"&gt;DB_NAME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"asterisk"&lt;/span&gt;
&lt;span class="nv"&gt;CAMPAIGN_ID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1001"&lt;/span&gt;

&lt;span class="c"&gt;# Get active agent count&lt;/span&gt;
&lt;span class="nv"&gt;AGENT_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nv"&gt;$DB_USER&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="nv"&gt;$DB_PASS&lt;/span&gt; &lt;span class="nv"&gt;$DB_NAME&lt;/span&gt; &lt;span class="nt"&gt;-sN&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"SELECT COUNT(*) FROM vicidial_users WHERE active = '1' AND user_level &amp;gt; 1;"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Adjust dial speed based on agent availability&lt;/span&gt;
&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$AGENT_COUNT&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 10 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;DIAL_SPEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.0"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$AGENT_COUNT&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 20 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;DIAL_SPEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.3"&lt;/span&gt;
&lt;span class="k"&gt;elif&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$AGENT_COUNT&lt;/span&gt; &lt;span class="nt"&gt;-lt&lt;/span&gt; 50 &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nv"&gt;DIAL_SPEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.5"&lt;/span&gt;
&lt;span class="k"&gt;else
  &lt;/span&gt;&lt;span class="nv"&gt;DIAL_SPEED&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"1.8"&lt;/span&gt;
&lt;span class="k"&gt;fi

&lt;/span&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nv"&gt;$DB_USER&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="nv"&gt;$DB_PASS&lt;/span&gt; &lt;span class="nv"&gt;$DB_NAME&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"UPDATE vicidial_campaigns SET dial_speed = &lt;/span&gt;&lt;span class="nv"&gt;$DIAL_SPEED&lt;/span&gt;&lt;span class="s2"&gt; WHERE campaign_id = '&lt;/span&gt;&lt;span class="nv"&gt;$CAMPAIGN_ID&lt;/span&gt;&lt;span class="s2"&gt;';"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;: Agents: &lt;/span&gt;&lt;span class="nv"&gt;$AGENT_COUNT&lt;/span&gt;&lt;span class="s2"&gt;, Dial Speed: &lt;/span&gt;&lt;span class="nv"&gt;$DIAL_SPEED&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/vicidial_dynamic.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue: Dial Speed Change Not Taking Effect
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt; Campaign shows updated dial speed in admin panel, but calling behavior unchanged.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify the change was saved to the database:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check if campaign is paused:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;active = '0'&lt;/code&gt;, enable the campaign:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Restart the vicidial_agent_api service:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl restart vicidial_agent_api
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or if using older init:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/etc/init.d/vicidial_agent_api restart
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Wait 2-3 minutes for the change to propagate through the system.&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Issue: Calls Connecting Too Slowly Despite High Dial Speed
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt; Dial speed set to 2.0 or higher, but agents still idle frequently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check for failed/abandoned calls:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
  &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;HOUR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;High counts of 'CANCEL', 'NO ANSWER', or 'BUSY' indicate connection issues, not dial speed problems.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify carrier/trunk capacity:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for registration status and call count per carrier.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check for dialplan errors:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; error
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce dial speed to improve call quality and answer rates&lt;/li&gt;
&lt;li&gt;Add additional trunks/carriers&lt;/li&gt;
&lt;li&gt;Optimize dialplan rules in extensions-vicidial.conf&lt;/li&gt;
&lt;li&gt;Increase available bandwidth for better SIP handling&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue: High System Load After Increasing Dial Speed
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt; CPU usage spikes to 100%, increased latency, database slowness.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;top &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check database query performance:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SHOW FULL PROCESSLIST&lt;/span&gt;&lt;span class="se"&gt;\G&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; Query_time
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check Asterisk CPU usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show calls"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reduce dial speed:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Optimize database:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"OPTIMIZE TABLE vicidial_log;"&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"OPTIMIZE TABLE vicidial_agent_log;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Increase server resources (CPU, RAM, disk I/O)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Distribute load across multiple Asterisk boxes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Enable connection pooling in my.cnf:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="nn"&gt;[mysqld]&lt;/span&gt;
&lt;span class="py"&gt;innodb_buffer_pool_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;4G&lt;/span&gt;
&lt;span class="py"&gt;thread_cache_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;128&lt;/span&gt;
&lt;span class="py"&gt;query_cache_size&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;512M&lt;/span&gt;
&lt;span class="py"&gt;query_cache_type&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Abandonment Rate Increased After Speed Change
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptoms:&lt;/strong&gt; Dial speed increased, but customer abandonment rate (calls hung up before agent pickup) jumped.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Analysis:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; 
  &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ABANDON'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;abandoned&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ABANDON'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;abandon_rate&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;24&lt;/span&gt; &lt;span class="n"&gt;HOUR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Reduce dial speed incrementally (e.g., from 1.8 to 1.5)&lt;/li&gt;
&lt;li&gt;Implement answer supervision to filter busy/no-answer calls&lt;/li&gt;
&lt;li&gt;Add agent headsets to speed up connect time&lt;/li&gt;
&lt;li&gt;Train agents on faster call acceptance&lt;/li&gt;
&lt;li&gt;Increase agent count to handle call volume&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Issue: Cannot Connect to Database to Update Dial Speed
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Error:&lt;/strong&gt; &lt;code&gt;ERROR 1045 (28000): Access denied for user 'cron'@'localhost'&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution:&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Verify database credentials in &lt;code&gt;/etc/astguiclient/astguiclient.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; password /etc/astguiclient/astguiclient.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If using wrong credentials, update:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;vi /etc/astguiclient/astguiclient.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or test connection directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-u&lt;/span&gt; cron &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT 1;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;cron&lt;/code&gt; user doesn't exist, create it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; mysql &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s2"&gt;"GRANT ALL ON asterisk.* TO 'cron'@'localhost' IDENTIFIED BY 'newpassword';"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Monitoring and Documentation
&lt;/h3&gt;

&lt;p&gt;Always document dial speed changes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# /var/log/vicidial_changes.log&lt;/span&gt;
2024-01-15 10:30:00 - Campaign SALES_Q1: dial_speed 1.2 → 1.5 &lt;span class="o"&gt;(&lt;/span&gt;reason: 20 new agents&lt;span class="o"&gt;)&lt;/span&gt;
2024-01-15 14:00:00 - Campaign SALES_Q1: dial_speed 1.5 → 1.3 &lt;span class="o"&gt;(&lt;/span&gt;reason: high abandonment&lt;span class="o"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Incremental Changes
&lt;/h3&gt;

&lt;p&gt;Never jump from 1.2 to 2.0. Increase in small steps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Day 1&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Day 2 (after monitoring)&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Day 3&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;dial_speed&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Regular Performance Reviews
&lt;/h3&gt;

&lt;p&gt;Schedule weekly reviews:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Weekly dial speed effectiveness report&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; 
  &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nb"&gt;date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_calls&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ANSWER'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;answered&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;ROUND&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ANSWER'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;answer_rate&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;AVG&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;LENGTH&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;avg_duration&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ABANDON'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;abandoned&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;7&lt;/span&gt; &lt;span class="k"&gt;DAY&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="nb"&gt;DATE&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Compliance Considerations
&lt;/h3&gt;

&lt;p&gt;Check FCC/TCPA regulations for your campaign type. Some call types have maximum abandonment limits. Document dial speed choices to demonstrate compliance efforts.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Changing campaign dial speed in ViciDial is a straightforward process with three primary methods:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Web Admin Panel&lt;/strong&gt; - Best for manual, single-campaign changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Direct Database Updates&lt;/strong&gt; - Fastest for bulk changes or scripted deployments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;API-Based Modifications&lt;/strong&gt; - Ideal for system integration and automation&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The key to successful dial speed optimization is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Monitor incrementally&lt;/strong&gt; - Small changes with monitoring periods&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Track metrics&lt;/strong&gt; - Answer rates, abandonment, agent idle time&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document changes&lt;/strong&gt; - Maintain audit trail of all adjustments&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Consider context&lt;/strong&gt; - Agent experience, system resources, compliance requirements&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test thoroughly&lt;/strong&gt; - Always have a rollback plan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Automate responsibly&lt;/strong&gt; - Use scheduling for predictable patterns&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A well-tuned dial speed balances agent productivity with call quality and customer satisfaction. Start conservative (1.2-1.3) and gradually increase based on your specific operational metrics and constraints. Your optimal dial speed depends on your agents' experience, your calling list quality, your system resources, and your business goals.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>How to Add an Agent in ViciDial — User Setup &amp; Phone Config</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Tue, 11 Aug 2026 03:30:02 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/how-to-add-an-agent-in-vicidial-user-setup-phone-config-19be</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/how-to-add-an-agent-in-vicidial-user-setup-phone-config-19be</guid>
      <description>&lt;h1&gt;
  
  
  How to Add an Agent in ViciDial — User Setup &amp;amp; Phone Config
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master the complete process of creating and configuring a new agent in ViciDial, from database entry through SIP registration and phone extension setup.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before adding an agent to your ViciDial system, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;ViciDial 2.x or 3.x installed and running (tested on 2.14+ through 3.x)&lt;/li&gt;
&lt;li&gt;Root or sudo access to the ViciDial server&lt;/li&gt;
&lt;li&gt;Access to the ViciDial web admin panel (&lt;code&gt;http://your-server/vicidial/admin.php&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;An existing campaign configured in the system&lt;/li&gt;
&lt;li&gt;A SIP phone or softphone application ready for the agent&lt;/li&gt;
&lt;li&gt;MySQL database access (for manual verification)&lt;/li&gt;
&lt;li&gt;Asterisk running and accessible via CLI&lt;/li&gt;
&lt;li&gt;Basic familiarity with Linux command line&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding ViciDial Agent Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Agent vs. User vs. Extension
&lt;/h3&gt;

&lt;p&gt;ViciDial uses three interconnected concepts:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;User&lt;/strong&gt;: The administrative login account in the ViciDial system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Agent&lt;/strong&gt;: The voice channel and phone configuration tied to that user&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extension&lt;/strong&gt;: The SIP endpoint (phone) that registers to Asterisk&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;One user can have one active agent, though multiple extensions can exist. The agent record defines which campaign the user can access, pause codes, and phone behavior.&lt;/p&gt;

&lt;h3&gt;
  
  
  Database Tables Involved
&lt;/h3&gt;

&lt;p&gt;Three primary tables interact when adding an agent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;vicidial_users           — User login credentials and permissions
vicidial_agents          — Agent configuration (user_id, phone, campaign)
asterisk_sip_peers       — SIP phone registration details (generated from sip-vicidial.conf)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 1: Create the User Account in ViciDial Web Admin
&lt;/h2&gt;

&lt;p&gt;The fastest and recommended method is through the web interface.&lt;/p&gt;

&lt;h3&gt;
  
  
  Access the User Management Panel
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Log in to &lt;code&gt;/vicidial/admin.php&lt;/code&gt; as an administrator&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Users&lt;/strong&gt; → &lt;strong&gt;Add User&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Fill in the required fields:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User Login&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent001&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Must be unique; lowercase recommended&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Password&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SecurePass123!&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Min 6 characters; change after first login&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Full Name&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;John Smith&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;For reporting and display&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Email&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;john@company.com&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Used for alerts and notifications&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Phone Number&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;5551234567&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Contact number for agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ACTIVE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Set to ACTIVE or INACTIVE&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Configure User Permissions
&lt;/h3&gt;

&lt;p&gt;Under the &lt;strong&gt;User Permissions&lt;/strong&gt; section:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Group&lt;/strong&gt;: Assign to &lt;code&gt;ADMIN&lt;/code&gt;, &lt;code&gt;QA&lt;/code&gt;, &lt;code&gt;SALES&lt;/code&gt;, or custom group&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;User Level&lt;/strong&gt;: Set to &lt;code&gt;1&lt;/code&gt; for agent, &lt;code&gt;7&lt;/code&gt; for manager, &lt;code&gt;8&lt;/code&gt; for admin&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm Password Changes&lt;/strong&gt;: Check if agent must change password at login&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inbound Only&lt;/strong&gt;: Check to restrict to inbound calls only&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outbound Only&lt;/strong&gt;: Check to restrict to outbound calls only&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Leave blank for both inbound and outbound access.&lt;/p&gt;

&lt;h3&gt;
  
  
  Save and Note the User ID
&lt;/h3&gt;

&lt;p&gt;After saving, ViciDial assigns a unique &lt;code&gt;user_id&lt;/code&gt;. You'll need this for the agent configuration.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: Create the Agent Record
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Via Web Admin (Recommended)
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Agents&lt;/strong&gt; → &lt;strong&gt;Add Agent&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Complete the agent setup form:&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Field&lt;/th&gt;
&lt;th&gt;Example&lt;/th&gt;
&lt;th&gt;Notes&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;User&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;agent001&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Auto-populated from user creation&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Agent ID&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;100001&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Can be auto-assigned; must be unique&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Phone Number&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;1001&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;SIP extension for this agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Phone Type&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SIP&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Use SIP for modern deployments&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Status&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;ACTIVE&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Ready to log in&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Campaign&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SALES_OUTBOUND&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Default campaign for agent&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Closer Group&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;code&gt;SALES&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;(Optional) Queue for inbound&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h3&gt;
  
  
  Via MySQL (For Scripted Deployments)
&lt;/h3&gt;

&lt;p&gt;If you're automating agent creation, use SQL directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;USE&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_agents&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;closer_group&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_call_time&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;123&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100001&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SIP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ACTIVE'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="s1"&gt;'SALES_OUTBOUND'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SALES'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'john@company.com'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Verify insertion&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_agents&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Replace:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;123&lt;/code&gt; with the actual &lt;code&gt;user_id&lt;/code&gt; from step 1&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;100001&lt;/code&gt; with your agent ID scheme&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;SALES_OUTBOUND&lt;/code&gt; with your campaign name&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 3: Configure the SIP Phone Extension
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Generate SIP Configuration
&lt;/h3&gt;

&lt;p&gt;ViciDial typically generates SIP extensions automatically in &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt; when you add an agent. However, you may need to generate or verify it manually.&lt;/p&gt;

&lt;h3&gt;
  
  
  Manual SIP Peer Configuration
&lt;/h3&gt;

&lt;p&gt;If auto-generation doesn't work, add the extension to &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="m"&gt;1001&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;-&lt;span class="n"&gt;agents&lt;/span&gt;
&lt;span class="n"&gt;callerid&lt;/span&gt;=&lt;span class="s2"&gt;"Agent 001"&lt;/span&gt; &amp;lt;&lt;span class="m"&gt;1001&lt;/span&gt;&amp;gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="n"&gt;dynamic&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;YourSecurePassword123&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;span class="n"&gt;canreinvite&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;,&lt;span class="n"&gt;alaw&lt;/span&gt;,&lt;span class="n"&gt;gsm&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt;=&lt;span class="m"&gt;1001&lt;/span&gt;
&lt;span class="n"&gt;mailbox&lt;/span&gt;=&lt;span class="m"&gt;1001&lt;/span&gt;@&lt;span class="n"&gt;default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key settings explained:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;type=friend&lt;/code&gt; — Allows bidirectional calling&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;context=from-vicidial-agents&lt;/code&gt; — Routes to ViciDial context (verify in extensions.conf)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;secret&lt;/code&gt; — SIP password; must match phone config&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;nat=yes&lt;/code&gt; — Accommodates agents behind NAT&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;insecure=port,invite&lt;/code&gt; — Relaxes authentication (production: tighten this)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;disallow=all; allow=ulaw&lt;/code&gt; — Codec restriction for bandwidth&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reload Asterisk Configuration
&lt;/h3&gt;

&lt;p&gt;After editing the SIP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the extension loaded:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;1001/1001                        (Unregistered)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Once the phone registers, it will show an IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;1001/1001                        192.168.1.105:5064    OK (42 ms)
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 4: Configure the Phone/Softphone
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SIP Phone Credentials
&lt;/h3&gt;

&lt;p&gt;Provide the agent with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Username&lt;/strong&gt;: &lt;code&gt;1001&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password&lt;/strong&gt;: (matching the SIP secret from config)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server/Domain&lt;/strong&gt;: &lt;code&gt;your-vicidial-server.com&lt;/code&gt; or IP address&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Port&lt;/strong&gt;: &lt;code&gt;5060&lt;/code&gt; (or custom if changed)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Display Name&lt;/strong&gt;: &lt;code&gt;Agent 001&lt;/code&gt; (or agent's name)&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Popular Softphone Clients
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Zoiper (iOS/Android/Windows/Mac)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Add Account → SIP Account&lt;/li&gt;
&lt;li&gt;Enter extension (e.g., &lt;code&gt;1001@your-server.com&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Password: SIP secret&lt;/li&gt;
&lt;li&gt;Server: ViciDial server IP/hostname&lt;/li&gt;
&lt;li&gt;Enable "Use SIP directly" if behind NAT&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Grandstream GrandStream Desktop (Windows/Mac)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Settings → Accounts&lt;/li&gt;
&lt;li&gt;Create SIP Account&lt;/li&gt;
&lt;li&gt;Configure with above details&lt;/li&gt;
&lt;li&gt;Enable "Behind NAT"&lt;/li&gt;
&lt;/ol&gt;

&lt;h4&gt;
  
  
  Physical SIP Phones (Yealink, Polycom, Cisco)
&lt;/h4&gt;

&lt;ol&gt;
&lt;li&gt;Web admin interface of phone&lt;/li&gt;
&lt;li&gt;Network settings → VoIP &amp;gt; Accounts&lt;/li&gt;
&lt;li&gt;Server address, username, password, port&lt;/li&gt;
&lt;li&gt;Enable NAT (usually labeled "Symmetric RTP")&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Test SIP Registration
&lt;/h3&gt;

&lt;p&gt;After phone configuration, check Asterisk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peer 1001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;  &lt;span class="na"&gt;Name       &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="m"&gt;1001&lt;/span&gt;
  &lt;span class="na"&gt;Exten      &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;1001                   ACTIVE&lt;/span&gt;
  &lt;span class="na"&gt;Context    &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;from-vicidial-agents&lt;/span&gt;
  &lt;span class="na"&gt;Callid     &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;agent001-sip@192.168.1.105&lt;/span&gt;
  &lt;span class="na"&gt;ChanObjectType &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;SIP&lt;/span&gt;
  &lt;span class="na"&gt;Useragent  &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Zoiper 5.3.18&lt;/span&gt;
  &lt;span class="na"&gt;Status     &lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;OK (42 ms)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If status is &lt;code&gt;UNKNOWN&lt;/code&gt; or &lt;code&gt;Unreachable&lt;/code&gt;, check firewall rules on port 5060/5061.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Configure ViciDial Phone Settings
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Access Phone Configuration
&lt;/h3&gt;

&lt;p&gt;In the web admin, navigate to &lt;strong&gt;System&lt;/strong&gt; → &lt;strong&gt;Phones&lt;/strong&gt; or &lt;strong&gt;Agents&lt;/strong&gt; → &lt;strong&gt;Phone Settings&lt;/strong&gt; for the agent.&lt;/p&gt;

&lt;h3&gt;
  
  
  Essential Phone Parameters
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Phone Codec&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;          &lt;span class="s"&gt;ULAW (or ALAW if EU-based)&lt;/span&gt;
&lt;span class="na"&gt;Inbound Context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;      &lt;span class="s"&gt;from-vicidial-agents&lt;/span&gt;
&lt;span class="na"&gt;Outbound Context&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;from-vicidial-agents&lt;/span&gt;
&lt;span class="na"&gt;Recording&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;            &lt;span class="s"&gt;ENABLED&lt;/span&gt;
&lt;span class="na"&gt;Recording Format&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;MP3 or WAV&lt;/span&gt;
&lt;span class="na"&gt;Voicemail Enabled&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;YES (optional)&lt;/span&gt;
&lt;span class="na"&gt;Inbound Answering&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;    &lt;span class="s"&gt;AGENT_ONLY&lt;/span&gt;
&lt;span class="na"&gt;Ringback&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;             &lt;span class="s"&gt;ENABLED&lt;/span&gt;
&lt;span class="na"&gt;Ringback Timeout&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;     &lt;span class="s"&gt;30 seconds&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent-Specific Settings
&lt;/h3&gt;

&lt;p&gt;If your ViciDial uses &lt;strong&gt;Vicidial Phone Screen&lt;/strong&gt;, configure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;Vicidial Phone Type&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;  &lt;span class="s"&gt;SIP&lt;/span&gt;
&lt;span class="na"&gt;VoiceGain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;            &lt;span class="s"&gt;0 (0-10 scale; increase if audio is low)&lt;/span&gt;
&lt;span class="na"&gt;MicGain&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;              &lt;span class="s"&gt;0 (0-10 scale)&lt;/span&gt;
&lt;span class="na"&gt;Monitoring&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;           &lt;span class="s"&gt;ENABLED (for QA supervisors)&lt;/span&gt;
&lt;span class="na"&gt;Blind Transfers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;      &lt;span class="s"&gt;ALLOWED&lt;/span&gt;
&lt;span class="na"&gt;Attended Transfers&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;   &lt;span class="s"&gt;ALLOWED&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;These may be set at campaign level (overrides) or globally.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 6: Set Campaign Access and Permissions
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Assign Agent to Campaign
&lt;/h3&gt;

&lt;p&gt;In the agent record or via the &lt;strong&gt;Campaigns&lt;/strong&gt; panel:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;strong&gt;Campaigns&lt;/strong&gt; → Edit campaign (e.g., &lt;code&gt;SALES_OUTBOUND&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Add agent &lt;code&gt;agent001&lt;/code&gt; to the agent list, or&lt;/li&gt;
&lt;li&gt;Add to the agent's &lt;code&gt;campaign_id&lt;/code&gt; field in the database:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_agents&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALES_OUTBOUND'&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Campaign Settings
&lt;/h3&gt;

&lt;p&gt;Ensure the campaign has the correct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dial Method&lt;/strong&gt;: &lt;code&gt;MANUAL&lt;/code&gt;, &lt;code&gt;PREVIEW&lt;/code&gt;, or &lt;code&gt;POWER&lt;/code&gt; (affects agent workflow)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Call Recording&lt;/strong&gt;: &lt;code&gt;ENABLED&lt;/code&gt; for compliance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Auto-Dial Level&lt;/strong&gt;: &lt;code&gt;0.8&lt;/code&gt; - &lt;code&gt;1.5&lt;/code&gt; (for POWER dial)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Lead Pool&lt;/strong&gt;: Campaign's lead source&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Optional: Restrict to Specific Queues
&lt;/h3&gt;

&lt;p&gt;If using inbound queues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_agents&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;closer_group&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALES'&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This restricts the agent to inbound calls routed to the &lt;code&gt;SALES&lt;/code&gt; queue.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 7: Test the Agent Login
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Via Vicidial Agent Screen
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Direct agent to &lt;code&gt;/agc/vicidial.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Log in with username and password&lt;/li&gt;
&lt;li&gt;Select the &lt;strong&gt;Phone&lt;/strong&gt; field (should show extension, e.g., &lt;code&gt;1001&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Agent should see a "READY" or "PAUSED" status&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Via CLI – Verify Agent in System
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"vicidial show agents"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This ViciDial-specific command (if installed) shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Agent ID     User         Extension  Status    Campaign
100001       agent001     1001       READY     SALES_OUTBOUND
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Alternatively, query the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT agent_id, user, phone_number, status FROM vicidial_agents WHERE user = 'agent001';"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Make a Test Call
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Agent logs in and changes status to READY&lt;/li&gt;
&lt;li&gt;Dial the agent extension: &lt;code&gt;asterisk -rx "console dial 1001@from-vicidial-agents"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Agent's phone should ring&lt;/li&gt;
&lt;li&gt;Verify audio quality and recording&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Step 8: Configure Advanced Features (Optional)
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Blind and Attended Transfers
&lt;/h3&gt;

&lt;p&gt;Edit the agent's &lt;strong&gt;User Profile&lt;/strong&gt; to enable transfer permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;blind_transfer_enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
    &lt;span class="n"&gt;attended_transfer_enabled&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Call Recording Configuration
&lt;/h3&gt;

&lt;p&gt;ViciDial records calls by default. Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-la&lt;/span&gt; /var/spool/asterisk/monitor/
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recordings stored as: &lt;code&gt;YYYY-MM-DD-HH-MM-SS_&amp;lt;extension&amp;gt;_&amp;lt;direction&amp;gt;.wav&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;To set recording path per agent, edit campaign settings or globally in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;/&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;extensions&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;.&lt;span class="n"&gt;conf&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;1001&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;MixMonitor&lt;/span&gt;(${&lt;span class="n"&gt;MYFILENAME&lt;/span&gt;}.&lt;span class="n"&gt;wav&lt;/span&gt;,&lt;span class="n"&gt;b&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Voicemail Setup (Optional)
&lt;/h3&gt;

&lt;p&gt;If agents need voicemail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"voicemail show users"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add voicemail to agent extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;; &lt;span class="n"&gt;In&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;sip&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;.&lt;span class="n"&gt;conf&lt;/span&gt;
[&lt;span class="m"&gt;1001&lt;/span&gt;]
&lt;span class="n"&gt;mailbox&lt;/span&gt;=&lt;span class="m"&gt;1001&lt;/span&gt;@&lt;span class="n"&gt;default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create voicemail box:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;; &lt;span class="n"&gt;In&lt;/span&gt; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;voicemail&lt;/span&gt;.&lt;span class="n"&gt;conf&lt;/span&gt;
[&lt;span class="n"&gt;default&lt;/span&gt;]
&lt;span class="m"&gt;1001&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;1234&lt;/span&gt;,&lt;span class="n"&gt;Agent&lt;/span&gt; &lt;span class="m"&gt;001&lt;/span&gt;,&lt;span class="n"&gt;john&lt;/span&gt;@&lt;span class="n"&gt;company&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"voicemail reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Agent Cannot Log In
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: "Invalid username or password" error&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify user exists and status is ACTIVE:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check agent record exists:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;agent_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_agents&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify password (ViciDial may hash it):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MD5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'NewPassword123'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check web server logs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/apache2/error.log
   &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SIP Phone Not Registering
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Extension shows "Unregistered" or "Unreachable"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify firewall allows SIP (port 5060/5061):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 5060/udp
   &lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 5061/udp
   &lt;span class="c"&gt;# Or for iptables:&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-A&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5060 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check SIP config syntax:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Verify phone has correct credentials and server:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Check phone's SIP logs (usually in phone settings)&lt;/li&gt;
&lt;li&gt;Test with a different softphone (e.g., Zoiper)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check Asterisk SIP debug:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug peer 1001"&lt;/span&gt;
   &lt;span class="c"&gt;# Watch registration attempts in /var/log/asterisk/messages&lt;/span&gt;
   &lt;span class="nb"&gt;sudo tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages
   &lt;span class="c"&gt;# Then disable:&lt;/span&gt;
   &lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug off"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify NAT settings if agent is remote:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;   &lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
   &lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
   &lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Poor Audio Quality or One-Way Audio
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Agent or caller cannot hear the other party, or audio is choppy&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check codec compatibility:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peer 1001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure codec is &lt;code&gt;ulaw&lt;/code&gt; or &lt;code&gt;alaw&lt;/code&gt;, not &lt;code&gt;gsm&lt;/code&gt; for production.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Enable media bypass correctly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;   &lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;    ; &lt;span class="n"&gt;Force&lt;/span&gt; &lt;span class="n"&gt;media&lt;/span&gt; &lt;span class="n"&gt;through&lt;/span&gt; &lt;span class="n"&gt;Asterisk&lt;/span&gt; (&lt;span class="n"&gt;recommended&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Increase jitter buffer on phone (if supported)&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check packet loss and latency:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ping &lt;span class="nt"&gt;-c&lt;/span&gt; 10 &amp;lt;agent-phone-ip&amp;gt;
   mtr &amp;lt;agent-phone-ip&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify RTP ports are open (5000-20000 UDP):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow 5000:20000/udp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Logged In But No Calls Received
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Agent shows "READY" but doesn't receive inbound calls&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify agent is assigned to a campaign:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_agents&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check campaign has available leads:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALES_OUTBOUND'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify closer group or queue assignment:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;closer_group&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_agents&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check call routing in dialplan (&lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt;):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan show from-vicidial-agents@1001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify campaign is active and not paused:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dial_method&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALES_OUTBOUND'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Agent Cannot Dial Out
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Agent clicks dial but call doesn't complete&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solutions&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check outbound context in extensions.conf:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"from-vicidial-agents"&lt;/span&gt; /etc/asterisk/extensions-vicidial.conf | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify SIP trunk configuration if using external dialing:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; trunk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check campaign dial method:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;dial_method&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SALES_OUTBOUND'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should be &lt;code&gt;MANUAL&lt;/code&gt;, &lt;code&gt;PREVIEW&lt;/code&gt;, or &lt;code&gt;POWER&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Review call logs for errors:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; agent001
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify dial plan has outbound rules:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;   &lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;.,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;}@&lt;span class="n"&gt;trunk&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Security Best Practices
&lt;/h2&gt;

&lt;p&gt;When adding agents, follow these security measures:&lt;/p&gt;

&lt;h3&gt;
  
  
  1. Use Strong Credentials
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;password&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;MD5&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Tr0pic@l!Mang0#2024SecurePass'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enforce complexity in &lt;code&gt;/usr/share/astguiclient/vicidial_passwd_requirements.php&lt;/code&gt; if available.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. Restrict SIP Access
&lt;/h3&gt;

&lt;p&gt;In &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt;, use &lt;code&gt;insecure&lt;/code&gt; carefully:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;; &lt;span class="n"&gt;Production&lt;/span&gt;: &lt;span class="n"&gt;More&lt;/span&gt; &lt;span class="n"&gt;restrictive&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;

; &lt;span class="n"&gt;Development&lt;/span&gt;/&lt;span class="n"&gt;Testing&lt;/span&gt;: &lt;span class="n"&gt;More&lt;/span&gt; &lt;span class="n"&gt;permissive&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  3. Enable User-Level Restrictions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;user_level&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="k"&gt;admin&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'N'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  4. Change Default Passwords
&lt;/h3&gt;

&lt;p&gt;Always require agents to change their initial password on first login:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;force_password_change&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  5. Monitor Agent Activity
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_login&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'agent001'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Log all administrative changes for compliance.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Adding an agent to ViciDial involves a coordinated sequence of steps:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Create User Account&lt;/strong&gt; — Web admin or MySQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Create Agent Record&lt;/strong&gt; — Link user to phone and campaign&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure SIP Extension&lt;/strong&gt; — sip-vicidial.conf or auto-generated&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure Phone/Softphone&lt;/strong&gt; — Provide credentials and server details&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test SIP Registration&lt;/strong&gt; — Verify in Asterisk CLI&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Configure Phone Settings&lt;/strong&gt; — Codec, recording, voicemail&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Assign Campaign Access&lt;/strong&gt; — Link agent to campaigns and queues&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test Login and Calling&lt;/strong&gt; — Verify agent can log in and make/receive calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Apply Security Measures&lt;/strong&gt; — Strong passwords, restricted access&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For production environments, automate this process with scripts or configuration management tools. Always test new agents with a sample campaign before full deployment.&lt;/p&gt;

&lt;p&gt;Key files to remember:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt; — SIP phone definitions&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt; — Dialplan and call routing&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/var/log/asterisk/messages&lt;/code&gt; — Debug logs&lt;/li&gt;
&lt;li&gt;ViciDial database: &lt;code&gt;asterisk&lt;/code&gt; — Agent and user tables&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/agc/vicidial.php&lt;/code&gt; — Agent login screen&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/vicidial/admin.php&lt;/code&gt; — Administrative interface&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Regular monitoring of agent status, call logs, and system health ensures smooth operation in your ViciDial deployment.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>ViciDial VDAD Not Dialing — AST_VDadapt Process Troubleshooting</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Mon, 10 Aug 2026 03:30:02 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/vicidial-vdad-not-dialing-astvdadapt-process-troubleshooting-522g</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/vicidial-vdad-not-dialing-astvdadapt-process-troubleshooting-522g</guid>
      <description>&lt;h1&gt;
  
  
  ViciDial VDAD Not Dialing — AST_VDadapt Process Troubleshooting
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Learn how to diagnose and fix the AST_VDadapt process when ViciDial campaigns fail to initiate outbound calls, with real configuration examples, database queries, and step-by-step debugging commands.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before starting this troubleshooting guide, you should have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A production or test ViciDial installation (v2.13+) with Asterisk 13+ running&lt;/li&gt;
&lt;li&gt;SSH access to the ViciDial server with root or sudo privileges&lt;/li&gt;
&lt;li&gt;Basic familiarity with ViciDial campaign setup and Asterisk dialplan concepts&lt;/li&gt;
&lt;li&gt;Access to the ViciDial MySQL database (typically &lt;code&gt;asterisk&lt;/code&gt; database)&lt;/li&gt;
&lt;li&gt;Understanding of ViciDial architecture: lead lists, campaigns, inbound/outbound routes, and carrier definitions&lt;/li&gt;
&lt;li&gt;The ability to check system logs in &lt;code&gt;/var/log/asterisk/messages&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;A test campaign configured and ready to dial&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding ViciDial's Dialing Architecture
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is AST_VDadapt?
&lt;/h3&gt;

&lt;p&gt;AST_VDadapt is the Asterisk Adaptive Dialing engine—the core process responsible for initiating outbound calls in ViciDial. When agents are logged into a campaign, AST_VDadapt monitors the lead list, applies dialing rules (predictive, preview, manual), and generates Asterisk channels to make the actual phone calls.&lt;/p&gt;

&lt;p&gt;The process runs as a background daemon and communicates with:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;ViciDial MySQL database&lt;/strong&gt; — reads leads, campaign settings, carrier routes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asterisk dialplan&lt;/strong&gt; — executes SIP/IAX channels via extensions-vicidial.conf&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;ViciDial agent interface&lt;/strong&gt; — receives real-time dialing commands&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System clock&lt;/strong&gt; — enforces DNC (Do Not Call), time-based call rules&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;When VDAD is not dialing, no outbound calls are initiated, and agents see a frozen lead screen.&lt;/p&gt;

&lt;h3&gt;
  
  
  High-Level Call Flow
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;Agent logs into campaign → AST_VDadapt spawns a dialer thread&lt;/li&gt;
&lt;li&gt;VDAD reads active leads from &lt;code&gt;vicidial_list&lt;/code&gt; table&lt;/li&gt;
&lt;li&gt;VDAD checks campaign settings in &lt;code&gt;vicidial_campaigns&lt;/code&gt; and &lt;code&gt;vicidial_carrier_log&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;VDAD determines outbound carrier/trunk from &lt;code&gt;vicidial_carrier_log&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;VDAD executes Asterisk dialplan: &lt;code&gt;exten =&amp;gt; XXXXXX,n,Dial(SIP/trunk/number)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Call is logged to &lt;code&gt;vicidial_log&lt;/code&gt; and &lt;code&gt;vicidial_closer_log&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If VDAD fails at any step, the call never dials.&lt;/p&gt;

&lt;h2&gt;
  
  
  Checking If AST_VDadapt Is Running
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Verify Process Status
&lt;/h3&gt;

&lt;p&gt;Start by confirming the AST_VDadapt process is actually running on your system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; vdadapt | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output (you should see one or more processes):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;asterisk  12345 0.5 2.3 412344 95212 ?    Ssl  10:45   0:12 /usr/bin/perl /usr/share/astguiclient/AST_VDadapt.pl
asterisk  12346 0.4 1.8 398764 71256 ?    Ssl  10:45   0:08 /usr/bin/perl /usr/share/astguiclient/AST_VDadapt.pl
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no processes appear, the dialer is not running.&lt;/p&gt;

&lt;h3&gt;
  
  
  Restart the AST_VDadapt Service
&lt;/h3&gt;

&lt;p&gt;ViciDial typically manages AST_VDadapt through init scripts or systemd:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For systems with systemd&lt;/span&gt;
systemctl restart vicidial-astguiclient

&lt;span class="c"&gt;# For older SysV init systems&lt;/span&gt;
/etc/init.d/vicidial-astguiclient restart

&lt;span class="c"&gt;# Manual restart (if scripts don't work)&lt;/span&gt;
killall AST_VDadapt.pl
&lt;span class="nb"&gt;sleep &lt;/span&gt;2
/usr/share/astguiclient/AST_VDadapt.pl &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait 10 seconds, then verify with &lt;code&gt;ps aux&lt;/code&gt; again.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check AST_VDadapt Logs
&lt;/h3&gt;

&lt;p&gt;AST_VDadapt writes debugging output to &lt;code&gt;/var/log/asterisk/&lt;/code&gt; or a dedicated log file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; vdadapt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or check the ViciDial-specific log directory:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; /var/log/vicidial/
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/vicidial/vdadapt.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for errors like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Database connection failed&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;No carriers available&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Campaign paused&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;No agents logged in&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Database Configuration and Lead List Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Verify Campaign Is Active
&lt;/h3&gt;

&lt;p&gt;VDAD will not dial if the campaign itself is paused or disabled. Check the campaign status:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dial_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="n"&gt;max_leads_for_24hrs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agents_logged_in&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key fields to verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;active&lt;/code&gt; = &lt;code&gt;Y&lt;/code&gt; (must be active)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dial_method&lt;/code&gt; = &lt;code&gt;ADAPT&lt;/code&gt;, &lt;code&gt;MANUAL&lt;/code&gt;, &lt;code&gt;INBOUND&lt;/code&gt;, or &lt;code&gt;BLENDED&lt;/code&gt; (common values)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;agents_logged_in&lt;/code&gt; &amp;gt; 0 (at least one agent must be logged in)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If &lt;code&gt;active = 'N'&lt;/code&gt;, activate it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check for Available Leads
&lt;/h3&gt;

&lt;p&gt;AST_VDadapt cannot dial if there are no leads in the list. Query the lead table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;total_leads&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;new_leads&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
       &lt;span class="k"&gt;SUM&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;CASE&lt;/span&gt; &lt;span class="k"&gt;WHEN&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'CALLBACK'&lt;/span&gt; &lt;span class="k"&gt;THEN&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;ELSE&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="k"&gt;END&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;callback_leads&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected result: &lt;code&gt;total_leads &amp;gt; 0&lt;/code&gt; and &lt;code&gt;new_leads &amp;gt; 0&lt;/code&gt; (or appropriate status for your campaign).&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;total_leads = 0&lt;/code&gt;, import or add leads:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_code&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gmt_offset_now&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'5551234567'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'1'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-5'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify DNC List and Do-Not-Call Rules
&lt;/h3&gt;

&lt;p&gt;If your leads exist but aren't dialing, they may be blocked by DNC (Do-Not-Call) rules. Check the &lt;code&gt;vicidial_dnc_list&lt;/code&gt; table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;dnc_count&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_dnc_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; 
  &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt; &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a high percentage of your test leads are in the DNC list, remove them temporarily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;DELETE&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_dnc_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'5551234567'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check campaign-level DNC enforcement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dnc_enforce_state&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dnc_enforce_county&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;dnc_enforce_state = 'Y'&lt;/code&gt; — respects state-level DNC&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;dnc_enforce_county = 'Y'&lt;/code&gt; — respects county/regional DNC&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Outbound Route and Carrier Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  List Configured Carriers
&lt;/h3&gt;

&lt;p&gt;VDAD must have at least one carrier (trunk) configured for the campaign. Query the carrier table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calling_codec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="n"&gt;technology&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;outbound_proxy&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_carrier_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'AGENT'&lt;/span&gt; &lt;span class="k"&gt;OR&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'default_carrier'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If no carriers appear, create one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_carrier_log&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;technology&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calling_codec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'SIP_CARRIER'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SIP Trunk'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SIP'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ULAW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify SIP/IAX Peer Configuration
&lt;/h3&gt;

&lt;p&gt;Check that the carrier's trunk is defined in Asterisk. Look in &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;sip_carrier_trunk&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;carrierhost&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt;=&lt;span class="n"&gt;your_account_id&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;your_sip_password&lt;/span&gt;
&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;your_account_id&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;carrierhost&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;gsm&lt;/span&gt;
&lt;span class="n"&gt;canreinvite&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the peer is loaded in Asterisk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for your carrier trunk in the output. If it's not listed, reload the SIP config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"module reload res_sip"&lt;/span&gt; 
&lt;span class="c"&gt;# or for old SIP stack&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Link Campaign to Carrier
&lt;/h3&gt;

&lt;p&gt;Ensure the campaign is mapped to an active carrier in the ViciDial web admin:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log into &lt;code&gt;/vicidial/admin.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Navigate to &lt;strong&gt;Campaigns&lt;/strong&gt; → select your campaign&lt;/li&gt;
&lt;li&gt;In the &lt;strong&gt;Carrier Outbound&lt;/strong&gt; section, select a carrier&lt;/li&gt;
&lt;li&gt;Save&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Or verify via database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;carrier_id&lt;/code&gt; is NULL or empty, update it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SIP_CARRIER'&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Asterisk Dialplan and Extensions Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Check extensions-vicidial.conf Syntax
&lt;/h3&gt;

&lt;p&gt;ViciDial's dialplan must be syntactically correct. Check for errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan show from-vicidial"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see errors, validate the configuration file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-nf&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;
&lt;span class="c"&gt;# Then at the Asterisk console:&lt;/span&gt;
dialplan show from-vicidial
quit
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Common issues in &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Missing context definitions&lt;/li&gt;
&lt;li&gt;Malformed Dial() applications&lt;/li&gt;
&lt;li&gt;Incorrect priority numbering&lt;/li&gt;
&lt;li&gt;Unclosed brackets or quotes&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Reload Dialplan
&lt;/h3&gt;

&lt;p&gt;After any changes to &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt;, reload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify the reload was successful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show uptime"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Asterisk uptime"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Outbound Dial Context
&lt;/h3&gt;

&lt;p&gt;Check the dialplan for outbound calls. The typical pattern is:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan show outbound-vicidial@from-vicidial"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output should show extensions for your carriers. If empty or missing, check &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt; for the outbound context definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;outbound&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/&lt;span class="n"&gt;carrier_name&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;},&lt;span class="m"&gt;45&lt;/span&gt;,&lt;span class="n"&gt;tTwW&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="n"&gt;X&lt;/span&gt;.,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Agent Login and Session Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Verify Agents Are Logged In
&lt;/h3&gt;

&lt;p&gt;VDAD only dials if agents are active in a campaign. Check the agent session table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;channel&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_agent_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt; 
  &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;event_epoch&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;UNIX_TIMESTAMP&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="mi"&gt;300&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;event_epoch&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected: You should see at least one agent with &lt;code&gt;status = 'READY'&lt;/code&gt; or &lt;code&gt;'PAUSED'&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;If no agents are logged in, log one in via &lt;code&gt;/agc/vicidial.php&lt;/code&gt; (the agent screen).&lt;/p&gt;

&lt;h3&gt;
  
  
  Check Agent Campaign Assignment
&lt;/h3&gt;

&lt;p&gt;The agent must be assigned to the campaign:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; 
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'AGENT1'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;campaign_id&lt;/code&gt; matches your test campaign&lt;/li&gt;
&lt;li&gt;&lt;code&gt;active = 'Y'&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If the agent isn't assigned to the campaign, add them in the admin panel or via SQL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'AGENT1'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check Agent Status in Real Time
&lt;/h3&gt;

&lt;p&gt;Monitor the agent's Asterisk channel while they're logged in:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show channels"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for a channel matching the agent's user ID. If no channel appears, the agent's SIP client connection is not active.&lt;/p&gt;

&lt;h2&gt;
  
  
  Memory and System Resource Constraints
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Check System Memory and Load
&lt;/h3&gt;

&lt;p&gt;AST_VDadapt and Asterisk are memory-intensive. If system resources are exhausted, dialing will stall:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;free &lt;span class="nt"&gt;-m&lt;/span&gt;
top &lt;span class="nt"&gt;-b&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-15&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: Free memory should be &amp;gt; 20% of total RAM&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load average&lt;/strong&gt;: Should be &amp;lt; 4x the number of CPU cores&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Swap usage&lt;/strong&gt;: Should be minimal (&amp;lt; 10% of swap)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If memory is critically low:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl stop vicidial-astguiclient
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"graceful shutdown"&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;30
&lt;span class="c"&gt;# Clear caches&lt;/span&gt;
&lt;span class="nb"&gt;sync&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo &lt;/span&gt;3 &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /proc/sys/vm/drop_caches
&lt;span class="c"&gt;# Restart&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-r&lt;/span&gt; &amp;amp;
&lt;span class="nb"&gt;sleep &lt;/span&gt;5
systemctl start vicidial-astguiclient
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitor AST_VDadapt Memory Usage
&lt;/h3&gt;

&lt;p&gt;Track VDadapt's memory consumption over time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;watch &lt;span class="nt"&gt;-n&lt;/span&gt; 5 &lt;span class="s1"&gt;'ps aux | grep -i vdadapt | grep -v grep'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a single process exceeds 500MB, restart the daemon:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;killall &lt;span class="nt"&gt;-9&lt;/span&gt; AST_VDadapt.pl
&lt;span class="nb"&gt;sleep &lt;/span&gt;2
/usr/share/astguiclient/AST_VDadapt.pl &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Database Connection Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Verify MySQL Connectivity from Asterisk User
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;asterisk&lt;/code&gt; system user must be able to connect to the ViciDial MySQL database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; asterisk mysql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-u&lt;/span&gt; asterisk &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="s1"&gt;'asterisk_db_password'&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT COUNT(*) FROM vicidial_list;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this fails with "access denied" or "connection refused", verify:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MySQL service is running&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   systemctl status mysql
   &lt;span class="c"&gt;# or&lt;/span&gt;
   systemctl status mariadb
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Asterisk user credentials&lt;/strong&gt; in &lt;code&gt;/etc/asterisk/asterisk.conf&lt;/code&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;   [&lt;span class="n"&gt;asterisk&lt;/span&gt;-&lt;span class="n"&gt;db&lt;/span&gt;]
   &lt;span class="n"&gt;dbhost&lt;/span&gt; = &lt;span class="n"&gt;localhost&lt;/span&gt;
   &lt;span class="n"&gt;dbname&lt;/span&gt; = &lt;span class="n"&gt;asterisk&lt;/span&gt;
   &lt;span class="n"&gt;dbuser&lt;/span&gt; = &lt;span class="n"&gt;asterisk&lt;/span&gt;
   &lt;span class="n"&gt;dbpass&lt;/span&gt; = &lt;span class="n"&gt;asterisk_db_password&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;MySQL user grants&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;ALL&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'asterisk'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt; &lt;span class="n"&gt;IDENTIFIED&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="s1"&gt;'asterisk_db_password'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check for Database Locks
&lt;/h3&gt;

&lt;p&gt;Long-running queries or deadlocks can block AST_VDadapt. Check for blocked processes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SHOW&lt;/span&gt; &lt;span class="n"&gt;PROCESSLIST&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for queries with long &lt;code&gt;Time&lt;/code&gt; values or &lt;code&gt;State = 'Locked'&lt;/code&gt;. Kill problematic queries:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;KILL&lt;/span&gt; &lt;span class="n"&gt;QUERY&lt;/span&gt; &lt;span class="mi"&gt;12345&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;  &lt;span class="c1"&gt;-- Replace 12345 with the process ID&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify vicidial_log Permissions
&lt;/h3&gt;

&lt;p&gt;The &lt;code&gt;asterisk&lt;/code&gt; user must have write access to log tables. Test an insert:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; asterisk mysql &lt;span class="nt"&gt;-h&lt;/span&gt; localhost &lt;span class="nt"&gt;-u&lt;/span&gt; asterisk &lt;span class="nt"&gt;-p&lt;/span&gt;&lt;span class="s1"&gt;'asterisk_db_password'&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
&lt;span class="s2"&gt;"INSERT INTO vicidial_log (user, campaign_id, phone_number, call_date, call_time_start) 
 VALUES ('test', 'TEST_CAMPAIGN', '5551234567', NOW(), '00:00:00');"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the insert fails, rebuild table permissions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'asterisk'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vicidial_list&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'asterisk'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;GRANT&lt;/span&gt; &lt;span class="k"&gt;INSERT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;UPDATE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; &lt;span class="k"&gt;TO&lt;/span&gt; &lt;span class="s1"&gt;'asterisk'&lt;/span&gt;&lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="s1"&gt;'localhost'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="n"&gt;FLUSH&lt;/span&gt; &lt;span class="k"&gt;PRIVILEGES&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Real-World Configuration Example
&lt;/h2&gt;

&lt;p&gt;Here's a complete, working configuration for a test campaign:&lt;/p&gt;

&lt;h3&gt;
  
  
  Campaign Setup
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Create a test campaign&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dial_method&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agents_logged_in&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="n"&gt;rate_frame&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;calls_queued&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;max_leads_for_24hrs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Test Campaign'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'ADAPT'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
 &lt;span class="mi"&gt;60&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'SIP_CARRIER'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="c1"&gt;-- Assign a user to the campaign&lt;/span&gt;
&lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_users&lt;/span&gt; 
&lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Y'&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="k"&gt;user&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'test_agent'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="c1"&gt;-- Insert test leads&lt;/span&gt;
&lt;span class="k"&gt;INSERT&lt;/span&gt; &lt;span class="k"&gt;INTO&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;gmt_offset_now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry_date&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;VALUES&lt;/span&gt; 
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'5551234567'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-5'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'5559876543'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-5'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;()),&lt;/span&gt;
&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'5552468135'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'-5'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Asterisk SIP Peer Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;sip&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;.&lt;span class="n"&gt;conf&lt;/span&gt;

[&lt;span class="n"&gt;SIP_CARRIER&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;provider&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt;=&lt;span class="n"&gt;myaccount&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;mypassword&lt;/span&gt;
&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;myaccount&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;provider&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;gsm&lt;/span&gt;
&lt;span class="n"&gt;canreinvite&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;maxcallbitrate&lt;/span&gt;=&lt;span class="m"&gt;384&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Dialplan Extension
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;; /&lt;span class="n"&gt;etc&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;extensions&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;.&lt;span class="n"&gt;conf&lt;/span&gt;

[&lt;span class="n"&gt;outbound&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;[&lt;span class="m"&gt;2&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;]&lt;span class="n"&gt;XX&lt;/span&gt;[&lt;span class="m"&gt;2&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;]&lt;span class="n"&gt;XXXXXX&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/&lt;span class="n"&gt;SIP_CARRIER&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;},&lt;span class="m"&gt;45&lt;/span&gt;,&lt;span class="n"&gt;tTwW&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;[&lt;span class="m"&gt;2&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;]&lt;span class="n"&gt;XX&lt;/span&gt;[&lt;span class="m"&gt;2&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;]&lt;span class="n"&gt;XXXXXX&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()

&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;[&lt;span class="m"&gt;2&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;]&lt;span class="n"&gt;XX&lt;/span&gt;[&lt;span class="m"&gt;2&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;]&lt;span class="n"&gt;XXXXXX&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/&lt;span class="n"&gt;SIP_CARRIER&lt;/span&gt;/&lt;span class="m"&gt;1&lt;/span&gt;${&lt;span class="n"&gt;EXTEN&lt;/span&gt;},&lt;span class="m"&gt;45&lt;/span&gt;,&lt;span class="n"&gt;tTwW&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;[&lt;span class="m"&gt;2&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;]&lt;span class="n"&gt;XX&lt;/span&gt;[&lt;span class="m"&gt;2&lt;/span&gt;-&lt;span class="m"&gt;9&lt;/span&gt;]&lt;span class="n"&gt;XXXXXX&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Symptom: AST_VDadapt Process Crashes Repeatedly
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Database connection loss, memory leak, or segmentation fault.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check Asterisk logs for core dumps:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   dmesg | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
   &lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; /tmp/core&lt;span class="k"&gt;*&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Monitor AST_VDadapt startup:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Kill any existing processes&lt;/span&gt;
   killall &lt;span class="nt"&gt;-9&lt;/span&gt; AST_VDadapt.pl
   &lt;span class="nb"&gt;sleep &lt;/span&gt;2

   &lt;span class="c"&gt;# Run in foreground with verbose output&lt;/span&gt;
   /usr/share/astguiclient/AST_VDadapt.pl &lt;span class="nt"&gt;--debug&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tee&lt;/span&gt; /tmp/vdadapt_debug.log
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;Watch for errors in the output. Common crashes:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;DBI-&amp;gt;connect failed&lt;/code&gt; — MySQL unavailable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Can't locate Asterisk/AGI.pm&lt;/code&gt; — Missing Perl module&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Segmentation fault&lt;/code&gt; — Corrupt Asterisk installation&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Rebuild Perl modules if needed:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;cd&lt;/span&gt; /usr/src/asterisk-version/
   make menuselect
   &lt;span class="c"&gt;# Select extra modules if needed&lt;/span&gt;
   make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Symptom: Calls Dial but Hang Up Immediately
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Incorrect carrier settings, NAT issues, or codec mismatch.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Monitor the actual SIP traffic:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
   &lt;span class="c"&gt;# Attempt a call&lt;/span&gt;
   &lt;span class="c"&gt;# Watch the output for SIP errors&lt;/span&gt;
   asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug off"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Check the carrier's SIP authentication:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;SIP_CARRIER
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;UNREACHABLE&lt;/code&gt; status. If so, verify host/port/auth in the config.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Test carrier connectivity:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Direct SIP REGISTER test&lt;/span&gt;
   sipsak &lt;span class="nt"&gt;-U&lt;/span&gt; &lt;span class="nt"&gt;-C&lt;/span&gt; sip:myaccount@sip.provider.com &lt;span class="nt"&gt;-l&lt;/span&gt; 0 &lt;span class="nt"&gt;-s&lt;/span&gt; sip:sip.provider.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Force codec to ULAW (most compatible):
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;   [&lt;span class="n"&gt;SIP_CARRIER&lt;/span&gt;]
   &lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
   &lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Symptom: Leads in vicidial_list but VDAD Reports "No Leads Available"
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Lead status filtering, date/time constraints, or VDAD logic blocking.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check lead statuses directly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; 
   &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt; 
   &lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;VDAD typically dials only &lt;code&gt;NEW&lt;/code&gt;, &lt;code&gt;CALLBACK&lt;/code&gt;, or &lt;code&gt;RECALL&lt;/code&gt; statuses. Verify your campaign calls the right statuses.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Check for timezone/callback time constraints:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;entry_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;callback_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;callback_time&lt;/span&gt; 
   &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt; 
     &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'CALLBACK'&lt;/span&gt; 
     &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;callback_date&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If callback times are in the future, they won't dial until that time arrives.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Reset stuck leads to NEW:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;UPDATE&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
   &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'NEW'&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt; 
     &lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'DNCL'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'XDEL'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Symptom: "ERROR: No Carrier Available" in VDAD Logs
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Campaign not linked to carrier, or carrier is inactive/offline.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify carrier assignment:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TEST_CAMPAIGN'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Verify carrier is active:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;active&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_carrier_log&lt;/span&gt; 
   &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'SIP_CARRIER'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test Asterisk can reach the carrier:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; carrier
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;OK&lt;/code&gt; status, not &lt;code&gt;UNREACHABLE&lt;/code&gt;.&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Force a manual dial test via Asterisk console:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   asterisk &lt;span class="nt"&gt;-r&lt;/span&gt;
   channel originate SIP/SIP_CARRIER/5551234567 application &lt;span class="nb"&gt;wait &lt;/span&gt;10
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this fails, the carrier is not configured correctly in Asterisk.&lt;/p&gt;

&lt;h3&gt;
  
  
  Symptom: High CPU Usage by AST_VDadapt, Dialing Is Slow
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Inefficient database queries, large lead lists, or CPU contention.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Profile the AST_VDadapt process:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   strace &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;pgrep AST_VDadapt | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Identify slow database queries:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="c1"&gt;-- Enable slow query log&lt;/span&gt;
   &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;GLOBAL&lt;/span&gt; &lt;span class="n"&gt;slow_query_log&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'ON'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="k"&gt;SET&lt;/span&gt; &lt;span class="k"&gt;GLOBAL&lt;/span&gt; &lt;span class="n"&gt;long_query_time&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
   &lt;span class="c1"&gt;-- Then check&lt;/span&gt;
   &lt;span class="n"&gt;TAIL&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;var&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;/&lt;/span&gt;&lt;span class="n"&gt;slow&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;log&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Add indexes to improve query performance:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;   &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_campaign_status&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;status&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
   &lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;INDEX&lt;/span&gt; &lt;span class="n"&gt;idx_dnc_phone&lt;/span&gt; &lt;span class="k"&gt;ON&lt;/span&gt; &lt;span class="n"&gt;vicidial_dnc_list&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Limit the number of AST_VDadapt processes:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;AST_VDadapt | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More than 3-4 processes may indicate runaway spawning. Restart:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   killall &lt;span class="nt"&gt;-9&lt;/span&gt; AST_VDadapt.pl
   &lt;span class="nb"&gt;sleep &lt;/span&gt;2
   /usr/share/astguiclient/AST_VDadapt.pl &amp;amp;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;ViciDial VDAD not dialing is typically caused by one of these categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Process Issues&lt;/strong&gt;: AST_VDadapt not running, crashing, or unable to connect to MySQL&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database Configuration&lt;/strong&gt;: Missing leads, inactive campaigns, or agent login failures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Carrier/Trunk Issues&lt;/strong&gt;: Missing or inactive SIP/IAX carrier, incorrect authentication, unreachable host&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Dialplan Issues&lt;/strong&gt;: Malformed extensions, missing contexts, or syntax errors&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;System Resources&lt;/strong&gt;: Insufficient memory, high CPU load, or disk I/O bottlenecks&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Quick Troubleshooting Checklist&lt;/strong&gt;:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;✅ Is AST_VDadapt process running? &lt;code&gt;ps aux | grep AST_VDadapt&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Is the campaign active? &lt;code&gt;SELECT active FROM vicidial_campaigns WHERE campaign_id = ?&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Are there leads to dial? &lt;code&gt;SELECT COUNT(*) FROM vicidial_list WHERE campaign_id = ? AND status = 'NEW'&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Is an agent logged in? &lt;code&gt;SELECT user FROM vicidial_agent_log WHERE campaign_id = ?&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Is the carrier configured and online? &lt;code&gt;asterisk -rx "sip show peers"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Does the dialplan load without errors? &lt;code&gt;asterisk -rx "dialplan reload"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;✅ Can MySQL be reached? &lt;code&gt;mysql -u asterisk -p asterisk -e "SELECT 1"&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Follow the sections above in order, test each component, and you'll identify the root cause. Most production VDAD failures are resolved within 15 minutes once you narrow down which subsystem is failing.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>Asterisk Core Dump &amp; Crash Analysis — Debugging Segfaults</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Sun, 09 Aug 2026 03:30:03 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/asterisk-core-dump-crash-analysis-debugging-segfaults-18b5</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/asterisk-core-dump-crash-analysis-debugging-segfaults-18b5</guid>
      <description>&lt;h1&gt;
  
  
  Asterisk Core Dump &amp;amp; Crash Analysis — Debugging Segfaults
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Learn how to capture, analyze, and fix segmentation faults in production Asterisk systems running ViciDial by examining core dumps, generating backtraces, and identifying memory corruption and module conflicts.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you start debugging core dumps, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Root access&lt;/strong&gt; to your Asterisk/ViciDial server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;GDB (GNU Debugger)&lt;/strong&gt; installed: &lt;code&gt;apt-get install gdb&lt;/code&gt; or &lt;code&gt;yum install gdb&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asterisk debug symbols&lt;/strong&gt; (compile from source with debug flags or install &lt;code&gt;-debuginfo&lt;/code&gt; package)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Basic familiarity&lt;/strong&gt; with Asterisk CLI commands and ViciDial architecture&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Backup of your running system&lt;/strong&gt; before making debugging changes&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;At least 2GB free disk space&lt;/strong&gt; in &lt;code&gt;/var/spool/asterisk/&lt;/code&gt; for core dumps&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Knowledge of your Asterisk version&lt;/strong&gt; (run &lt;code&gt;asterisk -V&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding Core Dumps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What is a Core Dump?
&lt;/h3&gt;

&lt;p&gt;A core dump is a file containing the memory snapshot of your process at the moment it crashed. When Asterisk segfaults, the kernel writes this memory to disk (if enabled), allowing you to inspect the call stack, variable states, and identify what caused the crash.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why Core Dumps Matter in Production
&lt;/h3&gt;

&lt;p&gt;In ViciDial environments, unpredictable crashes disrupt:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Active agent calls&lt;/li&gt;
&lt;li&gt;Inbound call routing&lt;/li&gt;
&lt;li&gt;Database synchronization&lt;/li&gt;
&lt;li&gt;Lead distribution&lt;/li&gt;
&lt;li&gt;Campaign execution&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Core dumps let you identify whether crashes are caused by:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Custom modules or dialplan issues&lt;/li&gt;
&lt;li&gt;SIP peer misconfigurations&lt;/li&gt;
&lt;li&gt;Memory leaks in third-party codecs&lt;/li&gt;
&lt;li&gt;Race conditions in high-concurrency scenarios&lt;/li&gt;
&lt;li&gt;Incompatible module versions&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Enabling Core Dumps on Linux
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Configure Kernel to Write Core Dumps
&lt;/h3&gt;

&lt;p&gt;Check current core dump limit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If output is &lt;code&gt;0&lt;/code&gt;, core dumps are disabled. Enable unlimited core dumps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; unlimited
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make this permanent by adding to &lt;code&gt;/etc/security/limits.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# Allow asterisk user to generate unlimited core dumps
&lt;/span&gt;&lt;span class="n"&gt;asterisk&lt;/span&gt; &lt;span class="n"&gt;soft&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="n"&gt;unlimited&lt;/span&gt;
&lt;span class="n"&gt;asterisk&lt;/span&gt; &lt;span class="n"&gt;hard&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="n"&gt;unlimited&lt;/span&gt;
&lt;span class="n"&gt;asterisk&lt;/span&gt; &lt;span class="n"&gt;soft&lt;/span&gt; &lt;span class="n"&gt;nofile&lt;/span&gt; &lt;span class="m"&gt;65536&lt;/span&gt;
&lt;span class="n"&gt;asterisk&lt;/span&gt; &lt;span class="n"&gt;hard&lt;/span&gt; &lt;span class="n"&gt;nofile&lt;/span&gt; &lt;span class="m"&gt;65536&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;su - asterisk &lt;span class="nt"&gt;-s&lt;/span&gt; /bin/bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"ulimit -c"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output: &lt;code&gt;unlimited&lt;/code&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 2: Set Core Dump Location
&lt;/h3&gt;

&lt;p&gt;Define where core files are written. Edit &lt;code&gt;/etc/sysctl.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;kernel&lt;/span&gt;.&lt;span class="n"&gt;core_pattern&lt;/span&gt; = /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;spool&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;core&lt;/span&gt;-%&lt;span class="n"&gt;e&lt;/span&gt;-%&lt;span class="n"&gt;p&lt;/span&gt;-%&lt;span class="n"&gt;t&lt;/span&gt;
&lt;span class="n"&gt;kernel&lt;/span&gt;.&lt;span class="n"&gt;core_uses_pid&lt;/span&gt; = &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Apply immediately:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sysctl &lt;span class="nt"&gt;-p&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This creates files like &lt;code&gt;/var/spool/asterisk/core-asterisk-12345-1703020800&lt;/code&gt; when crashes occur.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Ensure Directory Permissions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; /var/spool/asterisk
&lt;span class="nb"&gt;chown &lt;/span&gt;asterisk:asterisk /var/spool/asterisk
&lt;span class="nb"&gt;chmod &lt;/span&gt;755 /var/spool/asterisk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Configuring Asterisk for Debug Output
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Enable Core Dumps in asterisk.conf
&lt;/h3&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/asterisk/asterisk.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;options&lt;/span&gt;]
; &lt;span class="n"&gt;Enable&lt;/span&gt; &lt;span class="n"&gt;core&lt;/span&gt; &lt;span class="n"&gt;dumps&lt;/span&gt; &lt;span class="n"&gt;even&lt;/span&gt; &lt;span class="n"&gt;when&lt;/span&gt; &lt;span class="n"&gt;run&lt;/span&gt; &lt;span class="n"&gt;as&lt;/span&gt; &lt;span class="n"&gt;daemon&lt;/span&gt;
&lt;span class="n"&gt;dumpcore&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;

; &lt;span class="n"&gt;Log&lt;/span&gt; &lt;span class="n"&gt;all&lt;/span&gt; &lt;span class="n"&gt;debug&lt;/span&gt; &lt;span class="n"&gt;output&lt;/span&gt;
&lt;span class="n"&gt;debug&lt;/span&gt; = &lt;span class="m"&gt;3&lt;/span&gt;

; &lt;span class="n"&gt;Verbose&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;flow&lt;/span&gt;
&lt;span class="n"&gt;verbose&lt;/span&gt; = &lt;span class="m"&gt;3&lt;/span&gt;

; &lt;span class="n"&gt;Log&lt;/span&gt; &lt;span class="n"&gt;warnings&lt;/span&gt; &lt;span class="n"&gt;about&lt;/span&gt; &lt;span class="n"&gt;lock&lt;/span&gt; &lt;span class="n"&gt;contention&lt;/span&gt;
&lt;span class="n"&gt;lockingtest&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Restart Asterisk (gracefully):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core restart graceful"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wait for all channels to clear before Asterisk terminates.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enable Module-Specific Debug
&lt;/h3&gt;

&lt;p&gt;For SIP debugging (ViciDial primary protocol):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug ip 192.168.1.100"&lt;/span&gt;  &lt;span class="c"&gt;# Debug single peer&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For channel/bridge issues:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core set debug 3"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;View live logs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Compiling Asterisk with Debug Symbols
&lt;/h2&gt;

&lt;p&gt;If your Asterisk binary lacks debug symbols, backtraces will be useless. Recompile:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/src/asterisk-16.x.x
./configure &lt;span class="nv"&gt;CFLAGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-g -O0"&lt;/span&gt; &lt;span class="nv"&gt;CXXFLAGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-g -O0"&lt;/span&gt;
make clean
make &lt;span class="nt"&gt;-j4&lt;/span&gt;
make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key flags:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;-g&lt;/code&gt;: Include debug symbols&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;-O0&lt;/code&gt;: Disable optimization (makes symbols more readable; impacts performance)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Production tip&lt;/strong&gt;: Compile with &lt;code&gt;-g -O2&lt;/code&gt; to balance debugging capability with performance.&lt;/p&gt;

&lt;p&gt;Verify symbols are present:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;file /usr/sbin/asterisk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should show: &lt;code&gt;ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked, with debug_info&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nm &lt;span class="nt"&gt;-l&lt;/span&gt; /usr/sbin/asterisk | &lt;span class="nb"&gt;grep &lt;/span&gt;asterisk_log | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should return symbol entries, not empty output.&lt;/p&gt;

&lt;h2&gt;
  
  
  Triggering and Capturing a Crash
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Safe Testing: Use Test Dialplan
&lt;/h3&gt;

&lt;p&gt;Create a crashing dialplan in &lt;code&gt;/etc/asterisk/extensions-test.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;test&lt;/span&gt;-&lt;span class="n"&gt;crash&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;999&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Testing&lt;/span&gt; &lt;span class="n"&gt;crash&lt;/span&gt; &lt;span class="n"&gt;scenario&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;999&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;SIPNotify&lt;/span&gt;(&lt;span class="n"&gt;reboot&lt;/span&gt;,${&lt;span class="n"&gt;CHANNEL&lt;/span&gt;})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;999&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Wait&lt;/span&gt;(&lt;span class="m"&gt;2&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;999&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or trigger via asterisk CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core set debug 5"&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan eval &lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;SOME_BROKEN_VAR&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;  &lt;span class="c"&gt;# Intentional bad variable&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Identify Recent Crashes
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lah&lt;/span&gt; /var/spool/asterisk/core-&lt;span class="k"&gt;*&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lah&lt;/span&gt; /tmp/core.&lt;span class="k"&gt;*&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check system logs for segmentation fault:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;journalctl &lt;span class="nt"&gt;-xe&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; segfault
dmesg | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; segfault
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt; /var/log/syslog | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"segmentation&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;core dump"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example journal output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Nov 23 14:32:01 vicidial-01 kernel: [34567.891234] asterisk[12345]: segfault at 0x0 ip 00007ffff5a2c000 sp 00007fffabc12345 error 4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Analyzing Core Dumps with GDB
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Locate the Core File
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lah&lt;/span&gt; /var/spool/asterisk/core-asterisk-&lt;span class="k"&gt;*&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;-rw------- 1 asterisk asterisk 324M Nov 23 14:32 /var/spool/asterisk/core-asterisk-12345-1700731920
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Start GDB Session
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gdb /usr/sbin/asterisk /var/spool/asterisk/core-asterisk-12345-1700731920
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;GNU gdb (Ubuntu 12.1-0ubuntu1~22.04) 12.1
Reading symbols from /usr/sbin/asterisk...
Reading symbols from /usr/lib/debug/.build-id/...
[New LWP 12345]
[New LWP 12346]
...
Core was generated by `/usr/sbin/asterisk -f'
Program terminated with signal SIGSEGV, Segmentation fault.
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 3: Generate Full Backtrace
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) thread apply all bt full
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows the call stack for all threads. Example output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Thread 47 (LWP 12389):
#0  0x00007ffff5a2c000 in chan_sip_pvt_lock () from /usr/lib/asterisk/modules/chan_sip.so
#1  0x00007ffff5a1f234 in sip_pvt_lock_full () from /usr/lib/asterisk/modules/chan_sip.so
#2  0x00007ffff5a3d123 in handle_incoming () from /usr/lib/asterisk/modules/chan_sip.so
#3  0x00007ffff5a2e456 in sip_io_read () from /usr/lib/asterisk/modules/chan_sip.so
#4  0x000055555555c789 in ast_channel_tech_read () at channel.c:5432
#5  0x000055555556b012 in __ast_read () at channel.c:4123
#6  0x000055555556c234 in ast_read () at channel.c:4234
#7  0x00007ffff7890000 in bridge_channel_wait_for_frame () from /usr/lib/asterisk/modules/app_bridging.so
#8  0x00007ffff7891200 in bridge_channel_run () from /usr/lib/asterisk/modules/app_bridging.so
#9  0x000055555558c345 in ast_spawn_extension () at pbx.c:3912
#10 0x000055555558c600 in pbx_exec () at pbx.c:4012
#11 0x00007ffff6234567 in handle_request_invite () from /usr/lib/asterisk/modules/chan_sip.so
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Focus on the Crashing Thread
&lt;/h3&gt;

&lt;p&gt;Find the thread that crashed (typically reported first):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) thread 1
(gdb) bt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Limit output to top 20 frames:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) bt 20
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Inspect Variables at Crash Point
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) frame 0
(gdb) info local
(gdb) print *variablename
(gdb) print sizeof(structname)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Example: Check if a pointer is NULL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) print pvt
$1 = (struct sip_pvt *) 0x0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A NULL pointer dereference is your culprit.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 6: Examine SIP Channel State
&lt;/h3&gt;

&lt;p&gt;For ViciDial crashes, inspect the SIP channel context:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) frame 2
(gdb) print pvt-&amp;gt;callid
(gdb) print pvt-&amp;gt;dialplan
(gdb) print pvt-&amp;gt;thestate
(gdb) print pvt-&amp;gt;lastinvite
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common Crash Patterns in ViciDial
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Pattern 1: Null Pointer Dereference in SIP Module
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Crash in &lt;code&gt;chan_sip.so&lt;/code&gt; when handling INVITE&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backtrace indicator&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#0  0x... in chan_sip_pvt_lock
#1  0x... in handle_incoming
#2  0x... in sip_io_read
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Root cause&lt;/strong&gt;: SIP peer object deallocated while handling incoming request.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) print pvt
$1 = (struct sip_pvt *) 0x0
(gdb) print dialog
$2 = (struct sip_pvt *) 0x0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;: Add NULL check in custom dialplan or module. Check &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt; for stale peer configs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"UNREACHABLE&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;LAGGED"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Remove outdated peers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip prune peers"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pattern 2: Memory Leak Leading to Crash
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Asterisk runs fine initially, crashes after hours/days of operation.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Indicator&lt;/strong&gt;: Check memory usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ps aux | &lt;span class="nb"&gt;grep &lt;/span&gt;asterisk | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nb"&gt;grep&lt;/span&gt;
&lt;span class="c"&gt;# Look at RSS column (resident set size)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor over time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;watch &lt;span class="nt"&gt;-n&lt;/span&gt; 5 &lt;span class="s1"&gt;'ps aux | grep asterisk | grep -v grep'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If RSS grows continuously, memory leak is present. Backtrace will show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#0  0x... in malloc (or realloc)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: Enable MALLOC_DEBUG in Asterisk:&lt;/p&gt;

&lt;p&gt;Edit &lt;code&gt;/etc/asterisk/asterisk.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;options&lt;/span&gt;]
&lt;span class="n"&gt;allowmultiple&lt;/span&gt; = &lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;astdb&lt;/span&gt; = /&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;lib&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;astdb&lt;/span&gt;.&lt;span class="n"&gt;sqlite3&lt;/span&gt;
&lt;span class="n"&gt;debug&lt;/span&gt; = &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;verbose&lt;/span&gt; = &lt;span class="m"&gt;3&lt;/span&gt;
&lt;span class="n"&gt;dumpcore&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Recompile Asterisk with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./configure &lt;span class="nt"&gt;--with-malloc-debug&lt;/span&gt;
make
make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then run GDB and check memory allocator:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;(gdb) handle SIG35 noprint nostop
(gdb) continue
# ... let it run and crash ...
(gdb) bt
(gdb) print heapmgr
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pattern 3: Race Condition in Database Access
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Intermittent crashes when multiple channels access ViciDial database tables simultaneously.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Affected tables&lt;/strong&gt;: &lt;code&gt;vicidial_log&lt;/code&gt;, &lt;code&gt;vicidial_closer_log&lt;/code&gt;, &lt;code&gt;vicidial_carrier_log&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backtrace indicator&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#0  0x... in ast_db_get
#1  0x... in ast_app_parse_timezones
#2  0x... in custom_app_exec
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: Check for missing table locks in custom AGI scripts or dialplan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="s2"&gt;"astdb&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;ast_db_get"&lt;/span&gt; /etc/asterisk/extensions-vicidial.conf | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;: Use dialplan locks when accessing shared resources:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;100&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Lock&lt;/span&gt;(&lt;span class="n"&gt;vicidial&lt;/span&gt;-&lt;span class="n"&gt;db&lt;/span&gt;-&lt;span class="n"&gt;lock&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;100&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;NoOp&lt;/span&gt;(&lt;span class="n"&gt;Safe&lt;/span&gt; &lt;span class="n"&gt;database&lt;/span&gt; &lt;span class="n"&gt;access&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;100&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Unlock&lt;/span&gt;(&lt;span class="n"&gt;vicidial&lt;/span&gt;-&lt;span class="n"&gt;db&lt;/span&gt;-&lt;span class="n"&gt;lock&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use database transactions in AGI scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# Safe database query in AGI&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;
  flock &lt;span class="nt"&gt;-x&lt;/span&gt; 200
  mysql &lt;span class="nt"&gt;-N&lt;/span&gt; &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"SELECT * FROM vicidial_log WHERE lead_id = &lt;/span&gt;&lt;span class="nv"&gt;$LEAD_ID&lt;/span&gt;&lt;span class="s2"&gt; LIMIT 1"&lt;/span&gt; asterisk
&lt;span class="o"&gt;)&lt;/span&gt; 200&amp;gt;/var/lock/vicidial-db.lock
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Pattern 4: Module Incompatibility
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Crash when loading custom module or third-party codec.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Backtrace indicator&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;#0  0x... in module_symbol_not_found
#1  0x... in dlopen
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Debugging&lt;/strong&gt;: Check loaded modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"module show loaded"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"custom&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;third"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check module dependencies:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ldd /usr/lib/asterisk/modules/codec_custom.so | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"not found"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;: Rebuild module with correct Asterisk version:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/src/asterisk-16.x.x/addons
make clean
make
make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify module loads without errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"module load codec_custom"&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show settings"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Build Date"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Creating a Core Dump Archive for Analysis
&lt;/h2&gt;

&lt;p&gt;Preserve crashes for later investigation or vendor support:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# save_core_dump.sh&lt;/span&gt;

&lt;span class="nv"&gt;CORE_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;ARCHIVE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/spool/asterisk/crash-archives"&lt;/span&gt;
&lt;span class="nv"&gt;TIMESTAMP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%Y%m%d-%H%M%S&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="nb"&gt;mkdir&lt;/span&gt; &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="nv"&gt;$ARCHIVE_DIR&lt;/span&gt;

&lt;span class="c"&gt;# Tar the core and associated binaries&lt;/span&gt;
&lt;span class="nb"&gt;tar&lt;/span&gt; &lt;span class="nt"&gt;-czf&lt;/span&gt; &lt;span class="nv"&gt;$ARCHIVE_DIR&lt;/span&gt;/crash-&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;.tar.gz &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;$CORE_FILE&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  /usr/sbin/asterisk &lt;span class="se"&gt;\&lt;/span&gt;
  /usr/lib/asterisk/modules/&lt;span class="k"&gt;*&lt;/span&gt;.so &lt;span class="se"&gt;\&lt;/span&gt;
  /etc/asterisk/ &lt;span class="se"&gt;\&lt;/span&gt;
  /var/log/asterisk/messages &lt;span class="se"&gt;\&lt;/span&gt;
  2&amp;gt;/dev/null

&lt;span class="c"&gt;# Generate backtrace for quick reference&lt;/span&gt;
gdb &lt;span class="nt"&gt;-batch&lt;/span&gt; &lt;span class="nt"&gt;-ex&lt;/span&gt; &lt;span class="s2"&gt;"bt"&lt;/span&gt; /usr/sbin/asterisk &lt;span class="nv"&gt;$CORE_FILE&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;$ARCHIVE_DIR&lt;/span&gt;/crash-&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;.backtrace.txt 2&amp;gt;&amp;amp;1

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Core dump archived: &lt;/span&gt;&lt;span class="nv"&gt;$ARCHIVE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/crash-&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.tar.gz"&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Backtrace: &lt;/span&gt;&lt;span class="nv"&gt;$ARCHIVE_DIR&lt;/span&gt;&lt;span class="s2"&gt;/crash-&lt;/span&gt;&lt;span class="nv"&gt;$TIMESTAMP&lt;/span&gt;&lt;span class="s2"&gt;.backtrace.txt"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/save_core_dump.sh
/usr/local/bin/save_core_dump.sh /var/spool/asterisk/core-asterisk-12345-1700731920
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Automated Crash Detection and Response
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Create a Core Dump Watcher
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /usr/local/bin/asterisk-crash-monitor.sh&lt;/span&gt;

&lt;span class="nv"&gt;CORE_DIR&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/spool/asterisk"&lt;/span&gt;
&lt;span class="nv"&gt;LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/log/asterisk/crash-monitor.log"&lt;/span&gt;
&lt;span class="nv"&gt;ALERT_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"admin@example.com"&lt;/span&gt;

check_for_new_cores&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  find &lt;span class="nv"&gt;$CORE_DIR&lt;/span&gt; &lt;span class="nt"&gt;-name&lt;/span&gt; &lt;span class="s2"&gt;"core-*"&lt;/span&gt; &lt;span class="nt"&gt;-type&lt;/span&gt; f &lt;span class="nt"&gt;-mmin&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;core_file&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;timestamp&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="s1"&gt;'+%Y-%m-%d %H:%M:%S'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Extract backtrace&lt;/span&gt;
    &lt;span class="nv"&gt;backtrace&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;gdb &lt;span class="nt"&gt;-batch&lt;/span&gt; &lt;span class="nt"&gt;-ex&lt;/span&gt; &lt;span class="s2"&gt;"bt 30"&lt;/span&gt; /usr/sbin/asterisk &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$core_file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="c"&gt;# Log incident&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="s2"&gt;] Crash detected: &lt;/span&gt;&lt;span class="nv"&gt;$core_file&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$backtrace&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"---"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;

    &lt;span class="c"&gt;# Send alert&lt;/span&gt;
    &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$backtrace&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | mail &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"Asterisk Crash: &lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;hostname&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nv"&gt;$ALERT_EMAIL&lt;/span&gt;

    &lt;span class="c"&gt;# Restart Asterisk if needed&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;!&lt;/span&gt; pgrep &lt;span class="nt"&gt;-x&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
      &lt;/span&gt;systemctl start asterisk
      &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[&lt;/span&gt;&lt;span class="nv"&gt;$timestamp&lt;/span&gt;&lt;span class="s2"&gt;] Asterisk restarted"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt;
    &lt;span class="k"&gt;fi
  done&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

&lt;span class="c"&gt;# Run every 2 minutes&lt;/span&gt;
&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  &lt;/span&gt;check_for_new_cores
  &lt;span class="nb"&gt;sleep &lt;/span&gt;120
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Install as systemd service:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;&lt;span class="c"&gt;# /etc/systemd/system/asterisk-crash-monitor.service
&lt;/span&gt;&lt;span class="nn"&gt;[Unit]&lt;/span&gt;
&lt;span class="py"&gt;Description&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;Asterisk Crash Monitor&lt;/span&gt;
&lt;span class="py"&gt;After&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;network.target&lt;/span&gt;
&lt;span class="py"&gt;Wants&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;asterisk.service&lt;/span&gt;

&lt;span class="nn"&gt;[Service]&lt;/span&gt;
&lt;span class="py"&gt;Type&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;simple&lt;/span&gt;
&lt;span class="py"&gt;User&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;root&lt;/span&gt;
&lt;span class="py"&gt;ExecStart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;/usr/local/bin/asterisk-crash-monitor.sh&lt;/span&gt;
&lt;span class="py"&gt;Restart&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;always&lt;/span&gt;
&lt;span class="py"&gt;RestartSec&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;10&lt;/span&gt;

&lt;span class="nn"&gt;[Install]&lt;/span&gt;
&lt;span class="py"&gt;WantedBy&lt;/span&gt;&lt;span class="p"&gt;=&lt;/span&gt;&lt;span class="s"&gt;multi-user.target&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Enable:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl daemon-reload
systemctl &lt;span class="nb"&gt;enable &lt;/span&gt;asterisk-crash-monitor
systemctl start asterisk-crash-monitor
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  GDB Automation Script
&lt;/h3&gt;

&lt;p&gt;For unattended backtrace generation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# /usr/local/bin/extract_backtrace.sh&lt;/span&gt;

&lt;span class="nv"&gt;CORE_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="nv"&gt;BINARY&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/usr/sbin/asterisk"&lt;/span&gt;
&lt;span class="nv"&gt;OUTPUT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;CORE_FILE&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.backtrace.txt"&lt;/span&gt;

gdb &lt;span class="nt"&gt;-batch&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-ex&lt;/span&gt; &lt;span class="s2"&gt;"thread apply all bt full"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-ex&lt;/span&gt; &lt;span class="s2"&gt;"quit"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nv"&gt;$BINARY&lt;/span&gt; &lt;span class="nv"&gt;$CORE_FILE&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$OUTPUT&lt;/span&gt; 2&amp;gt;&amp;amp;1

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Backtrace written to: &lt;/span&gt;&lt;span class="nv"&gt;$OUTPUT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="nv"&gt;$OUTPUT&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Usage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/usr/local/bin/extract_backtrace.sh /var/spool/asterisk/core-asterisk-12345-1700731920
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ViciDial-Specific Debugging Tips
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Check for Lead Lock Deadlocks
&lt;/h3&gt;

&lt;p&gt;ViciDial's lead distribution can deadlock when multiple processes compete for the same lead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"database show vicidial-lead-locks"&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If locks don't clear within seconds, investigate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="n"&gt;mysql&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;lead_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;LEAD_ID&lt;/span&gt;&lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;entry_date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Clear stale locks manually (if safe):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"database deltree vicidial-lead-locks"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitor Call Bridge Issues
&lt;/h3&gt;

&lt;p&gt;ViciDial bridges agent and carrier channels. Crashes often occur at bridge setup:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core set debug 3"&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"bridge show all"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check for stuck bridges:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"channel show all"&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If channel count grows unbounded, bridge leak exists. Restart may be necessary:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core restart graceful"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Review Dialplan Syntax
&lt;/h3&gt;

&lt;p&gt;Dialplan errors can trigger crashes in edge cases. Validate:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check for warnings in &lt;code&gt;/var/log/asterisk/messages&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"warning&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;error"&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Inspect AGI Script Failures
&lt;/h3&gt;

&lt;p&gt;Custom AGI scripts sometimes cause Asterisk to crash. Test scripts in isolation:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;/var/lib/asterisk/agi-bin/vicidial_loader.agi &lt;span class="nb"&gt;test&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add error handling to AGI scripts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="s1"&gt;'echo "HANGUP" &amp;gt;&amp;amp;3'&lt;/span&gt; EXIT
&lt;span class="nb"&gt;trap&lt;/span&gt; &lt;span class="s1"&gt;'exit'&lt;/span&gt; SIGTERM

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; 1 line&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
  case&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$line&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;in
    &lt;/span&gt;agi_uniqueid:&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;UNIQUEID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;line&lt;/span&gt;&lt;span class="p"&gt;#*&lt;/span&gt;:&lt;span class="p"&gt; &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
    agi_calleridnum:&lt;span class="k"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="nv"&gt;CALLERID&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;line&lt;/span&gt;&lt;span class="p"&gt;#*&lt;/span&gt;:&lt;span class="p"&gt; &lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;;;&lt;/span&gt;
  &lt;span class="k"&gt;esac&lt;/span&gt;
  &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nt"&gt;-z&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$line&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;break
&lt;/span&gt;&lt;span class="k"&gt;done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"EXEC Hangup"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt;&amp;amp;3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue: Core Dumps Not Being Generated
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Check 1: ulimit&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Should return &lt;code&gt;unlimited&lt;/code&gt;. If not:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; unlimited
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ulimit -c unlimited"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /etc/profile
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Check 2: File System Space&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;df&lt;/span&gt; &lt;span class="nt"&gt;-h&lt;/span&gt; /var/spool/asterisk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If full, clean old cores:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;rm&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/spool/asterisk/core-&lt;span class="k"&gt;*&lt;/span&gt; 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Check 3: SELinux&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;If enabled, SELinux may block core dumps:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;getenforce
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;Enforcing&lt;/code&gt;, add policy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;semanage fcontext &lt;span class="nt"&gt;-a&lt;/span&gt; &lt;span class="nt"&gt;-t&lt;/span&gt; asterisk_var_spool_t &lt;span class="s2"&gt;"/var/spool/asterisk(/.*)?"&lt;/span&gt;
restorecon &lt;span class="nt"&gt;-Rv&lt;/span&gt; /var/spool/asterisk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: GDB Backtrace Shows "??" Instead of Function Names
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Missing debug symbols.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;: Recompile Asterisk with &lt;code&gt;-g&lt;/code&gt; flag:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;./configure &lt;span class="nv"&gt;CFLAGS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"-g -O2"&lt;/span&gt;
make &lt;span class="nt"&gt;-j4&lt;/span&gt;
make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gdb /usr/sbin/asterisk &lt;span class="nt"&gt;-batch&lt;/span&gt; &lt;span class="nt"&gt;-ex&lt;/span&gt; &lt;span class="s2"&gt;"file /usr/sbin/asterisk"&lt;/span&gt; &lt;span class="nt"&gt;-ex&lt;/span&gt; &lt;span class="s2"&gt;"quit"&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"debug_info"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: GDB Takes Too Long to Load Large Core Files
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Workaround&lt;/strong&gt;: Use &lt;code&gt;gdb --nx&lt;/code&gt; to skip initialization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gdb &lt;span class="nt"&gt;--nx&lt;/span&gt; /usr/sbin/asterisk /var/spool/asterisk/core-asterisk-12345-1700731920
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or extract backtrace without full symbols:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;gdb &lt;span class="nt"&gt;-batch&lt;/span&gt; &lt;span class="nt"&gt;-ex&lt;/span&gt; &lt;span class="s2"&gt;"bt"&lt;/span&gt; /usr/sbin/asterisk /var/spool/asterisk/core-asterisk-12345-1700731920 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Asterisk Keeps Crashing in Infinite Loop
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Diagnosis&lt;/strong&gt;: Check crash frequency:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; /var/spool/asterisk/core-&lt;span class="k"&gt;*&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Disable automatic restart temporarily:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;systemctl stop asterisk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run Asterisk in foreground with debug:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Stop at first crash with Ctrl+C. Review console output for error messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue: Backtrace Points to Third-Party Module, But Module Isn't Loaded
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause&lt;/strong&gt;: Module was loaded in a previous process instance, shared library is corrupted.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix&lt;/strong&gt;: Force reload all modules:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"module reload FORCE"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If crash persists:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"module unload extra/codec_custom"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Rebuild module:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; /usr/src/asterisk-16.x.x/addons
make clean
./configure &lt;span class="nt"&gt;--with-asterisk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr
make
make &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Debugging Asterisk core dumps in production ViciDial environments requires:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Preparation&lt;/strong&gt;: Enable core dumps at OS, kernel, and Asterisk levels. Compile with debug symbols.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Capture&lt;/strong&gt;: Monitor &lt;code&gt;/var/spool/asterisk/&lt;/code&gt; for new core files. Log crash timestamps and associated system state.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Analysis&lt;/strong&gt;: Use GDB to extract full backtraces with &lt;code&gt;thread apply all bt full&lt;/code&gt;. Focus on the faulting thread. Inspect variable states at crash point.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Pattern Recognition&lt;/strong&gt;: Know common ViciDial crash patterns—SIP channel deallocation, database race conditions, memory leaks, module incompatibilities.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;ViciDial-Specific Checks&lt;/strong&gt;: Verify lead locks aren't stuck, call bridges aren't leaking, dialplan is valid, AGI scripts have error handling.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Response&lt;/strong&gt;: Automate crash detection with systemd services. Generate backtrace archives for vendor support. Implement graceful restarts to minimize call loss.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Remediation&lt;/strong&gt;: Address root causes—patch Asterisk, rebuild incompatible modules, refactor dialplan, fix AGI scripts, update SIP peers.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Core dumps are your most powerful debugging tool in production. Invest in capturing and preserving them. A single backtrace can save weeks of troubleshooting and prevent recurring crashes that destroy agent productivity and customer experience.&lt;/p&gt;

&lt;p&gt;Keep backtraces, logs, and configurations together when escalating to Asterisk support or ViciDial engineers. Always test fixes in staging before deploying to production.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>SIP 408 Request Timeout — Network &amp; Firewall Troubleshooting</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Sat, 08 Aug 2026 03:30:02 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/sip-408-request-timeout-network-firewall-troubleshooting-44cf</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/sip-408-request-timeout-network-firewall-troubleshooting-44cf</guid>
      <description>&lt;h1&gt;
  
  
  SIP 408 Request Timeout — Network &amp;amp; Firewall Troubleshooting
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master the complete diagnostic and resolution process for SIP 408 errors in ViciDial and Asterisk production environments, covering network analysis, firewall rules, SIP configuration tuning, and carrier-level debugging.&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before diving into this tutorial, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;A running ViciDial/Asterisk installation (tested on 2.14+)&lt;/li&gt;
&lt;li&gt;SSH access to your Asterisk server with sudo privileges&lt;/li&gt;
&lt;li&gt;Basic understanding of SIP protocol and VoIP concepts&lt;/li&gt;
&lt;li&gt;Network diagnostic tools: &lt;code&gt;tcpdump&lt;/code&gt;, &lt;code&gt;netstat&lt;/code&gt;, &lt;code&gt;iptables&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Access to &lt;code&gt;/etc/asterisk/&lt;/code&gt; configuration directory&lt;/li&gt;
&lt;li&gt;ViciDial database access (MySQL/MariaDB)&lt;/li&gt;
&lt;li&gt;Knowledge of your carrier's SIP trunk details&lt;/li&gt;
&lt;li&gt;Ability to check firewall rules and NAT configuration&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding SIP 408 Request Timeout
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is SIP 408?
&lt;/h3&gt;

&lt;p&gt;The SIP 408 (Request Timeout) response indicates that the Asterisk server did not receive a response from the remote SIP endpoint (usually your carrier's SIP trunk) within the expected timeframe. This is fundamentally different from call failures caused by rejection—the server is simply not answering.&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Scenarios in ViciDial
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Outbound calls hang&lt;/strong&gt;: Agents see "no answer" or calls drop during routing&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Inbound calls fail&lt;/strong&gt;: DIDs receive no connection attempts from carrier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Intermittent issues&lt;/strong&gt;: Timeout occurs randomly, typically under load&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Carrier-specific problems&lt;/strong&gt;: One carrier works, another doesn't&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The root cause is always one of these categories:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Network connectivity issues (firewall blocking, NAT misconfiguration)&lt;/li&gt;
&lt;li&gt;SIP timeout values too aggressive for your infrastructure&lt;/li&gt;
&lt;li&gt;Asymmetric routing or packet loss&lt;/li&gt;
&lt;li&gt;Carrier not properly configured or experiencing issues&lt;/li&gt;
&lt;li&gt;DNS resolution failures&lt;/li&gt;
&lt;li&gt;RTP port range problems&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Network Diagnostics: Foundational Steps
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Verify Basic Connectivity
&lt;/h3&gt;

&lt;p&gt;Start by confirming your Asterisk server can reach your SIP carrier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test carrier IP/hostname resolution&lt;/span&gt;
nslookup sip.yourcarrier.com
dig sip.yourcarrier.com +short

&lt;span class="c"&gt;# Ping the carrier (may be disabled by carrier, but worth trying)&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 5 203.0.113.50

&lt;span class="c"&gt;# Test SIP port connectivity with nc (netcat)&lt;/span&gt;
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; 203.0.113.50 5060
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; 203.0.113.50 5061

&lt;span class="c"&gt;# More detailed test with timeout&lt;/span&gt;
&lt;span class="nb"&gt;timeout &lt;/span&gt;5 bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s1"&gt;'echo &amp;gt; /dev/tcp/203.0.113.50/5060'&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Port 5060 is open"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Port 5060 is closed"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Check Asterisk Binding
&lt;/h3&gt;

&lt;p&gt;Verify that Asterisk is properly binding to the correct interface:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View all SIP ports Asterisk is listening on&lt;/span&gt;
netstat &lt;span class="nt"&gt;-tlnp&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;asterisk | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'5060|5061'&lt;/span&gt;

&lt;span class="c"&gt;# Example output should show:&lt;/span&gt;
&lt;span class="c"&gt;# tcp  0  0 0.0.0.0:5060  0.0.0.0:*  LISTEN  1234/asterisk&lt;/span&gt;
&lt;span class="c"&gt;# udp  0  0 0.0.0.0:5060  0.0.0.0:*           1234/asterisk&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If Asterisk is only binding to 127.0.0.1 or a specific internal IP, external carriers cannot reach it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Analyze Outbound Packet Flow
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;tcpdump&lt;/code&gt; to capture SIP packets and identify where the conversation breaks:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Capture SIP traffic to/from your carrier&lt;/span&gt;
tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-s&lt;/span&gt; 0 &lt;span class="nt"&gt;-vvv&lt;/span&gt; host 203.0.113.50 and port 5060 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/sip_capture.pcap

&lt;span class="c"&gt;# In another terminal, initiate a test call, then stop capture with Ctrl+C&lt;/span&gt;

&lt;span class="c"&gt;# View the capture in human-readable format&lt;/span&gt;
tcpdump &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/sip_capture.pcap &lt;span class="nt"&gt;-vvv&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt;

&lt;span class="c"&gt;# Count SIP messages by type&lt;/span&gt;
tcpdump &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/sip_capture.pcap | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-oE&lt;/span&gt; &lt;span class="s1"&gt;'SIP/2.0 [A-Z]+ |^[A-Z]+ sip:'&lt;/span&gt; | &lt;span class="nb"&gt;sort&lt;/span&gt; | &lt;span class="nb"&gt;uniq&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for this pattern:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;INVITE sent to carrier (your server → carrier)
100 Trying received from carrier (carrier → your server)
INVITE TIMEOUT (no 183/180/200 response)
BYE sent (cleanup)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see INVITE but no response, the issue is almost certainly carrier-side or network-path related.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Monitor Real-Time SIP Sessions
&lt;/h3&gt;

&lt;p&gt;While making test calls, observe Asterisk's SIP channel state:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# SSH to Asterisk server&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show channels"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'Channel|TO|FROM'&lt;/span&gt;

&lt;span class="c"&gt;# Example output:&lt;/span&gt;
&lt;span class="c"&gt;# Channel              State     Type      Exten     Context     &lt;/span&gt;
&lt;span class="c"&gt;# SIP/carrier-0000001f DOWN      INVITE    s         from-external&lt;/span&gt;

&lt;span class="c"&gt;# Get detailed info on a specific channel&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show channel SIP/carrier-0000001f"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Firewall Configuration &amp;amp; NAT
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Understanding the Firewall Problem
&lt;/h3&gt;

&lt;p&gt;The most common cause of 408 timeouts in production ViciDial systems is &lt;strong&gt;asymmetric firewall rules&lt;/strong&gt; or &lt;strong&gt;NAT configuration&lt;/strong&gt;. Your outbound packets reach the carrier, but their responses are blocked coming back.&lt;/p&gt;

&lt;h3&gt;
  
  
  Firewall Rules: Bulletproof Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# First, determine your internal IP and external carrier IP&lt;/span&gt;
&lt;span class="c"&gt;# Internal SIP IP (usually private):&lt;/span&gt;
ip addr show | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"inet "&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; 127.0.0.1

&lt;span class="c"&gt;# External interface (usually eth0, ens0, etc.):&lt;/span&gt;
ip route | &lt;span class="nb"&gt;grep &lt;/span&gt;default

&lt;span class="c"&gt;# Check current iptables rules&lt;/span&gt;
iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'5060|5061|10000:20000'&lt;/span&gt;

&lt;span class="c"&gt;# If using UFW (Ubuntu/Debian):&lt;/span&gt;
ufw status
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Proper firewall rules for a ViciDial system:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Allow SIP from your carrier (CRITICAL)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5060 &lt;span class="nt"&gt;-s&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5060 &lt;span class="nt"&gt;-s&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5061 &lt;span class="nt"&gt;-s&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5061 &lt;span class="nt"&gt;-s&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Allow RTP audio stream (critical!)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 10000:20000 &lt;span class="nt"&gt;-s&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Allow established/related connections&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-m&lt;/span&gt; conntrack &lt;span class="nt"&gt;--ctstate&lt;/span&gt; ESTABLISHED,RELATED &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Allow loopback (internal communication)&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-i&lt;/span&gt; lo &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Outbound: Allow SIP to carrier&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5060 &lt;span class="nt"&gt;-d&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5060 &lt;span class="nt"&gt;-d&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5061 &lt;span class="nt"&gt;-d&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5061 &lt;span class="nt"&gt;-d&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Allow RTP outbound&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 10000:20000 &lt;span class="nt"&gt;-d&lt;/span&gt; 203.0.113.50 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# Save rules permanently (iptables-persistent)&lt;/span&gt;
iptables-save &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/iptables/rules.v4
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  UFW Configuration (Modern Ubuntu/Debian)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Enable UFW if not already&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw &lt;span class="nb"&gt;enable&lt;/span&gt;

&lt;span class="c"&gt;# Allow from carrier (replace with your carrier IP)&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow from 203.0.113.50 to any port 5060 proto udp
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow from 203.0.113.50 to any port 5061 proto tcp
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow from 203.0.113.50 to any port 10000:20000 proto udp

&lt;span class="c"&gt;# Allow SSH to not lock yourself out&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw allow ssh

&lt;span class="c"&gt;# Check active rules&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;ufw status verbose
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  NAT Configuration
&lt;/h3&gt;

&lt;p&gt;If your ViciDial server is behind NAT, Asterisk must know its public IP:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Edit main SIP config&lt;/span&gt;
nano /etc/asterisk/sip-vicidial.conf

&lt;span class="c"&gt;# Find or add these lines under [general]:&lt;/span&gt;
externip &lt;span class="o"&gt;=&lt;/span&gt; 203.0.113.100           &lt;span class="p"&gt;;&lt;/span&gt; Your PUBLIC IP &lt;span class="o"&gt;(&lt;/span&gt;not carrier IP&lt;span class="o"&gt;)&lt;/span&gt;
localnet &lt;span class="o"&gt;=&lt;/span&gt; 192.168.1.0/24          &lt;span class="p"&gt;;&lt;/span&gt; Your INTERNAL network
nat &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;yes&lt;/span&gt;                           &lt;span class="p"&gt;;&lt;/span&gt; Enable NAT processing
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If using a dynamic public IP (not recommended for production), use:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;externhost&lt;/span&gt; = &lt;span class="n"&gt;mypublicip&lt;/span&gt;.&lt;span class="n"&gt;dyndns&lt;/span&gt;.&lt;span class="n"&gt;org&lt;/span&gt;
&lt;span class="n"&gt;localnet&lt;/span&gt; = &lt;span class="m"&gt;192&lt;/span&gt;.&lt;span class="m"&gt;168&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;/&lt;span class="m"&gt;24&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After NAT changes, reload Asterisk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Asterisk SIP Configuration Tuning
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Aggressive vs. Conservative Timeout Values
&lt;/h3&gt;

&lt;p&gt;The default SIP timeout in Asterisk (6 seconds) is too aggressive for international carriers or congested networks. ViciDial's default is better, but still needs tuning.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Backup current config&lt;/span&gt;
&lt;span class="nb"&gt;cp&lt;/span&gt; /etc/asterisk/sip-vicidial.conf /etc/asterisk/sip-vicidial.conf.backup.&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; +%s&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Edit the main SIP configuration&lt;/span&gt;
nano /etc/asterisk/sip-vicidial.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add or modify these parameters in the &lt;code&gt;[general]&lt;/code&gt; section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
; === &lt;span class="n"&gt;Timeout&lt;/span&gt; &lt;span class="n"&gt;Configuration&lt;/span&gt; ===
; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="n"&gt;SIP&lt;/span&gt; &lt;span class="n"&gt;invite&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;milliseconds&lt;/span&gt; (&lt;span class="n"&gt;default&lt;/span&gt;: &lt;span class="m"&gt;6000&lt;/span&gt;)
; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;unstable&lt;/span&gt;/&lt;span class="n"&gt;international&lt;/span&gt; &lt;span class="n"&gt;carriers&lt;/span&gt;, &lt;span class="n"&gt;increase&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="m"&gt;15000&lt;/span&gt;-&lt;span class="m"&gt;30000&lt;/span&gt;
&lt;span class="n"&gt;sip_t1&lt;/span&gt; = &lt;span class="m"&gt;500&lt;/span&gt;                    ; &lt;span class="n"&gt;Initial&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;between&lt;/span&gt; &lt;span class="n"&gt;retransmissions&lt;/span&gt; (&lt;span class="n"&gt;ms&lt;/span&gt;)
&lt;span class="n"&gt;sip_t1min&lt;/span&gt; = &lt;span class="m"&gt;100&lt;/span&gt;                 ; &lt;span class="n"&gt;Minimum&lt;/span&gt; &lt;span class="n"&gt;T1&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; (&lt;span class="n"&gt;ms&lt;/span&gt;)
&lt;span class="n"&gt;sip_invite_timeout&lt;/span&gt; = &lt;span class="m"&gt;30&lt;/span&gt;         ; &lt;span class="n"&gt;Timeout&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;INVITE&lt;/span&gt; &lt;span class="n"&gt;responses&lt;/span&gt; (&lt;span class="n"&gt;seconds&lt;/span&gt;)
&lt;span class="n"&gt;sip_register_timeout&lt;/span&gt; = &lt;span class="m"&gt;20&lt;/span&gt;       ; &lt;span class="n"&gt;Registration&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;

; === &lt;span class="n"&gt;Retransmission&lt;/span&gt; &lt;span class="n"&gt;Policy&lt;/span&gt; ===
; &lt;span class="n"&gt;Number&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;retransmissions&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;giving&lt;/span&gt; &lt;span class="n"&gt;up&lt;/span&gt;
; &lt;span class="n"&gt;Default&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;usually&lt;/span&gt; &lt;span class="m"&gt;6&lt;/span&gt;, &lt;span class="n"&gt;which&lt;/span&gt; &lt;span class="n"&gt;means&lt;/span&gt; ~&lt;span class="m"&gt;32&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt;
; &lt;span class="n"&gt;For&lt;/span&gt; &lt;span class="n"&gt;ViciDial&lt;/span&gt; &lt;span class="n"&gt;production&lt;/span&gt;: &lt;span class="m"&gt;8&lt;/span&gt;-&lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="n"&gt;is&lt;/span&gt; &lt;span class="n"&gt;safer&lt;/span&gt;
&lt;span class="n"&gt;max_retries&lt;/span&gt; = &lt;span class="m"&gt;8&lt;/span&gt;

; === &lt;span class="n"&gt;Connection&lt;/span&gt; &lt;span class="n"&gt;Management&lt;/span&gt; ===
; &lt;span class="n"&gt;Timeout&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;idle&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt; (&lt;span class="n"&gt;seconds&lt;/span&gt;)
; &lt;span class="n"&gt;Prevents&lt;/span&gt; &lt;span class="n"&gt;phantom&lt;/span&gt; &lt;span class="n"&gt;timeouts&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;long&lt;/span&gt;-&lt;span class="n"&gt;lived&lt;/span&gt; &lt;span class="n"&gt;connections&lt;/span&gt;
&lt;span class="n"&gt;tcp_connect_timeout&lt;/span&gt; = &lt;span class="m"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;tcp_read_timeout&lt;/span&gt; = &lt;span class="m"&gt;10&lt;/span&gt;

; === &lt;span class="n"&gt;Keep&lt;/span&gt;-&lt;span class="n"&gt;Alive&lt;/span&gt; / &lt;span class="n"&gt;Session&lt;/span&gt;-&lt;span class="n"&gt;Timer&lt;/span&gt; ===
; &lt;span class="n"&gt;Enable&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="n"&gt;timers&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;refresh&lt;/span&gt; &lt;span class="n"&gt;connection&lt;/span&gt; &lt;span class="n"&gt;state&lt;/span&gt;
&lt;span class="n"&gt;session_timer&lt;/span&gt; = &lt;span class="m"&gt;1800&lt;/span&gt;            ; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;timer&lt;/span&gt; &lt;span class="n"&gt;in&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt; (&lt;span class="m"&gt;30&lt;/span&gt; &lt;span class="n"&gt;minutes&lt;/span&gt;)
&lt;span class="n"&gt;session_refresher&lt;/span&gt; = &lt;span class="n"&gt;uas&lt;/span&gt;          ; &lt;span class="n"&gt;Who&lt;/span&gt; &lt;span class="n"&gt;refreshes&lt;/span&gt;: &lt;span class="n"&gt;uas&lt;/span&gt;, &lt;span class="n"&gt;uac&lt;/span&gt;, &lt;span class="n"&gt;or&lt;/span&gt; &lt;span class="n"&gt;auto&lt;/span&gt;
&lt;span class="n"&gt;session_expires&lt;/span&gt; = &lt;span class="m"&gt;1800&lt;/span&gt;
&lt;span class="n"&gt;min_se&lt;/span&gt; = &lt;span class="m"&gt;90&lt;/span&gt;

; === &lt;span class="n"&gt;Other&lt;/span&gt; &lt;span class="n"&gt;Critical&lt;/span&gt; &lt;span class="n"&gt;Settings&lt;/span&gt; ===
; &lt;span class="n"&gt;Disable&lt;/span&gt; &lt;span class="n"&gt;aggressive&lt;/span&gt; &lt;span class="n"&gt;NAT&lt;/span&gt; &lt;span class="n"&gt;if&lt;/span&gt; &lt;span class="n"&gt;you&lt;/span&gt;&lt;span class="err"&gt;'&lt;/span&gt;&lt;span class="n"&gt;ve&lt;/span&gt; &lt;span class="n"&gt;configured&lt;/span&gt; &lt;span class="n"&gt;externip&lt;/span&gt; &lt;span class="n"&gt;correctly&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt; = &lt;span class="n"&gt;no&lt;/span&gt;               ; &lt;span class="n"&gt;Force&lt;/span&gt; &lt;span class="n"&gt;media&lt;/span&gt; &lt;span class="n"&gt;through&lt;/span&gt; &lt;span class="n"&gt;Asterisk&lt;/span&gt; (&lt;span class="n"&gt;safer&lt;/span&gt;)
&lt;span class="n"&gt;nat&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;                       ; &lt;span class="n"&gt;Enable&lt;/span&gt; &lt;span class="n"&gt;NAT&lt;/span&gt; &lt;span class="n"&gt;mode&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt; = &lt;span class="m"&gt;100&lt;/span&gt;                   ; &lt;span class="n"&gt;Send&lt;/span&gt; &lt;span class="n"&gt;OPTIONS&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;peers&lt;/span&gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="m"&gt;100&lt;/span&gt;&lt;span class="n"&gt;ms&lt;/span&gt;
&lt;span class="n"&gt;qualify_timeout&lt;/span&gt; = &lt;span class="m"&gt;2&lt;/span&gt;             ; &lt;span class="n"&gt;Timeout&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;qualify&lt;/span&gt; (&lt;span class="n"&gt;seconds&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Carrier-Specific Configuration
&lt;/h3&gt;

&lt;p&gt;Each carrier endpoint needs its own timeout values. In the &lt;code&gt;[carrier_name]&lt;/code&gt; sections:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;mycarrier&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt; = &lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt; = &lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;mycarrier&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt; = &lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt; = &lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;carrier&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt; = &lt;span class="n"&gt;mycarrier&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;fromname&lt;/span&gt; = &lt;span class="n"&gt;ViciDial&lt;/span&gt;-&lt;span class="n"&gt;System&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt; = &lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt; = &lt;span class="n"&gt;ulaw&lt;/span&gt;,&lt;span class="n"&gt;alaw&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt; = &lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt; = &lt;span class="n"&gt;no&lt;/span&gt;

; &lt;span class="n"&gt;Carrier&lt;/span&gt;-&lt;span class="n"&gt;specific&lt;/span&gt; &lt;span class="n"&gt;timeouts&lt;/span&gt;
&lt;span class="n"&gt;sip_t1&lt;/span&gt; = &lt;span class="m"&gt;1000&lt;/span&gt;                   ; &lt;span class="n"&gt;Longer&lt;/span&gt; &lt;span class="n"&gt;initial&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;this&lt;/span&gt; &lt;span class="n"&gt;carrier&lt;/span&gt;
&lt;span class="n"&gt;sip_invite_timeout&lt;/span&gt; = &lt;span class="m"&gt;45&lt;/span&gt;         ; &lt;span class="n"&gt;Very&lt;/span&gt; &lt;span class="n"&gt;tolerant&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualify_timeout&lt;/span&gt; = &lt;span class="m"&gt;3&lt;/span&gt;             ; &lt;span class="n"&gt;Longer&lt;/span&gt; &lt;span class="n"&gt;qualify&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check Configuration Syntax
&lt;/h3&gt;

&lt;p&gt;Before reloading, validate the configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Validate SIP config&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-C&lt;/span&gt; /etc/asterisk/asterisk.conf &lt;span class="nt"&gt;-n&lt;/span&gt;

&lt;span class="c"&gt;# If valid, reload SIP module&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;

&lt;span class="c"&gt;# Verify the changes took effect&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show settings"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="nb"&gt;timeout&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  ViciDial-Specific Configuration
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Update ViciDial Carrier Settings via Database
&lt;/h3&gt;

&lt;p&gt;Some timeout settings are stored in the ViciDial database, not Asterisk config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Access ViciDial database&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk

&lt;span class="nt"&gt;--&lt;/span&gt; View your carriers
SELECT carrier_id, carrier_name, active FROM vicidial_carriers&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;--&lt;/span&gt; Check SIP carrier details
SELECT &lt;span class="k"&gt;*&lt;/span&gt; FROM vicidial_sip_headers WHERE carrier_id &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_CARRIER'&lt;/span&gt; &lt;span class="se"&gt;\G&lt;/span&gt;

&lt;span class="nt"&gt;--&lt;/span&gt; Update carrier settings &lt;span class="o"&gt;(&lt;/span&gt;e.g., increase &lt;span class="nb"&gt;timeout&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt;
UPDATE vicidial_carriers 
SET notes &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Timeout 45s, Qualify enabled'&lt;/span&gt;
WHERE carrier_id &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_CARRIER'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nt"&gt;--&lt;/span&gt; Check &lt;span class="k"&gt;if &lt;/span&gt;there are carrier-specific SIP parameters
SELECT &lt;span class="k"&gt;*&lt;/span&gt; FROM vicidial_sip_headers LIMIT 10&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify ViciDial Dialplan Integration
&lt;/h3&gt;

&lt;p&gt;ViciDial's dialplan in &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt; must properly route to carriers:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"from-carrier&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;from-external"&lt;/span&gt; /etc/asterisk/extensions-vicidial.conf | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Should show proper routing contexts for incoming calls from carrier&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the ViciDial web admin panel for carrier configuration:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Navigate to &lt;code&gt;/vicidial/admin.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Go to &lt;strong&gt;Carriers&lt;/strong&gt; section&lt;/li&gt;
&lt;li&gt;Edit your SIP carrier&lt;/li&gt;
&lt;li&gt;Verify:

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Carrier IP/Host&lt;/strong&gt;: Correct&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Carrier Port&lt;/strong&gt;: Usually 5060&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Protocol&lt;/strong&gt;: SIP UDP or TCP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DID Pattern&lt;/strong&gt;: Matches your incoming numbers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Active&lt;/strong&gt;: Yes&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Real-World Troubleshooting Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario 1: Intermittent Timeouts Under Load
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Timeouts happen when call volume is high, not during testing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;: Network congestion or Asterisk overload causing response delays.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check Asterisk CPU and memory under load&lt;/span&gt;
top &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;pgrep asterisk&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="c"&gt;# Check network interface statistics&lt;/span&gt;
netstat &lt;span class="nt"&gt;-i&lt;/span&gt;

&lt;span class="c"&gt;# Monitor packet loss&lt;/span&gt;
mtr &lt;span class="nt"&gt;-r&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 100 203.0.113.50 | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;

&lt;span class="c"&gt;# If packet loss &amp;gt; 2%, contact carrier or ISP&lt;/span&gt;
&lt;span class="c"&gt;# If Asterisk CPU &amp;gt; 80%, increase server resources or reduce call load&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Increase SIP timeouts further:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;sip_invite_timeout&lt;/span&gt; = &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;max_retries&lt;/span&gt; = &lt;span class="m"&gt;10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario 2: International Carrier Timeouts
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Timeouts to UK, India, or other remote carriers, but domestic calls work fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;: High latency on international routes (normal 100-300ms).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Measure latency to carrier&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 20 sip.international-carrier.com | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s1"&gt;'min/avg/max'&lt;/span&gt;

&lt;span class="c"&gt;# Example output: min/avg/max = 150.234/175.123/200.456 ms&lt;/span&gt;
&lt;span class="c"&gt;# With this latency, set sip_t1 to ~200-250ms&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Configure for international:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;international_carrier&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt; = &lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt; = &lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;international&lt;/span&gt;-&lt;span class="n"&gt;carrier&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;sip_t1&lt;/span&gt; = &lt;span class="m"&gt;250&lt;/span&gt;                    ; &lt;span class="n"&gt;Match&lt;/span&gt; &lt;span class="n"&gt;latency&lt;/span&gt;
&lt;span class="n"&gt;sip_invite_timeout&lt;/span&gt; = &lt;span class="m"&gt;60&lt;/span&gt;         ; &lt;span class="n"&gt;Very&lt;/span&gt; &lt;span class="n"&gt;tolerant&lt;/span&gt;
&lt;span class="n"&gt;max_retries&lt;/span&gt; = &lt;span class="m"&gt;10&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualify_timeout&lt;/span&gt; = &lt;span class="m"&gt;5&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario 3: DNS Resolution Failures
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Carrier works sometimes, then stops. Logs show "unresolved"&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;: Carrier hostname not resolving, or DNS is failing intermittently.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check Asterisk's DNS resolution&lt;/span&gt;
nslookup sip.carrier.com
dig sip.carrier.com

&lt;span class="c"&gt;# Force Asterisk to use specific nameserver in /etc/asterisk/asterisk.conf:&lt;/span&gt;
&lt;span class="c"&gt;# [options]&lt;/span&gt;
&lt;span class="c"&gt;# Don't add this to asterisk.conf typically, instead use system resolver&lt;/span&gt;

&lt;span class="c"&gt;# Check /etc/resolv.conf&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/resolv.conf

&lt;span class="c"&gt;# Add reliable nameservers (Google DNS, Cloudflare DNS)&lt;/span&gt;
&lt;span class="c"&gt;# Edit /etc/resolv.conf or netplan config&lt;/span&gt;

&lt;span class="c"&gt;# For Ubuntu 20.04+ (Netplan):&lt;/span&gt;
nano /etc/netplan/00-installer-config.yaml

&lt;span class="c"&gt;# Add:&lt;/span&gt;
&lt;span class="c"&gt;# nameservers:&lt;/span&gt;
&lt;span class="c"&gt;#   addresses: [8.8.8.8, 8.8.4.4, 1.1.1.1]&lt;/span&gt;

netplan apply

&lt;span class="c"&gt;# Verify:&lt;/span&gt;
nslookup sip.carrier.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Use carrier IP directly instead of hostname (if stable):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;carrier&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt; = &lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt; = &lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;50&lt;/span&gt;             ; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;IP&lt;/span&gt; &lt;span class="n"&gt;instead&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;hostname&lt;/span&gt;
; ... &lt;span class="n"&gt;rest&lt;/span&gt; &lt;span class="n"&gt;of&lt;/span&gt; &lt;span class="n"&gt;config&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario 4: One-Way Audio (RTP Issues)
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Calls connect (no 408), but no audio. Often misdiagnosed as timeout.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Root Cause&lt;/strong&gt;: RTP ports blocked or NAT misconfiguration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Solution&lt;/strong&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Ensure RTP port range is open&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"rtpstart&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;rtpend"&lt;/span&gt; /etc/asterisk/rtp.conf

&lt;span class="c"&gt;# Should show something like:&lt;/span&gt;
&lt;span class="c"&gt;# rtpstart=10000&lt;/span&gt;
&lt;span class="c"&gt;# rtpend=20000&lt;/span&gt;

&lt;span class="c"&gt;# Verify firewall allows RTP&lt;/span&gt;
iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"10000:20000"&lt;/span&gt;

&lt;span class="c"&gt;# If not present, add:&lt;/span&gt;
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 10000:20000 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
iptables &lt;span class="nt"&gt;-I&lt;/span&gt; OUTPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 10000:20000 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT

&lt;span class="c"&gt;# For carrier-specific NAT, ensure externip includes RTP:&lt;/span&gt;
&lt;span class="c"&gt;# In sip.conf: externip = YOUR_PUBLIC_IP (applies to all media)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Verify RTP is actually flowing:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Tcpdump on RTP port range during call&lt;/span&gt;
tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'udp portrange 10000-20000'&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; 50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Monitoring and Alerting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Set Up Asterisk Logging for SIP Issues
&lt;/h3&gt;

&lt;p&gt;Configure detailed SIP logging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Edit logger configuration&lt;/span&gt;
nano /etc/asterisk/logger.conf

&lt;span class="c"&gt;# Add these lines:&lt;/span&gt;
&lt;span class="o"&gt;[&lt;/span&gt;logfiles]
sip &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; WARNING,NOTICE,DEBUG
messages &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; WARNING,NOTICE,ERROR

&lt;span class="c"&gt;# Optionally log to separate file:&lt;/span&gt;
&lt;span class="c"&gt;# messages =&amp;gt; WARNING,NOTICE,ERROR(/var/log/asterisk/sip-debug.log)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload logging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"logger reload"&lt;/span&gt;

&lt;span class="c"&gt;# Tail the debug log&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"sip&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;timeout"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitor 408 Errors in ViciDial Logs
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check ViciDial call logs for 408 patterns&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
SELECT call_date, vicidial_id, length_in_sec, hangup_cause
FROM vicidial_log
WHERE hangup_cause LIKE '%408%' OR hangup_cause LIKE '%timeout%'
AND call_date &amp;gt;= DATE_SUB(NOW(), INTERVAL 1 DAY)
LIMIT 20;
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;&lt;span class="c"&gt;# Check closer log (agent-initiated calls)&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
SELECT call_date, closer_id, length_in_sec, hangup_reason
FROM vicidial_closer_log
WHERE hangup_reason LIKE '%timeout%'
AND call_date &amp;gt;= DATE_SUB(NOW(), INTERVAL 24 HOUR);
&lt;/span&gt;&lt;span class="no"&gt;EOF
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Create a Real-Time Monitoring Script
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# File: /usr/local/bin/monitor-sip-408.sh&lt;/span&gt;

&lt;span class="nv"&gt;CARRIER_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"203.0.113.50"&lt;/span&gt;
&lt;span class="nv"&gt;ALERT_EMAIL&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"admin@yourcompany.com"&lt;/span&gt;
&lt;span class="nv"&gt;THRESHOLD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;10  &lt;span class="c"&gt;# Alert if 10+ timeouts in 5 minutes&lt;/span&gt;

&lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="c"&gt;# Count recent 408s from tcpdump (5 minute window)&lt;/span&gt;
    &lt;span class="nv"&gt;TIMEOUT_COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;timeout &lt;/span&gt;10 tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s2"&gt;"host &lt;/span&gt;&lt;span class="nv"&gt;$CARRIER_IP&lt;/span&gt;&lt;span class="s2"&gt; and port 5060"&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="se"&gt;\&lt;/span&gt;
                    &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"SIP/2.0 408"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$TIMEOUT_COUNT&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$THRESHOLD&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ALERT: &lt;/span&gt;&lt;span class="nv"&gt;$TIMEOUT_COUNT&lt;/span&gt;&lt;span class="s2"&gt; SIP 408 timeouts detected"&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
        mail &lt;span class="nt"&gt;-s&lt;/span&gt; &lt;span class="s2"&gt;"ViciDial SIP 408 Alert"&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$ALERT_EMAIL&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

        &lt;span class="c"&gt;# Log to asterisk messages&lt;/span&gt;
        asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"log channel verbose &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;ALERT: High 408 timeout rate detected: &lt;/span&gt;&lt;span class="nv"&gt;$TIMEOUT_COUNT&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi

    &lt;/span&gt;&lt;span class="nb"&gt;sleep &lt;/span&gt;300  &lt;span class="c"&gt;# Check every 5 minutes&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make it executable and add to cron:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/monitor-sip-408.sh

&lt;span class="c"&gt;# Add to crontab&lt;/span&gt;
&lt;span class="o"&gt;(&lt;/span&gt;crontab &lt;span class="nt"&gt;-l&lt;/span&gt; 2&amp;gt;/dev/null&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"@reboot /usr/local/bin/monitor-sip-408.sh &amp;amp;"&lt;/span&gt;&lt;span class="o"&gt;)&lt;/span&gt; | crontab -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting Checklist
&lt;/h2&gt;

&lt;p&gt;Use this systematic approach when 408 errors occur:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="c"&gt;# ViciDial SIP 408 Diagnostic Checklist&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== SIP 408 Troubleshooting Checklist ==="&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;

&lt;span class="c"&gt;# 1. Network Connectivity&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[1] Testing carrier connectivity..."&lt;/span&gt;
&lt;span class="nv"&gt;CARRIER_IP&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"203.0.113.50"&lt;/span&gt;
&lt;span class="nb"&gt;timeout &lt;/span&gt;5 bash &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"echo &amp;gt; /dev/tcp/&lt;/span&gt;&lt;span class="nv"&gt;$CARRIER_IP&lt;/span&gt;&lt;span class="s2"&gt;/5060"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✓ Port 5060 accessible"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✗ Port 5060 blocked"&lt;/span&gt;

&lt;span class="c"&gt;# 2. Asterisk Binding&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[2] Checking Asterisk SIP bindings..."&lt;/span&gt;
netstat &lt;span class="nt"&gt;-tlnp&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep &lt;/span&gt;asterisk | &lt;span class="nb"&gt;grep &lt;/span&gt;5060 &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✓ Asterisk listening on 5060"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✗ Asterisk not bound to 5060"&lt;/span&gt;

&lt;span class="c"&gt;# 3. Firewall Rules&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[3] Verifying firewall rules..."&lt;/span&gt;
iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"5060"&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✓ Firewall rules exist"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✗ No firewall rules found"&lt;/span&gt;

&lt;span class="c"&gt;# 4. RTP Configuration&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[4] Checking RTP port range..."&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"rtpstart|rtpend"&lt;/span&gt; /etc/asterisk/rtp.conf &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✓ RTP configured"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"✗ RTP config missing"&lt;/span&gt;

&lt;span class="c"&gt;# 5. NAT Configuration&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[5] Verifying NAT settings..."&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"externip&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;nat"&lt;/span&gt; /etc/asterisk/sip-vicidial.conf | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-3&lt;/span&gt;

&lt;span class="c"&gt;# 6. Timeout Values&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[6] SIP timeout settings..."&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"sip_invite_timeout|sip_t1|max_retries"&lt;/span&gt; /etc/asterisk/sip-vicidial.conf | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-5&lt;/span&gt;

&lt;span class="c"&gt;# 7. Active Channels&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[7] Current SIP channels..."&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show channels"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

&lt;span class="c"&gt;# 8. Carrier Status&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[8] Carrier registration status..."&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; 2&amp;gt;/dev/null | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; carrier

&lt;span class="c"&gt;# 9. Recent Errors&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"[9] Recent SIP errors in logs..."&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"408&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;timeout&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;sip"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== End Diagnostic ==="&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Save as &lt;code&gt;/usr/local/bin/check-sip-408.sh&lt;/code&gt; and run:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;chmod&lt;/span&gt; +x /usr/local/bin/check-sip-408.sh
./check-sip-408.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;SIP 408 Request Timeout errors in ViciDial are almost always caused by one of these factors:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Firewall/NAT Issues&lt;/strong&gt; (most common): Ensure inbound SIP/RTP from carrier is explicitly allowed, and externip is correctly set.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Aggressive Timeouts&lt;/strong&gt;: Increase &lt;code&gt;sip_invite_timeout&lt;/code&gt; to 30-60 seconds and &lt;code&gt;sip_t1&lt;/code&gt; to 500-1000ms for production stability.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Network Path Problems&lt;/strong&gt;: Verify latency with &lt;code&gt;ping&lt;/code&gt;/&lt;code&gt;mtr&lt;/code&gt;, use &lt;code&gt;tcpdump&lt;/code&gt; to confirm packets reach Asterisk.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;Carrier Configuration&lt;/strong&gt;: Double-check carrier IP, port, and context routing in both &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt; and ViciDial database.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;strong&gt;DNS Failures&lt;/strong&gt;: Use carrier IPs directly if hostname resolution is unreliable.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Quick Fix Procedure&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Run &lt;code&gt;/usr/local/bin/check-sip-408.sh&lt;/code&gt; to identify the issue&lt;/li&gt;
&lt;li&gt;If firewall: Add rules with &lt;code&gt;iptables&lt;/code&gt; or &lt;code&gt;ufw&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;If timeouts: Update &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt; with carrier-specific settings&lt;/li&gt;
&lt;li&gt;If NAT: Verify &lt;code&gt;externip&lt;/code&gt; matches your public IP&lt;/li&gt;
&lt;li&gt;Reload SIP: &lt;code&gt;asterisk -rx "sip reload"&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Test with &lt;code&gt;tcpdump&lt;/code&gt; to confirm fix&lt;/li&gt;
&lt;li&gt;Monitor logs: &lt;code&gt;tail -f /var/log/asterisk/messages&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Most 408 issues resolve within 30 minutes using this systematic approach. Document your carrier-specific settings for future reference, and implement monitoring to catch issues before users report them.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>SIP 503 Service Unavailable — Carrier &amp; Server-Side Fixes</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Fri, 07 Aug 2026 03:30:02 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/sip-503-service-unavailable-carrier-server-side-fixes-pea</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/sip-503-service-unavailable-carrier-server-side-fixes-pea</guid>
      <description>&lt;h1&gt;
  
  
  SIP 503 Service Unavailable — Carrier &amp;amp; Server-Side Fixes
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Learn how to diagnose and resolve SIP 503 errors in ViciDial and Asterisk production environments, with carrier-side and server-side remediation strategies&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before implementing the fixes in this tutorial, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Root or sudo access to your ViciDial/Asterisk server&lt;/li&gt;
&lt;li&gt;SSH terminal access to the production system&lt;/li&gt;
&lt;li&gt;Basic understanding of SIP protocol and VoIP call flow&lt;/li&gt;
&lt;li&gt;Access to &lt;code&gt;/etc/asterisk/&lt;/code&gt; configuration directory&lt;/li&gt;
&lt;li&gt;MySQL/MariaDB access to the asterisk database&lt;/li&gt;
&lt;li&gt;Asterisk CLI knowledge (asterisk -rx commands)&lt;/li&gt;
&lt;li&gt;A working ViciDial installation (tested on 2.14+)&lt;/li&gt;
&lt;li&gt;Network monitoring tools: tcpdump, tshark, or similar&lt;/li&gt;
&lt;li&gt;Carrier/trunk documentation and support contact information&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding SIP 503 Service Unavailable
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Is a 503 Error?
&lt;/h3&gt;

&lt;p&gt;A SIP 503 Service Unavailable response indicates that the server (or the route to it) is temporarily unable to handle the request. In ViciDial and Asterisk environments, this typically means:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Carrier side:&lt;/strong&gt; The carrier's SIP infrastructure is overloaded, under maintenance, or rejecting calls&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Server side:&lt;/strong&gt; Your Asterisk instance is overloaded, channels are exhausted, or no available trunks exist&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Routing side:&lt;/strong&gt; The dial plan cannot find a valid route to the destination&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The 503 is &lt;strong&gt;not&lt;/strong&gt; a call rejection due to invalid credentials or blocked numbers—those are 401, 403, or 486. A 503 means "temporarily unavailable, try again later."&lt;/p&gt;

&lt;h3&gt;
  
  
  Common Causes in ViciDial
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Insufficient trunk channels&lt;/strong&gt; on carrier connections&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Carrier API/service outage&lt;/strong&gt; or maintenance window&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Max channels exceeded&lt;/strong&gt; on the Asterisk server&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Codec mismatch&lt;/strong&gt; between endpoints&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;NAT/firewall blocking&lt;/strong&gt; SIP responses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DNS resolution failure&lt;/strong&gt; for carrier SIP servers&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asterisk resource exhaustion&lt;/strong&gt; (memory, file descriptors, SIP slots)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Load-balanced trunk pool misconfiguration&lt;/strong&gt; (all trunks unavailable)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Carrier rate-limit or threshold hit&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Bad SIP header or malformed request&lt;/strong&gt; from ViciDial&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Carrier-Side Diagnostics and Fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Verify Carrier Trunk Configuration in ViciDial
&lt;/h3&gt;

&lt;p&gt;Log into the ViciDial web admin panel and navigate to &lt;strong&gt;System Admin → Carriers&lt;/strong&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Query the carrier configuration directly&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT carrier_id, carrier_name, active, outbound_sip_ip, outbound_sip_port, 
       max_channels, carrier_protocol FROM vicidial_carrier_log 
WHERE active='Y' 
ORDER BY carrier_id;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check the following fields:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;carrier_name&lt;/strong&gt;: Ensure the carrier is active and correctly named&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;outbound_sip_ip&lt;/strong&gt;: Verify IP matches carrier documentation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;outbound_sip_port&lt;/strong&gt;: Default is 5060; some carriers use 5061 (TLS) or custom ports&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;max_channels&lt;/strong&gt;: Should match carrier's license/plan (not 1 or 0)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;carrier_protocol&lt;/strong&gt;: Should be &lt;code&gt;SIP&lt;/code&gt; for modern deployments&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 2: Test Carrier Connectivity
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Perform basic connectivity test to carrier SIP server&lt;/span&gt;
&lt;span class="c"&gt;# Replace CARRIER_IP and PORT with your carrier's details&lt;/span&gt;
&lt;span class="nb"&gt;timeout &lt;/span&gt;5 nc &lt;span class="nt"&gt;-zv&lt;/span&gt; 203.0.113.50 5060

&lt;span class="c"&gt;# For TLS (port 5061)&lt;/span&gt;
&lt;span class="nb"&gt;timeout &lt;/span&gt;5 nc &lt;span class="nt"&gt;-zv&lt;/span&gt; 203.0.113.50 5061

&lt;span class="c"&gt;# DNS resolution test&lt;/span&gt;
nslookup sip.carrier.example.com
dig sip.carrier.example.com +short
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the connection times out or DNS fails, contact your carrier immediately. If connectivity is good, continue to step 3.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 3: Monitor Real-Time SIP Traffic
&lt;/h3&gt;

&lt;p&gt;Use tcpdump to capture SIP traffic to the carrier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Capture SIP traffic to specific carrier IP (replace with actual IP)&lt;/span&gt;
tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="nt"&gt;-n&lt;/span&gt; &lt;span class="s1"&gt;'host 203.0.113.50 and (port 5060 or port 5061)'&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt;

&lt;span class="c"&gt;# Alternatively, use tshark for more detailed SIP analysis&lt;/span&gt;
tshark &lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s1"&gt;'host 203.0.113.50 and port 5060'&lt;/span&gt; &lt;span class="nt"&gt;-O&lt;/span&gt; SIP | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;INVITE&lt;/strong&gt; messages sent (should see FROM/TO headers)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIP/2.0 100 Trying&lt;/strong&gt; (carrier acknowledges receipt)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIP/2.0 503 Service Unavailable&lt;/strong&gt; (where the failure occurs)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;SIP/2.0 200 OK&lt;/strong&gt; (successful calls, for comparison)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A 503 response without "100 Trying" suggests the carrier is rejecting at gateway level, not downstream.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 4: Check Carrier Account Status and Limits
&lt;/h3&gt;

&lt;p&gt;Contact your carrier's technical support and request:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Account/trunk status&lt;/strong&gt; — Is the account active? Any blocks?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Current channel utilization&lt;/strong&gt; — Are you at max concurrent channels?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Rate limits&lt;/strong&gt; — CPS (calls per second) or PPS (packets per second) limits&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;IP allowlist&lt;/strong&gt; — Is your ViciDial server IP whitelisted?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Maintenance windows&lt;/strong&gt; — Any scheduled maintenance today?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Recent changes&lt;/strong&gt; — Any recent carrier-side configuration changes?&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Step 5: Review ViciDial Trunk Configuration File
&lt;/h3&gt;

&lt;p&gt;Check the SIP trunk definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View the carrier-specific SIP context&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 50 &lt;span class="s2"&gt;"carrier_"&lt;/span&gt; /etc/asterisk/sip-vicidial.conf | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for your carrier's SIP registration block. It should resemble:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;carrier_mycarrier&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;50&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt;=&lt;span class="n"&gt;youraccountid&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;yoursecretkey&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;carrier&lt;/span&gt;.&lt;span class="n"&gt;example&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;youraccountid&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;carrier&lt;/span&gt;
&lt;span class="n"&gt;canreinvite&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;dtmfmode&lt;/span&gt;=&lt;span class="n"&gt;rfc2833&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;alaw&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;register&lt;/span&gt;=&amp;gt;&lt;span class="n"&gt;youraccountid&lt;/span&gt;:&lt;span class="n"&gt;yoursecretkey&lt;/span&gt;@&lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;50&lt;/span&gt;:&lt;span class="m"&gt;5060&lt;/span&gt;/&lt;span class="n"&gt;youraccountid&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical checks:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;username/secret&lt;/strong&gt;: Match carrier account credentials&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;host/port&lt;/strong&gt;: Match carrier's primary SIP server (not a secondary or failover)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;register&lt;/strong&gt; line: Must be present and correct; it registers your trunk with the carrier&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;allow codecs&lt;/strong&gt;: Must match carrier's supported codecs (ulaw is safest)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;nat=yes&lt;/strong&gt;: Enable if your ViciDial server is behind NAT&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;insecure=port,invite&lt;/strong&gt;: May be required by some carriers for IP-based auth&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 6: Force Trunk Re-registration
&lt;/h3&gt;

&lt;p&gt;After correcting configuration, force Asterisk to re-register with the carrier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Reload SIP configuration&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;

&lt;span class="c"&gt;# Unregister and re-register&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip unregister carrier_mycarrier"&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;2
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip register carrier_mycarrier"&lt;/span&gt;

&lt;span class="c"&gt;# Verify registration status&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show registry"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output from &lt;code&gt;sip show registry&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host                            dnsmgr Username       State       Reg.Expires ID
203.0.113.50:5060               N      youraccountid  Registered  60
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the state is "Unregistered" or "Rejected," review the carrier credentials and contact support.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 7: Check Carrier-Specific Rate Limits
&lt;/h3&gt;

&lt;p&gt;Some carriers enforce strict CPS (calls per second) or concurrent channel limits. Query your recent call volume:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check concurrent calls in the last hour&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT DATE_FORMAT(call_date, '%Y-%m-%d %H:00:00') as hour,
       COUNT(*) as total_calls,
       SUM(IF(call_duration &amp;gt; 0, 1, 0)) as connected_calls,
       SUM(IF(call_duration = 0, 1, 0)) as failed_calls
FROM vicidial_log
WHERE call_date &amp;gt;= DATE_SUB(NOW(), INTERVAL 1 HOUR)
AND carrier_id = 'CARRIER_ID_HERE'
GROUP BY hour
ORDER BY hour DESC;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see a spike corresponding to 503 errors, you may have exceeded the carrier's threshold. Request higher limits or implement call-rate throttling.&lt;/p&gt;

&lt;h2&gt;
  
  
  Server-Side Diagnostics and Fixes
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Step 1: Check Asterisk Channel Availability
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View current SIP channel status&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show channels"&lt;/span&gt;

&lt;span class="c"&gt;# Count active channels&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show channels"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-c&lt;/span&gt; &lt;span class="s2"&gt;"sip:"&lt;/span&gt;

&lt;span class="c"&gt;# View max channels setting&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show settings"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"maxcallbitrate&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;max"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if channels are approaching the configured maximum:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Query Asterisk config for max channels&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"^maxchannels"&lt;/span&gt; /etc/asterisk/asterisk.conf

&lt;span class="c"&gt;# Default is usually unlimited or 1000; for ViciDial, set explicitly&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /etc/asterisk/asterisk.conf | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 5 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;options&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 2: Monitor System Resources
&lt;/h3&gt;

&lt;p&gt;A 503 often indicates resource exhaustion. Check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Memory usage&lt;/span&gt;
free &lt;span class="nt"&gt;-h&lt;/span&gt;

&lt;span class="c"&gt;# CPU load&lt;/span&gt;
&lt;span class="nb"&gt;uptime&lt;/span&gt;

&lt;span class="c"&gt;# Disk I/O&lt;/span&gt;
iostat &lt;span class="nt"&gt;-x&lt;/span&gt; 1 5

&lt;span class="c"&gt;# File descriptors in use&lt;/span&gt;
lsof &lt;span class="nt"&gt;-p&lt;/span&gt; &lt;span class="si"&gt;$(&lt;/span&gt;pgrep &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"asterisk -p"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;

&lt;span class="c"&gt;# Network connections by state&lt;/span&gt;
netstat &lt;span class="nt"&gt;-an&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;SIP | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
netstat &lt;span class="nt"&gt;-an&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;ESTABLISHED | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical thresholds:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Memory&lt;/strong&gt;: If free memory &amp;lt; 500 MB, Asterisk may fail to allocate SIP slots&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;CPU&lt;/strong&gt;: Load &amp;gt; 80% of cores indicates saturation&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;File descriptors&lt;/strong&gt;: If approaching the system limit (usually 1024 or more), increase with &lt;code&gt;ulimit -n&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Network&lt;/strong&gt;: If SIP connections &amp;gt; 5000, you may hit kernel limits&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Step 3: Increase File Descriptor Limits
&lt;/h3&gt;

&lt;p&gt;Edit the Asterisk systemd service or init script:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# For systemd-based systems (modern ViciDial)&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /etc/systemd/system/asterisk.service.d/limits.conf &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="sh"&gt;'&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;'
[Service]
LimitNOFILE=65536
LimitNPROC=65536
&lt;/span&gt;&lt;span class="no"&gt;EOF

&lt;/span&gt;systemctl daemon-reload
systemctl restart asterisk

&lt;span class="c"&gt;# Verify&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /proc/&lt;span class="si"&gt;$(&lt;/span&gt;pgrep &lt;span class="nt"&gt;-f&lt;/span&gt; &lt;span class="s2"&gt;"asterisk -p"&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;/limits | &lt;span class="nb"&gt;grep &lt;/span&gt;files
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For older init.d systems:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Edit /etc/init.d/asterisk&lt;/span&gt;
&lt;span class="c"&gt;# Add before asterisk startup:&lt;/span&gt;
&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; 65536
&lt;span class="nb"&gt;ulimit&lt;/span&gt; &lt;span class="nt"&gt;-u&lt;/span&gt; 65536
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 4: Review Asterisk SIP Channel Limits
&lt;/h3&gt;

&lt;p&gt;Check the main SIP configuration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# View SIP channel configuration&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"^maxexpire|^minexpire|^defaultexpire|^srvlookup"&lt;/span&gt; /etc/asterisk/sip.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Add or adjust these settings in &lt;code&gt;/etc/asterisk/sip.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
; &lt;span class="n"&gt;Increase&lt;/span&gt; &lt;span class="n"&gt;SIP&lt;/span&gt; &lt;span class="n"&gt;slot&lt;/span&gt; &lt;span class="n"&gt;capacity&lt;/span&gt;
&lt;span class="n"&gt;maxchannels&lt;/span&gt; = &lt;span class="m"&gt;2000&lt;/span&gt;

; &lt;span class="n"&gt;Enable&lt;/span&gt; &lt;span class="n"&gt;DNS&lt;/span&gt; &lt;span class="n"&gt;SRV&lt;/span&gt; &lt;span class="n"&gt;lookups&lt;/span&gt; &lt;span class="n"&gt;for&lt;/span&gt; &lt;span class="n"&gt;carrier&lt;/span&gt; &lt;span class="n"&gt;failover&lt;/span&gt;
&lt;span class="n"&gt;srvlookup&lt;/span&gt; = &lt;span class="n"&gt;yes&lt;/span&gt;

; &lt;span class="n"&gt;Optimize&lt;/span&gt; &lt;span class="n"&gt;timers&lt;/span&gt;
&lt;span class="n"&gt;minexpire&lt;/span&gt; = &lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;defaultexpire&lt;/span&gt; = &lt;span class="m"&gt;3600&lt;/span&gt;
&lt;span class="n"&gt;maxexpire&lt;/span&gt; = &lt;span class="m"&gt;3600&lt;/span&gt;

; &lt;span class="n"&gt;Enable&lt;/span&gt; &lt;span class="n"&gt;call&lt;/span&gt; &lt;span class="n"&gt;completion&lt;/span&gt; &lt;span class="n"&gt;on&lt;/span&gt; &lt;span class="n"&gt;busy&lt;/span&gt; &lt;span class="n"&gt;subscriber&lt;/span&gt; (&lt;span class="n"&gt;CCBS&lt;/span&gt;) &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;reduce&lt;/span&gt; &lt;span class="n"&gt;rejections&lt;/span&gt;
; &lt;span class="n"&gt;This&lt;/span&gt; &lt;span class="n"&gt;requires&lt;/span&gt; &lt;span class="n"&gt;carrier&lt;/span&gt; &lt;span class="n"&gt;support&lt;/span&gt;
&lt;span class="n"&gt;ccbsmode&lt;/span&gt; = &lt;span class="n"&gt;core&lt;/span&gt;

; &lt;span class="n"&gt;Increase&lt;/span&gt; &lt;span class="n"&gt;UDP&lt;/span&gt; &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="n"&gt;size&lt;/span&gt;
&lt;span class="n"&gt;udpbuffersize&lt;/span&gt; = &lt;span class="m"&gt;262144&lt;/span&gt;

; &lt;span class="n"&gt;Session&lt;/span&gt; &lt;span class="n"&gt;timers&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;detect&lt;/span&gt; &lt;span class="n"&gt;dead&lt;/span&gt; &lt;span class="n"&gt;calls&lt;/span&gt;
&lt;span class="n"&gt;session_expires&lt;/span&gt; = &lt;span class="m"&gt;1800&lt;/span&gt;
&lt;span class="n"&gt;session_minse&lt;/span&gt; = &lt;span class="m"&gt;90&lt;/span&gt;
&lt;span class="n"&gt;sessiontimeout&lt;/span&gt; = &lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;After changes, reload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 5: Optimize Codec Selection
&lt;/h3&gt;

&lt;p&gt;Codec negotiation failures can trigger 503s. Enforce a single, widely-supported codec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Current codec configuration for a trunk&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 10 &lt;span class="s2"&gt;"carrier_mycarrier&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; /etc/asterisk/sip-vicidial.conf | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"allow|disallow"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Update to use only G.711 µ-law (most universal):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;carrier_mycarrier&lt;/span&gt;]
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 6: Monitor Asterisk Logs for Errors
&lt;/h3&gt;

&lt;p&gt;Real-time log monitoring:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Tail Asterisk messages log&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"503&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;service&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;unavailable"&lt;/span&gt;

&lt;span class="c"&gt;# Search for recent errors&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"service.*unavailable&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;503"&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;

&lt;span class="c"&gt;# Full SIP debug output (verbose, use sparingly)&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
&lt;span class="c"&gt;# ... make a test call ...&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug off"&lt;/span&gt;

&lt;span class="c"&gt;# Check debug output&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"sip.*debug&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;--"&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-50&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 7: Enable and Check Asterisk Queue Logs
&lt;/h3&gt;

&lt;p&gt;ViciDial relies on queue logs to track call outcomes. Verify they're being written:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check queue logging&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"^queue_log"&lt;/span&gt; /etc/asterisk/logger.conf

&lt;span class="c"&gt;# Ensure this line exists:&lt;/span&gt;
&lt;span class="c"&gt;# queue_log =&amp;gt; queue_log&lt;/span&gt;

&lt;span class="c"&gt;# Restart logger if needed&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"logger reload"&lt;/span&gt;

&lt;span class="c"&gt;# Verify queue_log file exists and is being written&lt;/span&gt;
&lt;span class="nb"&gt;ls&lt;/span&gt; &lt;span class="nt"&gt;-lh&lt;/span&gt; /var/log/asterisk/queue_log
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt; /var/log/asterisk/queue_log | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"COMPLETE&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;503"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 8: Check ViciDial Dial Plan Logic
&lt;/h3&gt;

&lt;p&gt;Review the outbound dial plan for the carrier. In ViciDial, this is controlled by &lt;code&gt;extensions-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Search for outbound call routing&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 30 &lt;span class="s2"&gt;"^exten =&amp;gt; _[0-9]"&lt;/span&gt; /etc/asterisk/extensions-vicidial.conf | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 30 &lt;span class="s2"&gt;"Dial&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;SIP"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for a pattern like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;OUTBOUND_GROUP&lt;/span&gt;=${&lt;span class="n"&gt;CHANNEL&lt;/span&gt;(&lt;span class="n"&gt;group&lt;/span&gt;)})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;2&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;GROUP_COUNT_LIMIT&lt;/span&gt;=&lt;span class="m"&gt;10&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;3&lt;/span&gt;,&lt;span class="n"&gt;CheckGroup&lt;/span&gt;()
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;4&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;}@&lt;span class="n"&gt;carrier_mycarrier&lt;/span&gt;,&lt;span class="m"&gt;45&lt;/span&gt;,&lt;span class="n"&gt;TM&lt;/span&gt;(&lt;span class="n"&gt;custom_hangup&lt;/span&gt;))
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;5&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If &lt;code&gt;CheckGroup()&lt;/code&gt; is blocking calls due to GROUP_COUNT_LIMIT, increase the limit:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;2&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;GROUP_COUNT_LIMIT&lt;/span&gt;=&lt;span class="m"&gt;100&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload dialplan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Step 9: Monitor ViciDial Call Log for Patterns
&lt;/h3&gt;

&lt;p&gt;Use the ViciDial database to identify 503 error rates:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Find all calls with 503 or similar SIP errors in the last hour&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;length&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;call_duration&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;duration_sec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="n"&gt;SIP_RESPONSE&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;HOUR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;AND&lt;/span&gt; &lt;span class="n"&gt;SIP_RESPONSE&lt;/span&gt; &lt;span class="k"&gt;IN&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'503'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'500'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'502'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;
&lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;20&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If SIP_RESPONSE is NULL, check the &lt;code&gt;call_result&lt;/code&gt; field:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="c1"&gt;-- Alternative: filter by call_result&lt;/span&gt;
&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;phone_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="k"&gt;COUNT&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;
&lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt;
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;DATE_SUB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt; &lt;span class="n"&gt;INTERVAL&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="n"&gt;HOUR&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;call_result&lt;/span&gt;
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you see a spike in "FAILED" or "SERVICE_UNAVAILABLE" call results, correlate with the time of the 503 errors.&lt;/p&gt;

&lt;h3&gt;
  
  
  Step 10: Implement Call Rate Throttling
&lt;/h3&gt;

&lt;p&gt;If you're generating calls too quickly for the carrier or your own system, implement rate limiting in the ViciDial dial plan:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;; &lt;span class="n"&gt;In&lt;/span&gt; &lt;span class="n"&gt;extensions&lt;/span&gt;-&lt;span class="n"&gt;vicidial&lt;/span&gt;.&lt;span class="n"&gt;conf&lt;/span&gt;, &lt;span class="n"&gt;add&lt;/span&gt; &lt;span class="n"&gt;before&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;Dial&lt;/span&gt;() &lt;span class="n"&gt;command&lt;/span&gt;
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;2&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;GROUP_COUNT_LIMIT&lt;/span&gt;=&lt;span class="m"&gt;20&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;3&lt;/span&gt;,&lt;span class="n"&gt;Set&lt;/span&gt;(&lt;span class="n"&gt;OUTBOUND_GROUP&lt;/span&gt;=${&lt;span class="n"&gt;CHANNEL&lt;/span&gt;(&lt;span class="n"&gt;group&lt;/span&gt;)})
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;4&lt;/span&gt;,&lt;span class="n"&gt;CheckGroup&lt;/span&gt;()
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;5&lt;/span&gt;,&lt;span class="n"&gt;Wait&lt;/span&gt;(&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;5&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="n"&gt;NXXNXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;6&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;}@&lt;span class="n"&gt;carrier_mycarrier&lt;/span&gt;,&lt;span class="m"&gt;45&lt;/span&gt;,&lt;span class="n"&gt;TM&lt;/span&gt;())
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Adjust the &lt;code&gt;Wait()&lt;/code&gt; duration to throttle call initiation (0.5 = 500ms delay per call).&lt;/p&gt;

&lt;p&gt;Alternatively, set a CPS limit in ViciDial's carrier config:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# In ViciDial web admin, set the carrier's "CPS Limit" field to a conservative value&lt;/span&gt;
&lt;span class="c"&gt;# (e.g., 10 calls/second) and reload the carrier&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Advanced Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario 1: 503 Only on Specific Destinations
&lt;/h3&gt;

&lt;p&gt;If 503 errors occur only for certain phone numbers or prefixes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Query logs filtered by destination prefix&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT phone_number, COUNT(*) as attempts, 
       SUM(IF(SIP_RESPONSE = '503', 1, 0)) as sip_503_count
FROM vicidial_log
WHERE call_date &amp;gt;= DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY SUBSTR(phone_number, 1, 3)
ORDER BY sip_503_count DESC;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This may indicate a &lt;strong&gt;route-specific issue&lt;/strong&gt; on the carrier. Contact support for that specific destination or region.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 2: 503 During Peak Hours
&lt;/h3&gt;

&lt;p&gt;If 503s only occur during peak call volumes (e.g., 9 AM - 5 PM):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Identify peak hour patterns&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT DATE_FORMAT(call_date, '%Y-%m-%d %H:00:00') as hour_block,
       COUNT(*) as total_calls,
       SUM(IF(SIP_RESPONSE = '503', 1, 0)) as sip_503_count,
       ROUND(100 * SUM(IF(SIP_RESPONSE = '503', 1, 0)) / COUNT(*), 2) as fail_rate_pct
FROM vicidial_log
WHERE call_date &amp;gt;= DATE_SUB(NOW(), INTERVAL 7 DAY)
GROUP BY hour_block
ORDER BY fail_rate_pct DESC;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request carrier to increase allocated channels&lt;/li&gt;
&lt;li&gt;Implement call queuing: instead of rejecting with 503, queue calls and retry when capacity available&lt;/li&gt;
&lt;li&gt;Load-balance across multiple carrier trunks&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Scenario 3: 503 + High Latency
&lt;/h3&gt;

&lt;p&gt;If network latency to the carrier is high (&amp;gt; 200ms), SIP timeouts may trigger 503s:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Measure latency to carrier SIP server&lt;/span&gt;
ping &lt;span class="nt"&gt;-c&lt;/span&gt; 10 203.0.113.50

&lt;span class="c"&gt;# For UDP latency (more accurate for SIP)&lt;/span&gt;
mtr &lt;span class="nt"&gt;-c&lt;/span&gt; 10 203.0.113.50
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If latency &amp;gt; 200ms:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Contact your ISP or network provider&lt;/li&gt;
&lt;li&gt;Request a dedicated link to the carrier&lt;/li&gt;
&lt;li&gt;Implement connection pooling in Asterisk to reduce RTT&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Increase SIP timeout in asterisk.conf:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;options&lt;/span&gt;]
; &lt;span class="n"&gt;Increase&lt;/span&gt; &lt;span class="n"&gt;SIP&lt;/span&gt; &lt;span class="n"&gt;transaction&lt;/span&gt; &lt;span class="n"&gt;timeout&lt;/span&gt; &lt;span class="n"&gt;from&lt;/span&gt; &lt;span class="n"&gt;default&lt;/span&gt; (&lt;span class="m"&gt;6&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt;) &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="m"&gt;10&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt;
&lt;span class="n"&gt;maxcallbitrate&lt;/span&gt; = &lt;span class="m"&gt;384&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Unfortunately, Asterisk's SIP timeout is not easily configurable per-trunk; you may need to upgrade to PJSIP channel driver (Asterisk 13+) for finer control.&lt;/p&gt;

&lt;h3&gt;
  
  
  Scenario 4: 503 + High Memory Usage
&lt;/h3&gt;

&lt;p&gt;If system memory is near capacity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check memory by process&lt;/span&gt;
ps aux &lt;span class="nt"&gt;--sort&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;-%mem | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;

&lt;span class="c"&gt;# Monitor Asterisk memory specifically&lt;/span&gt;
watch &lt;span class="nt"&gt;-n&lt;/span&gt; 1 &lt;span class="s1"&gt;'ps aux | grep -i asterisk | grep -v grep'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Solutions:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Restart Asterisk during a maintenance window&lt;/li&gt;
&lt;li&gt;Increase server RAM&lt;/li&gt;
&lt;li&gt;Reduce call queue size or max concurrent calls&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Restart Asterisk cleanly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core stop gracefully"&lt;/span&gt;
&lt;span class="c"&gt;# Wait for all calls to complete (check status)&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;30
/etc/init.d/asterisk start

&lt;span class="c"&gt;# Verify restart&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core show version"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue: "Registration failed" for carrier trunk
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Incorrect SIP credentials or carrier doesn't recognize the IP.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Verify credentials in sip-vicidial.conf&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 5 &lt;span class="s2"&gt;"username=&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;secret="&lt;/span&gt; /etc/asterisk/sip-vicidial.conf

&lt;span class="c"&gt;# Confirm with carrier documentation&lt;/span&gt;
&lt;span class="c"&gt;# Reload SIP and check registration&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show registry"&lt;/span&gt;

&lt;span class="c"&gt;# Check detailed registration attempt&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
&lt;span class="c"&gt;# Reload SIP&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;span class="c"&gt;# Wait 10 seconds&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;10
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug off"&lt;/span&gt;
&lt;span class="c"&gt;# Review logs&lt;/span&gt;
&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"register&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;auth"&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-30&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Calls fail immediately with 503, no "100 Trying" response
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Carrier is rejecting at gateway level (possibly due to IP allowlist or account block).&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify your server's public IP:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   dig @8.8.8.8 myserver.example.com +short
   &lt;span class="c"&gt;# or&lt;/span&gt;
   curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://ifconfig.me
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Contact carrier and request they whitelist your IP&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Check if carrier requires specific SIP headers or authentication method:&lt;br&gt;
&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="c"&gt;# Enable detailed SIP logging&lt;/span&gt;
   asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
   &lt;span class="c"&gt;# Attempt a call&lt;/span&gt;
   &lt;span class="c"&gt;# Check logs for authentication challenges&lt;/span&gt;
   &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"401&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;407"&lt;/span&gt; /var/log/asterisk/messages
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Random 503s, no correlation with load or time
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Intermittent carrier connectivity or DNS resolution failures.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Test carrier DNS continuously&lt;/span&gt;
watch &lt;span class="nt"&gt;-n&lt;/span&gt; 1 &lt;span class="s1"&gt;'dig sip.carrier.example.com +short'&lt;/span&gt;

&lt;span class="c"&gt;# Verify DNS resolution doesn't change&lt;/span&gt;
&lt;span class="k"&gt;for &lt;/span&gt;i &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;1..20&lt;span class="o"&gt;}&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do &lt;/span&gt;dig sip.carrier.example.com +short&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="nb"&gt;sleep &lt;/span&gt;1&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;done&lt;/span&gt;

&lt;span class="c"&gt;# If DNS is inconsistent, set static IP in sip.conf&lt;/span&gt;
&lt;span class="c"&gt;# Instead of: host=sip.carrier.example.com&lt;/span&gt;
&lt;span class="c"&gt;# Use: host=203.0.113.50 (static IP)&lt;/span&gt;

&lt;span class="c"&gt;# Reload SIP&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If carrier's DNS is unreliable, request their static SIP server IP.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue: 503 after Asterisk restart
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; SIP registration hasn't completed yet.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Monitor registration status during startup&lt;/span&gt;
watch &lt;span class="nt"&gt;-n&lt;/span&gt; 2 &lt;span class="s1"&gt;'asterisk -rx "sip show registry"'&lt;/span&gt;

&lt;span class="c"&gt;# Wait for all trunks to show "Registered" status&lt;/span&gt;
&lt;span class="c"&gt;# This typically takes 10-30 seconds&lt;/span&gt;

&lt;span class="c"&gt;# If any trunk remains "Unregistered" after 1 minute, check:&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;carrier_mycarrier

&lt;span class="c"&gt;# Force re-registration&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip unregister carrier_mycarrier"&lt;/span&gt;
&lt;span class="nb"&gt;sleep &lt;/span&gt;3
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip register carrier_mycarrier"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: 503 for international calls only
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Carrier may not have routing to that destination, or special handling required.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Query international call attempts&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; root &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT phone_number, COUNT(*) as attempts,
       SUM(IF(SIP_RESPONSE = '503', 1, 0)) as sip_503_count
FROM vicidial_log
WHERE call_date &amp;gt;= DATE_SUB(NOW(), INTERVAL 1 DAY)
AND phone_number LIKE '00%' OR phone_number LIKE '+%'
GROUP BY SUBSTR(phone_number, 1, 3)
ORDER BY sip_503_count DESC;"&lt;/span&gt;

&lt;span class="c"&gt;# Contact carrier and verify:&lt;/span&gt;
&lt;span class="c"&gt;# 1. International routing is enabled on account&lt;/span&gt;
&lt;span class="c"&gt;# 2. Destination country is in approved list&lt;/span&gt;
&lt;span class="c"&gt;# 3. Specific prefix handling (e.g., +1 vs 1)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Carrier returns 503 with "Temporarily Unavailable" message
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Cause:&lt;/strong&gt; Carrier is overloaded or performing maintenance.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Fix:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check carrier status page or contact support&lt;/span&gt;
&lt;span class="c"&gt;# In the meantime, implement automatic failover:&lt;/span&gt;

&lt;span class="c"&gt;# In extensions-vicidial.conf, add a secondary carrier&lt;/span&gt;
exten &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; _1NXXNXXXXXX,4,Dial&lt;span class="o"&gt;(&lt;/span&gt;SIP/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;EXTEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;@carrier_mycarrier,30,TM&lt;span class="o"&gt;())&lt;/span&gt;
exten &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; _1NXXNXXXXXX,5,Dial&lt;span class="o"&gt;(&lt;/span&gt;SIP/&lt;span class="k"&gt;${&lt;/span&gt;&lt;span class="nv"&gt;EXTEN&lt;/span&gt;&lt;span class="k"&gt;}&lt;/span&gt;@carrier_backup,30,TM&lt;span class="o"&gt;())&lt;/span&gt;
exten &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; _1NXXNXXXXXX,6,Hangup&lt;span class="o"&gt;()&lt;/span&gt;

&lt;span class="c"&gt;# Reload dialplan&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"dialplan reload"&lt;/span&gt;

&lt;span class="c"&gt;# Verify both carriers are registered&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show registry"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Resolving SIP 503 Service Unavailable errors requires systematic diagnosis of both carrier-side and server-side factors:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Carrier-side fixes:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Verify trunk configuration (IP, port, credentials)&lt;/li&gt;
&lt;li&gt;Test connectivity to carrier SIP server&lt;/li&gt;
&lt;li&gt;Monitor SIP traffic for 503 responses&lt;/li&gt;
&lt;li&gt;Contact carrier for account status, channel limits, and rate limits&lt;/li&gt;
&lt;li&gt;Force trunk re-registration&lt;/li&gt;
&lt;li&gt;Check for geographic or destination-specific routing issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Server-side fixes:&lt;/strong&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Monitor Asterisk channel availability and resource usage&lt;/li&gt;
&lt;li&gt;Increase file descriptor limits and SIP maxchannels&lt;/li&gt;
&lt;li&gt;Optimize codec selection for carrier compatibility&lt;/li&gt;
&lt;li&gt;Review and fix dial plan logic (CheckGroup limits)&lt;/li&gt;
&lt;li&gt;Enable call rate throttling to prevent overload&lt;/li&gt;
&lt;li&gt;Monitor ViciDial logs for error patterns&lt;/li&gt;
&lt;li&gt;Implement call queuing and failover to secondary carriers&lt;/li&gt;
&lt;li&gt;Address network latency and DNS issues&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Prevention:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Set up continuous monitoring of SIP registration status and channel utilization&lt;/li&gt;
&lt;li&gt;Implement alerting when carrier registration fails or channel usage exceeds 80%&lt;/li&gt;
&lt;li&gt;Schedule regular carrier connectivity tests&lt;/li&gt;
&lt;li&gt;Maintain redundant carrier connections&lt;/li&gt;
&lt;li&gt;Document carrier SIP configurations with clear comments&lt;/li&gt;
&lt;li&gt;Keep Asterisk and ViciDial updated to latest stable versions&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Most 503 errors resolve quickly once you identify whether the issue is carrier-side (contact support) or server-side (resource scaling or configuration). Use the diagnostic commands in this tutorial to pinpoint the root cause and apply targeted fixes.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>SIP 403 Forbidden Error — Trunk Authentication Troubleshooting</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Thu, 06 Aug 2026 03:30:02 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/sip-403-forbidden-error-trunk-authentication-troubleshooting-5024</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/sip-403-forbidden-error-trunk-authentication-troubleshooting-5024</guid>
      <description>&lt;h1&gt;
  
  
  SIP 403 Forbidden Error — Trunk Authentication Troubleshooting
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master the complete diagnostic and resolution process for SIP 403 Forbidden errors affecting your ViciDial trunks and Asterisk SIP authentication&lt;/strong&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Overview
&lt;/h2&gt;

&lt;p&gt;A SIP 403 Forbidden error indicates that your Asterisk server attempted to authenticate with a remote SIP trunk provider, but the credentials or authorization rules were rejected. In ViciDial production environments, this manifests as failed outbound calls, dropped inbound routes, and frustrated agents seeing "trunk unavailable" errors.&lt;/p&gt;

&lt;p&gt;This tutorial covers the exact troubleshooting methodology used in production ViciDial deployments running hundreds of concurrent calls. You'll learn to diagnose root causes, modify configurations, validate changes, and implement monitoring to prevent future occurrences.&lt;/p&gt;

&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Active ViciDial installation (16.x or later)&lt;/li&gt;
&lt;li&gt;Root or sudo access to your Asterisk server&lt;/li&gt;
&lt;li&gt;Familiarity with Linux command line and basic Asterisk concepts&lt;/li&gt;
&lt;li&gt;Access to &lt;code&gt;/etc/asterisk/&lt;/code&gt; configuration directory&lt;/li&gt;
&lt;li&gt;ViciDial MySQL database credentials&lt;/li&gt;
&lt;li&gt;SIP trunk provider account details and authentication parameters&lt;/li&gt;
&lt;li&gt;Working Asterisk CLI access via &lt;code&gt;asterisk -rx&lt;/code&gt; commands&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Understanding SIP 403 Forbidden in Context
&lt;/h2&gt;

&lt;h3&gt;
  
  
  What Causes 403 Forbidden Errors
&lt;/h3&gt;

&lt;p&gt;A 403 Forbidden response in SIP means the upstream server understood your request but refused to authorize it. Unlike 401 (Unauthorized, requiring credentials) or 407 (Proxy Authentication Required), a 403 indicates:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Invalid or expired credentials&lt;/li&gt;
&lt;li&gt;Username/password mismatch&lt;/li&gt;
&lt;li&gt;IP authentication failure&lt;/li&gt;
&lt;li&gt;Rate limiting or blacklisting&lt;/li&gt;
&lt;li&gt;Missing or incorrect authentication headers&lt;/li&gt;
&lt;li&gt;Codec mismatch (rarely, but possible)&lt;/li&gt;
&lt;li&gt;Subscriber not authorized for that endpoint&lt;/li&gt;
&lt;li&gt;Account suspension or payment issues&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Where ViciDial Processes Trunk Authentication
&lt;/h3&gt;

&lt;p&gt;ViciDial manages trunks through:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;SIP Configuration Files&lt;/strong&gt;: &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt; contains peer definitions&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Database&lt;/strong&gt;: &lt;code&gt;vicidial_carrier_log&lt;/code&gt; and trunk definitions in Asterisk dialplan&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Extensions Dialplan&lt;/strong&gt;: &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt; routes calls through specific trunks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Asterisk Core&lt;/strong&gt;: Processes authentication before sending requests upstream&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  ViciDial Trunk Configuration Structure
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Database Trunk Definition
&lt;/h3&gt;

&lt;p&gt;First, verify your trunk exists in the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; &lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'YOUR_TRUNK_ID'&lt;/span&gt;&lt;span class="err"&gt;\&lt;/span&gt;&lt;span class="k"&gt;G&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For carrier-level configuration, check:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;auth_type&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_user&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_pass&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ip_address&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_carrier_log&lt;/span&gt; &lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;date_added&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  SIP Peer Configuration
&lt;/h3&gt;

&lt;p&gt;Locate your trunk definition in &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;mytrunksip&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;provider&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;username&lt;/span&gt;=&lt;span class="n"&gt;youraccountname&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;yourpassword&lt;/span&gt;
&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;youraccountname&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;provider&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;trunk&lt;/span&gt;
&lt;span class="n"&gt;insecure&lt;/span&gt;=&lt;span class="n"&gt;port&lt;/span&gt;,&lt;span class="n"&gt;invite&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;canreinvite&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;dtmfmode&lt;/span&gt;=&lt;span class="n"&gt;rfc2833&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;force_rport&lt;/span&gt;,&lt;span class="n"&gt;comedia&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Key fields related to 403 errors:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;username&lt;/code&gt;: The authentication username (must match provider account)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;secret&lt;/code&gt;: The password (must match provider configuration exactly)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fromuser&lt;/code&gt;: The From: header username in outbound requests&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;fromdomain&lt;/code&gt;: The domain used in From: header&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;host&lt;/code&gt;: The upstream provider's SIP server address&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;insecure&lt;/code&gt;: Whether to accept requests without authentication verification&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 1: Locate and Review SIP Trunk Logs
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Enable SIP Debug Logging
&lt;/h3&gt;

&lt;p&gt;First, enable full SIP debugging to capture the actual 403 response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Generate a test call and watch the console output in real-time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"sip&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;forbidden&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;auth"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Capture Full SIP Trace
&lt;/h3&gt;

&lt;p&gt;For detailed analysis, use tcpdump to capture the raw SIP messages:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;tcpdump &lt;span class="nt"&gt;-i&lt;/span&gt; any &lt;span class="nt"&gt;-s&lt;/span&gt; 0 &lt;span class="nt"&gt;-w&lt;/span&gt; /tmp/sip_trace.pcap &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'host sip.provider.com and port 5060'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run a test call, then stop the capture (Ctrl+C).&lt;/p&gt;

&lt;p&gt;Convert to readable format:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/sip_trace.pcap &lt;span class="nt"&gt;-Y&lt;/span&gt; sip &lt;span class="nt"&gt;-O&lt;/span&gt; sip &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/sip_trace.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Review the trace for the exact 403 response:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 5 &lt;span class="nt"&gt;-B&lt;/span&gt; 5 &lt;span class="s2"&gt;"403&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;Forbidden"&lt;/span&gt; /tmp/sip_trace.txt
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Asterisk Verbose Logging
&lt;/h3&gt;

&lt;p&gt;Enable Asterisk verbose mode to log SIP transactions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core set verbose 10"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This produces output in &lt;code&gt;/var/log/asterisk/messages&lt;/code&gt;. Monitor during test calls:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"INVITE|SIP/2.0 403|Trying|Calling"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Step 2: Validate Credentials Against Provider
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Verify Provider-Supplied Values
&lt;/h3&gt;

&lt;p&gt;Contact your SIP trunk provider and confirm:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Account Username&lt;/strong&gt;: Case-sensitive, no spaces&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Password/Secret&lt;/strong&gt;: Exactly as configured in their system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Outbound Proxy/Host&lt;/strong&gt;: SIP server address and port&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Your IP Address(es)&lt;/strong&gt;: Whitelisted on their system&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;DID/Extension&lt;/strong&gt;: Authorized for your account&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Authentication Method&lt;/strong&gt;: Digest, Basic, or IP-based&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Example request to provider:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"We're receiving 403 Forbidden errors from sip.provider.com when authenticating with username 'accountname'. Can you confirm: (1) the exact password configured for this account, (2) whether IP whitelisting is enabled, (3) what our outbound IP should be, (4) the correct SIP URI format for requests?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Test With SIPp (SIP Protocol Tester)
&lt;/h3&gt;

&lt;p&gt;Use the sipp tool to test authentication independently:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;apt-get &lt;span class="nb"&gt;install &lt;/span&gt;sipp
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Create a test scenario file &lt;code&gt;/tmp/test_sip.xml&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?xml version="1.0" encoding="ISO-8859-1" ?&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;scenario&lt;/span&gt; &lt;span class="na"&gt;name=&lt;/span&gt;&lt;span class="s"&gt;"Basic SIP UAC"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;send&lt;/span&gt; &lt;span class="na"&gt;retrans=&lt;/span&gt;&lt;span class="s"&gt;"500"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
    &lt;span class="cp"&gt;&amp;lt;![CDATA[
      INVITE sip:test@sip.provider.com SIP/2.0
      Via: SIP/2.0/[transport] [local_ip]:[local_port];branch=[branch]
      From: &amp;lt;sip:youraccountname@yourdomain.com&amp;gt;&lt;/span&gt;;tag=[call_number]
      To: &lt;span class="nt"&gt;&amp;lt;sip:test&lt;/span&gt;&lt;span class="err"&gt;@sip.provider.com&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Call-ID: [call_id]
      CSeq: 1 INVITE
      Contact: &lt;span class="nt"&gt;&amp;lt;sip:&lt;/span&gt;&lt;span class="err"&gt;[local_ip]:[local_port]&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
      Max-Forwards: 70
      User-Agent: Test SIPp
      Content-Length: 0
    ]]&amp;gt;
  &lt;span class="nt"&gt;&amp;lt;/send&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;recv&lt;/span&gt; &lt;span class="na"&gt;response=&lt;/span&gt;&lt;span class="s"&gt;"403"&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/scenario&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run the test:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sipp &lt;span class="nt"&gt;-sf&lt;/span&gt; /tmp/test_sip.xml &lt;span class="nt"&gt;-s&lt;/span&gt; sip.provider.com &lt;span class="nt"&gt;-p&lt;/span&gt; 5060 &lt;span class="nt"&gt;-ap&lt;/span&gt; youraccountname:yourpassword your_local_ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This tests basic SIP authentication without Asterisk complexity.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: Check Credential Configuration in ViciDial
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Review SIP Configuration File
&lt;/h3&gt;

&lt;p&gt;Open your trunk definition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-A&lt;/span&gt; 20 &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\[&lt;/span&gt;&lt;span class="s2"&gt;mytrunksip&lt;/span&gt;&lt;span class="se"&gt;\]&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; /etc/asterisk/sip-vicidial.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;username&lt;/span&gt;=&lt;span class="n"&gt;youraccountname&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;yourpassword&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Common mistakes:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Extra spaces around &lt;code&gt;=&lt;/code&gt; sign&lt;/li&gt;
&lt;li&gt;Trailing whitespace on password line&lt;/li&gt;
&lt;li&gt;Password contains special characters not properly escaped&lt;/li&gt;
&lt;li&gt;Wrong username or password copied from wrong provider account&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Verify From: Header Construction
&lt;/h3&gt;

&lt;p&gt;The From: header must match provider expectations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;youraccountname&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="n"&gt;sip&lt;/span&gt;.&lt;span class="n"&gt;provider&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This constructs: &lt;code&gt;From: "youraccountname" &amp;lt;sip:youraccountname@sip.provider.com&amp;gt;&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Provider may require:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Your assigned DID as fromuser&lt;/li&gt;
&lt;li&gt;Your domain instead of fromdomain&lt;/li&gt;
&lt;li&gt;A specific format like &lt;code&gt;+1234567890@yourdomain.com&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Check Extensions Dialplan
&lt;/h3&gt;

&lt;p&gt;Verify your trunk is invoked correctly in &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;XXXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;:&lt;span class="m"&gt;1&lt;/span&gt;}@&lt;span class="n"&gt;mytrunksip&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;XXXXXXXX&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The &lt;code&gt;@mytrunksip&lt;/code&gt; reference must match your peer definition exactly (case-sensitive).&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 4: Diagnose IP and Network Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Verify Outbound IP Address
&lt;/h3&gt;

&lt;p&gt;Your Asterisk server's outbound IP must match what the provider has whitelisted:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-s&lt;/span&gt; https://api.ipify.org
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or from within Asterisk:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show settings"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"Bindaddr"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare this IP against your provider's whitelist.&lt;/p&gt;

&lt;h3&gt;
  
  
  Test Network Connectivity
&lt;/h3&gt;

&lt;p&gt;Verify basic connectivity to the SIP server:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ping &lt;span class="nt"&gt;-c&lt;/span&gt; 3 sip.provider.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Test port-level connectivity:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc &lt;span class="nt"&gt;-zv&lt;/span&gt; sip.provider.com 5060
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Check if firewall rules permit SIP traffic:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;5060
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For proper SIP NAT traversal, ensure:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;mytrunksip&lt;/span&gt;]
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;force_rport&lt;/span&gt;,&lt;span class="n"&gt;comedia&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify DNS Resolution
&lt;/h3&gt;

&lt;p&gt;Confirm the provider's hostname resolves correctly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nslookup sip.provider.com
dig sip.provider.com @8.8.8.8
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;DNS issues can cause timeouts that look like authentication failures.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 5: Resolve Common 403 Scenarios
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Scenario A: Credential Mismatch
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: 403 response immediately upon sending INVITE.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Request fresh credentials from provider&lt;/li&gt;
&lt;li&gt;Update both &lt;code&gt;username&lt;/code&gt; and &lt;code&gt;secret&lt;/code&gt; fields:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;vi /etc/asterisk/sip-vicidial.conf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If password contains special characters, escape properly:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="s2"&gt;"pa$$w0rd@2024!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Reload SIP configuration:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Test a call and monitor logs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
&lt;span class="c"&gt;# Make test call&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug off"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario B: IP Whitelisting
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: 403 error after successful authentication attempts, only from specific network.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Confirm your public IP:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;wget &lt;span class="nt"&gt;-qO-&lt;/span&gt; https://checkip.amazonaws.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Contact provider to whitelist this IP&lt;/li&gt;
&lt;li&gt;If using failover/redundancy, whitelist all potential outbound IPs&lt;/li&gt;
&lt;li&gt;Test after provider confirms whitelist update:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip qualify mytrunksip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario C: Rate Limiting/Blacklisting
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: 403 after initial successful calls, becomes persistent.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Contact provider to check if your IP is temporarily blocked&lt;/li&gt;
&lt;li&gt;Check for malformed SIP requests in your logs:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"malformed&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;invalid&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;error"&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;Ensure no SIP scanning attacks from your server:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;netstat &lt;span class="nt"&gt;-tupan&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;5060
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;If provider has rate limits, implement call queuing in ViciDial dialplan to space out requests&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Scenario D: Account Suspension/Expiration
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: Abrupt 403 errors with no configuration changes.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log into provider's web portal&lt;/li&gt;
&lt;li&gt;Check account status, payment status, and service activation&lt;/li&gt;
&lt;li&gt;Verify DID/trunk subscription is current&lt;/li&gt;
&lt;li&gt;Request manual account re-activation&lt;/li&gt;
&lt;li&gt;Once confirmed active, reload SIP:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Scenario E: Inbound Route Mismatch
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;Symptom&lt;/strong&gt;: 403 only occurs on inbound calls; outbound works fine.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Resolution&lt;/strong&gt;:&lt;/p&gt;

&lt;p&gt;Inbound calls use different SIP URI matching. Check your inbound context in &lt;code&gt;/etc/asterisk/extensions-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;trunk&lt;/span&gt;]
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;5551234567&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Verbose&lt;/span&gt;(&lt;span class="s2"&gt;"Inbound from ${CALLERID(num)}"&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;5551234567&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;Local&lt;/span&gt;/&lt;span class="m"&gt;5551234567&lt;/span&gt;@&lt;span class="n"&gt;default&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="m"&gt;5551234567&lt;/span&gt;,&lt;span class="n"&gt;n&lt;/span&gt;,&lt;span class="n"&gt;Hangup&lt;/span&gt;()
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ensure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;The inbound DID is exactly what the provider sends (with or without +1 prefix)&lt;/li&gt;
&lt;li&gt;The extension is properly defined in the context&lt;/li&gt;
&lt;li&gt;No invalid characters in the DID&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Step 6: Test the Fix
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Manual SIP Test Call
&lt;/h3&gt;

&lt;p&gt;Use Asterisk's dial command directly:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"channel originate SIP/5551234567@mytrunksip Application VoiceMAil"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Monitor the response in real-time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"INVITE|403|200 OK|Call"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A successful INVITE shows &lt;code&gt;200 OK&lt;/code&gt; response.&lt;/p&gt;

&lt;h3&gt;
  
  
  Agent Test Call from ViciDial
&lt;/h3&gt;

&lt;p&gt;Log into the ViciDial agent screen at &lt;code&gt;/agc/vicidial.php&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Log in with test agent account&lt;/li&gt;
&lt;li&gt;Select a campaign with your fixed trunk&lt;/li&gt;
&lt;li&gt;Dial a test number (external cell phone or test service)&lt;/li&gt;
&lt;li&gt;Monitor the call completion&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Check call logs in the database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;call_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;caller_id_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;dialed_number&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_status&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; 
       &lt;span class="n"&gt;length_in_sec&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_log&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;dialed_number&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'5551234567'&lt;/span&gt; 
&lt;span class="k"&gt;ORDER&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;call_date&lt;/span&gt; &lt;span class="k"&gt;DESC&lt;/span&gt; &lt;span class="k"&gt;LIMIT&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for &lt;code&gt;call_status = 'COMPLETE'&lt;/code&gt; or similar success indicators.&lt;/p&gt;

&lt;h3&gt;
  
  
  Verify SIP Qualify Status
&lt;/h3&gt;

&lt;p&gt;Check if the trunk qualifies (can reach the provider):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;mytrunksip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output should show:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mytrunksip/sip.provider.com    sip.provider.com:5060         OK
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If showing &lt;code&gt;UNREACHABLE&lt;/code&gt;, the trunk cannot reach the provider at all. This may indicate network issues or wrong host address.&lt;/p&gt;

&lt;h2&gt;
  
  
  Advanced Troubleshooting
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Parse Raw SIP Headers
&lt;/h3&gt;

&lt;p&gt;If you have a tcpdump capture, extract the exact failing INVITE:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo &lt;/span&gt;tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/sip_trace.pcap &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"sip.Request.Method == INVITE"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; sip.From &lt;span class="nt"&gt;-e&lt;/span&gt; sip.To &lt;span class="nt"&gt;-e&lt;/span&gt; sip.Contact &lt;span class="nt"&gt;-e&lt;/span&gt; sip.User-Agent
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare the From:/To:/Contact: headers against provider requirements.&lt;/p&gt;

&lt;h3&gt;
  
  
  Check Asterisk SIP Registry
&lt;/h3&gt;

&lt;p&gt;If your trunk uses outbound registration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show registry"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output shows registration status. &lt;code&gt;Registered&lt;/code&gt; means the trunk successfully authenticated with the provider for inbound calls.&lt;/p&gt;

&lt;p&gt;If &lt;code&gt;Request Sent&lt;/code&gt; or &lt;code&gt;Unregistered&lt;/code&gt;, the trunk cannot register:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip register mytrunksip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Review Authentication Digest Headers
&lt;/h3&gt;

&lt;p&gt;In tcpdump analysis, look for the response to your INVITE. If it's a 407 (Proxy Authentication Required) followed by your 403 response, your credentials are wrong.&lt;/p&gt;

&lt;p&gt;The sequence should be:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;INVITE (no auth) → 407 Proxy Auth Required&lt;/li&gt;
&lt;li&gt;ACK&lt;/li&gt;
&lt;li&gt;INVITE (with Authorization header) → 200 OK or 180 Ringing&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;If the second INVITE still returns 403, credentials are incorrect.&lt;/p&gt;

&lt;p&gt;Extract the Authorization header from tcpdump:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;tshark &lt;span class="nt"&gt;-r&lt;/span&gt; /tmp/sip_trace.pcap &lt;span class="nt"&gt;-Y&lt;/span&gt; &lt;span class="s2"&gt;"sip"&lt;/span&gt; &lt;span class="nt"&gt;-T&lt;/span&gt; fields &lt;span class="nt"&gt;-e&lt;/span&gt; sip.Authorization
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Compare the username in the Authorization header against your configured username.&lt;/p&gt;

&lt;h2&gt;
  
  
  Preventive Measures and Monitoring
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Monitor for 403 Errors Proactively
&lt;/h3&gt;

&lt;p&gt;Create a monitoring script in &lt;code&gt;/usr/local/bin/check_sip_403.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;

&lt;span class="nv"&gt;LOG_FILE&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/var/log/asterisk/messages"&lt;/span&gt;
&lt;span class="nv"&gt;THRESHOLD&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5

&lt;span class="c"&gt;# Count 403 errors in last hour&lt;/span&gt;
&lt;span class="nv"&gt;COUNT&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="s2"&gt;"SIP/2.0 403"&lt;/span&gt; &lt;span class="nv"&gt;$LOG_FILE&lt;/span&gt; | &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="nt"&gt;-v&lt;/span&gt; &lt;span class="nv"&gt;d&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;date&lt;/span&gt; &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'1 hour ago'&lt;/span&gt; &lt;span class="s1"&gt;'+%b %d %H'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="s1"&gt;'$0 ~ d'&lt;/span&gt; | &lt;span class="nb"&gt;wc&lt;/span&gt; &lt;span class="nt"&gt;-l&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[&lt;/span&gt; &lt;span class="nv"&gt;$COUNT&lt;/span&gt; &lt;span class="nt"&gt;-gt&lt;/span&gt; &lt;span class="nv"&gt;$THRESHOLD&lt;/span&gt; &lt;span class="o"&gt;]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
  &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"ALERT: &lt;/span&gt;&lt;span class="nv"&gt;$COUNT&lt;/span&gt;&lt;span class="s2"&gt; SIP 403 errors detected in last hour"&lt;/span&gt;
  &lt;span class="c"&gt;# Send email, page, etc.&lt;/span&gt;
  &lt;span class="c"&gt;# mail -s "ViciDial SIP 403 Alert" admin@example.com&lt;/span&gt;
  &lt;span class="nb"&gt;exit &lt;/span&gt;1
&lt;span class="k"&gt;fi

&lt;/span&gt;&lt;span class="nb"&gt;exit &lt;/span&gt;0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make executable and add to crontab:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nb"&gt;sudo chmod&lt;/span&gt; +x /usr/local/bin/check_sip_403.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="k"&gt;*&lt;/span&gt;/5 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/local/bin/check_sip_403.sh
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Document Trunk Configuration
&lt;/h3&gt;

&lt;p&gt;Maintain a reference document with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight properties"&gt;&lt;code&gt;&lt;span class="err"&gt;Trunk&lt;/span&gt; &lt;span class="py"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;mytrunksip&lt;/span&gt;
&lt;span class="py"&gt;Provider&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;Provider Name&lt;/span&gt;
&lt;span class="py"&gt;Host&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sip.provider.com:5060&lt;/span&gt;
&lt;span class="py"&gt;Username&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;accountname (NOT case-sensitive at provider)&lt;/span&gt;
&lt;span class="py"&gt;Password&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;(hash, not plaintext) - updated DATE&lt;/span&gt;
&lt;span class="err"&gt;From&lt;/span&gt; &lt;span class="py"&gt;Domain&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;sip.provider.com&lt;/span&gt;
&lt;span class="err"&gt;Outbound&lt;/span&gt; &lt;span class="py"&gt;IPs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;203.0.113.45&lt;/span&gt;
&lt;span class="err"&gt;Inbound&lt;/span&gt; &lt;span class="py"&gt;DIDs&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;555-123-4567, 555-123-4568&lt;/span&gt;
&lt;span class="err"&gt;Support&lt;/span&gt; &lt;span class="py"&gt;Contact&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;+1-555-0000&lt;/span&gt;
&lt;span class="err"&gt;Rate&lt;/span&gt; &lt;span class="py"&gt;Limits&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;100 CPS&lt;/span&gt;
&lt;span class="err"&gt;Last&lt;/span&gt; &lt;span class="py"&gt;Verified&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;DATE&lt;/span&gt;
&lt;span class="err"&gt;Known&lt;/span&gt; &lt;span class="py"&gt;Issues&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;None&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Implement Health Checks
&lt;/h3&gt;

&lt;p&gt;Add to your monitoring system (Nagios, Zabbix, etc.):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;check_sip_qualify&lt;span class="o"&gt;()&lt;/span&gt; &lt;span class="o"&gt;{&lt;/span&gt;
  &lt;span class="nb"&gt;local &lt;/span&gt;&lt;span class="nv"&gt;trunk&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$1&lt;/span&gt;
  asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-q&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$trunk&lt;/span&gt;&lt;span class="s2"&gt;.*OK"&lt;/span&gt;
&lt;span class="o"&gt;}&lt;/span&gt;

check_sip_qualify mytrunksip &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"OK"&lt;/span&gt; &lt;span class="o"&gt;||&lt;/span&gt; &lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"CRITICAL"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Log Rotation Configuration
&lt;/h3&gt;

&lt;p&gt;Ensure Asterisk logs don't fill disk, which can mask 403 errors. Check &lt;code&gt;/etc/logrotate.d/asterisk&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;/&lt;span class="n"&gt;var&lt;/span&gt;/&lt;span class="n"&gt;log&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt;/&lt;span class="n"&gt;messages&lt;/span&gt; {
    &lt;span class="n"&gt;daily&lt;/span&gt;
    &lt;span class="n"&gt;missingok&lt;/span&gt;
    &lt;span class="n"&gt;rotate&lt;/span&gt; &lt;span class="m"&gt;7&lt;/span&gt;
    &lt;span class="n"&gt;compress&lt;/span&gt;
    &lt;span class="n"&gt;delaycompress&lt;/span&gt;
    &lt;span class="n"&gt;notifempty&lt;/span&gt;
    &lt;span class="n"&gt;create&lt;/span&gt; &lt;span class="m"&gt;0640&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt; &lt;span class="n"&gt;asterisk&lt;/span&gt;
    &lt;span class="n"&gt;postrotate&lt;/span&gt;
        /&lt;span class="n"&gt;usr&lt;/span&gt;/&lt;span class="n"&gt;sbin&lt;/span&gt;/&lt;span class="n"&gt;asterisk&lt;/span&gt; -&lt;span class="n"&gt;rx&lt;/span&gt; &lt;span class="s2"&gt;"logger rotate"&lt;/span&gt; &amp;gt; /&lt;span class="n"&gt;dev&lt;/span&gt;/&lt;span class="n"&gt;null&lt;/span&gt; &lt;span class="m"&gt;2&lt;/span&gt;&amp;gt;&amp;amp;&lt;span class="m"&gt;1&lt;/span&gt; || &lt;span class="n"&gt;true&lt;/span&gt;
    &lt;span class="n"&gt;endscript&lt;/span&gt;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Troubleshooting Decision Tree
&lt;/h2&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Is the trunk showing in "sip show peers"?
├─ NO → Check sip-vicidial.conf syntax and reload
├─ YES → Does "sip show registry" show it registered?
    ├─ NO (401 or 407) → Credentials are wrong
    ├─ YES → Are you seeing 403 on INVITE only?
        ├─ YES → IP whitelist or rate limit issue
        └─ NO → Check From: header format
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Common ViciDial-Specific Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Issue: Multiple Trunks, One Returns 403
&lt;/h3&gt;

&lt;p&gt;ViciDial may route calls through the wrong trunk. Check &lt;code&gt;extensions-vicidial.conf&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;9&lt;/span&gt;&lt;span class="n"&gt;XXXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;:&lt;span class="m"&gt;1&lt;/span&gt;}@&lt;span class="n"&gt;mytrunksip&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this extension pattern is ambiguous, other patterns might match first. Use more specific patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;91&lt;/span&gt;&lt;span class="n"&gt;NXXXXXX&lt;/span&gt;,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;:&lt;span class="m"&gt;1&lt;/span&gt;}@&lt;span class="n"&gt;mytrunksip&lt;/span&gt;)
&lt;span class="n"&gt;exten&lt;/span&gt; =&amp;gt; &lt;span class="err"&gt;_&lt;/span&gt;&lt;span class="m"&gt;9011&lt;/span&gt;.,&lt;span class="m"&gt;1&lt;/span&gt;,&lt;span class="n"&gt;Dial&lt;/span&gt;(&lt;span class="n"&gt;SIP&lt;/span&gt;/${&lt;span class="n"&gt;EXTEN&lt;/span&gt;:&lt;span class="m"&gt;1&lt;/span&gt;}@&lt;span class="n"&gt;intl_trunk&lt;/span&gt;)
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Issue: Campaign Trunk Assignment
&lt;/h3&gt;

&lt;p&gt;In ViciDial, verify campaign uses the correct trunk in database:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;campaign_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;vtiger_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaigns&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TESTCAMP'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;trunk_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_campaign_carriers&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;campaign_id&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'TESTCAMP'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wrong trunk assignment will route calls through a trunk with bad credentials.&lt;/p&gt;

&lt;h3&gt;
  
  
  Issue: Lead Filtering by Trunk
&lt;/h3&gt;

&lt;p&gt;Check if leads are filtered to specific trunks in &lt;code&gt;vicidial_list&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;SELECT&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;FROM&lt;/span&gt; &lt;span class="n"&gt;vicidial_list&lt;/span&gt; 
&lt;span class="k"&gt;WHERE&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt; &lt;span class="k"&gt;IS&lt;/span&gt; &lt;span class="k"&gt;NOT&lt;/span&gt; &lt;span class="k"&gt;NULL&lt;/span&gt; 
&lt;span class="k"&gt;GROUP&lt;/span&gt; &lt;span class="k"&gt;BY&lt;/span&gt; &lt;span class="n"&gt;list_id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;carrier_id&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a list requires a specific trunk with 403 errors, leads cannot be called.&lt;/p&gt;

&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;SIP 403 Forbidden errors in ViciDial require systematic diagnosis:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Enable debugging&lt;/strong&gt; to see the actual error in context&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Validate credentials&lt;/strong&gt; match provider configuration exactly&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Verify networking&lt;/strong&gt; allows packets to reach the provider&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check IP whitelisting&lt;/strong&gt; with your provider&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test independently&lt;/strong&gt; using sipp before restarting Asterisk&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor proactively&lt;/strong&gt; with log analysis and SIP qualify checks&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Document everything&lt;/strong&gt; for future troubleshooting&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The most common causes are wrong credentials, IP whitelisting issues, and provider account problems. Always contact your SIP provider with specific details:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"SIP 403 Forbidden error from [your outbound IP] to [their SIP host] with username [username] at [specific time]. Can you check authentication logs?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Keep Asterisk SIP logging enabled in production (&lt;code&gt;sip set debug on&lt;/code&gt; in verbosity levels), rotate logs regularly, and set up alerts for repeated 403 errors. This prevents lost calls and identifies problems before they impact your operation.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
    <item>
      <title>Asterisk 'Peer Is Not Registered' — SIP Registration Failure Debug</title>
      <dc:creator>Moisi Trungu</dc:creator>
      <pubDate>Wed, 05 Aug 2026 03:30:03 +0000</pubDate>
      <link>https://dev.to/moisi_trungu_31647b7ac300/asterisk-peer-is-not-registered-sip-registration-failure-debug-6o5</link>
      <guid>https://dev.to/moisi_trungu_31647b7ac300/asterisk-peer-is-not-registered-sip-registration-failure-debug-6o5</guid>
      <description>&lt;h1&gt;
  
  
  Asterisk 'Peer Is Not Registered' — SIP Registration Failure Debug
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;Master the diagnosis and resolution of SIP registration failures in Asterisk/ViciDial production environments by understanding peer registration mechanics, common misconfiguration patterns, and step-by-step troubleshooting methodology.&lt;/strong&gt;&lt;/p&gt;




&lt;h2&gt;
  
  
  Prerequisites
&lt;/h2&gt;

&lt;p&gt;Before you begin this guide, ensure you have:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Asterisk 1.6+, 11.x, 13.x, or 16.x (ViciDial typically runs 11.x or 13.x)&lt;/li&gt;
&lt;li&gt;Root or sudo access to the Asterisk server&lt;/li&gt;
&lt;li&gt;Knowledge of basic SIP concepts (registrar, registrant, peer, friend)&lt;/li&gt;
&lt;li&gt;Access to &lt;code&gt;/etc/asterisk/&lt;/code&gt; configuration directory&lt;/li&gt;
&lt;li&gt;Ability to tail logs in real-time: &lt;code&gt;tail -f /var/log/asterisk/messages&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Familiarity with &lt;code&gt;asterisk -rx&lt;/code&gt; CLI commands&lt;/li&gt;
&lt;li&gt;Understanding of your network topology (NAT, firewall, carrier routing)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  Understanding SIP Registration in Asterisk
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How Asterisk Registration Works
&lt;/h3&gt;

&lt;p&gt;When Asterisk is configured as a SIP registrant (client), it sends a &lt;strong&gt;SIP REGISTER&lt;/strong&gt; request to a remote SIP server (registrar). The registrar acknowledges and stores the binding. Asterisk then periodically re-registers to maintain the binding.&lt;/p&gt;

&lt;p&gt;When an external peer attempts to register &lt;strong&gt;to&lt;/strong&gt; Asterisk (Asterisk acting as registrar), Asterisk receives the REGISTER request, validates credentials, and stores the peer location in memory.&lt;/p&gt;

&lt;p&gt;The error &lt;strong&gt;"Peer is not registered"&lt;/strong&gt; occurs when:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Asterisk &lt;strong&gt;expects&lt;/strong&gt; a peer to have registered but hasn't&lt;/li&gt;
&lt;li&gt;The peer's registration has expired&lt;/li&gt;
&lt;li&gt;The peer never completed registration&lt;/li&gt;
&lt;li&gt;The peer is configured incorrectly&lt;/li&gt;
&lt;li&gt;Network/firewall blocks SIP traffic&lt;/li&gt;
&lt;li&gt;DNS resolution fails&lt;/li&gt;
&lt;/ol&gt;

&lt;h3&gt;
  
  
  Registration State Lifecycle
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Peer Configured (type=friend or type=peer)
    ↓
SIP REGISTER Request Sent (or expected)
    ↓
401 Unauthorized / 200 OK Response
    ↓
Credentials Validated / Failed
    ↓
Binding Stored in Memory / Rejected
    ↓
Re-registration Timer Starts (default: 3600s)
    ↓
Expiration / Renewal Cycle
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Configuration Fundamentals
&lt;/h2&gt;

&lt;h3&gt;
  
  
  SIP Peer vs. Friend vs. User Types
&lt;/h3&gt;

&lt;p&gt;ViciDial typically uses SIP configuration in &lt;code&gt;/etc/asterisk/sip-vicidial.conf&lt;/code&gt;. Understanding peer types is critical:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;internal&lt;/span&gt;
&lt;span class="n"&gt;recordhistory&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;bindport&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;bindaddr&lt;/span&gt;=&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;srvlookup&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;transport&lt;/span&gt;=&lt;span class="n"&gt;udp&lt;/span&gt;,&lt;span class="n"&gt;tcp&lt;/span&gt;
&lt;span class="n"&gt;allowguest&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;

&lt;span class="c"&gt;# TYPE 1: PEER (one-way trust, inbound calls only)
&lt;/span&gt;[&lt;span class="n"&gt;carrier_sip&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;peer&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;45&lt;/span&gt;
&lt;span class="n"&gt;port&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;pstn&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;,&lt;span class="n"&gt;alaw&lt;/span&gt;
&lt;span class="n"&gt;fromuser&lt;/span&gt;=&lt;span class="n"&gt;vicidial_account&lt;/span&gt;
&lt;span class="n"&gt;fromdomain&lt;/span&gt;=&lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;45&lt;/span&gt;

&lt;span class="c"&gt;# TYPE 2: USER (deprecated in modern Asterisk, avoid)
&lt;/span&gt;[&lt;span class="n"&gt;user_extension&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;user&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="n"&gt;dynamic&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;internal&lt;/span&gt;

&lt;span class="c"&gt;# TYPE 3: FRIEND (peer + user, two-way trust)
&lt;/span&gt;[&lt;span class="n"&gt;agent_extension&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;host&lt;/span&gt;=&lt;span class="n"&gt;dynamic&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;internal&lt;/span&gt;
&lt;span class="n"&gt;defaultuser&lt;/span&gt;=&lt;span class="m"&gt;1001&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;MySecurePassword123&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;,&lt;span class="n"&gt;alaw&lt;/span&gt;
&lt;span class="n"&gt;mailbox&lt;/span&gt;=&lt;span class="m"&gt;1001&lt;/span&gt;@&lt;span class="n"&gt;default&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;120&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 1: Verify Configuration Syntax
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Check SIP Configuration for Errors
&lt;/h3&gt;

&lt;p&gt;Invalid syntax prevents Asterisk from loading the peer entirely.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-20&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Name/username             Host                                    Dyn Forcerport ACL Port     Status      
agent_1001               192.168.1.100                            D   No         A  5060     OK (19 ms)
carrier_sip              203.0.113.45                             N   Yes        A  5060     UNREACHABLE
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a peer is missing from this list entirely, it failed to parse.&lt;/p&gt;

&lt;h3&gt;
  
  
  Reload and Check for Parse Errors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt; 2&amp;gt;&amp;amp;1 | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"error&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;warning&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;parse"&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"sip&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;error"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Look for lines like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;[2024-01-15 14:32:18] WARNING[12345]: chan_sip.c:30123 in parse_register_line(): Line 145: Bad syntax
[2024-01-15 14:32:18] ERROR[12345]: config.c:4567 in config_text_file_load(): Can't load config file "sip-vicidial.conf"
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Common Configuration Syntax Errors
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="c"&gt;# WRONG: Missing equals sign
&lt;/span&gt;[&lt;span class="n"&gt;agent_1001&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;password&lt;/span&gt;

&lt;span class="c"&gt;# WRONG: Invalid values
&lt;/span&gt;[&lt;span class="n"&gt;agent_1001&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;invalid_type&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;maybe&lt;/span&gt;

&lt;span class="c"&gt;# WRONG: Commented out required field
&lt;/span&gt;[&lt;span class="n"&gt;agent_1001&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
;&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;password&lt;/span&gt;

&lt;span class="c"&gt;# CORRECT:
&lt;/span&gt;[&lt;span class="n"&gt;agent_1001&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;password&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 2: Confirm Peer is Loaded and Present
&lt;/h2&gt;

&lt;h3&gt;
  
  
  List All Registered and Unregistered Peers
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Parse the output methodically:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Dyn = Y/D&lt;/strong&gt;: Peer expects dynamic (changing) host IP&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Host = actual IP or hostname&lt;/strong&gt;: Current known location&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Port&lt;/strong&gt;: SIP port (default 5060)&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Status&lt;/strong&gt;: 

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;OK (X ms)&lt;/code&gt; = responsive&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UNREACHABLE&lt;/code&gt; = can't reach this peer&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;UNKNOWN&lt;/code&gt; = hasn't registered yet&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Unmonitored&lt;/code&gt; = qualify=no&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;h3&gt;
  
  
  Check Specific Peer Registration Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peer agent_1001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output example (peer IS registered):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;  &lt;span class="err"&gt;Name&lt;/span&gt;       &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;agent_1001&lt;/span&gt;
  &lt;span class="err"&gt;Secret&lt;/span&gt;     &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;Set&amp;gt;&lt;/span&gt;
  &lt;span class="err"&gt;MD5Secret&lt;/span&gt;  &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;Not&lt;/span&gt; &lt;span class="err"&gt;set&amp;gt;&lt;/span&gt;
  &lt;span class="err"&gt;Context&lt;/span&gt;    &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;from-internal&lt;/span&gt;
  &lt;span class="err"&gt;Language&lt;/span&gt;   &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;en&lt;/span&gt;
  &lt;span class="err"&gt;AMA&lt;/span&gt; &lt;span class="err"&gt;flags&lt;/span&gt;  &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;Unknown&lt;/span&gt;
  &lt;span class="err"&gt;Transfer&lt;/span&gt; &lt;span class="err"&gt;mode&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;open&lt;/span&gt;
  &lt;span class="err"&gt;Dtmfmode&lt;/span&gt;   &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;rfc2833&lt;/span&gt;
  &lt;span class="err"&gt;Tohost&lt;/span&gt;     &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;192.168.1.100&lt;/span&gt;
  &lt;span class="err"&gt;Addr-&amp;gt;IP&lt;/span&gt;   &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;192.168.1.100&lt;/span&gt;
  &lt;span class="err"&gt;Defname&lt;/span&gt;    &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;agent_1001&lt;/span&gt;
  &lt;span class="err"&gt;Useragent&lt;/span&gt;  &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;Zoiper&lt;/span&gt; &lt;span class="err"&gt;2.52&lt;/span&gt; &lt;span class="err"&gt;(VoIP&lt;/span&gt; &lt;span class="err"&gt;Client)&lt;/span&gt;
  &lt;span class="err"&gt;Reg.&lt;/span&gt; &lt;span class="err"&gt;Contact:&lt;/span&gt; &lt;span class="err"&gt;sip:agent_1001@192.168.1.100:5060&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output example (peer NOT registered):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;  &lt;span class="err"&gt;Name&lt;/span&gt;       &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;agent_1002&lt;/span&gt;
  &lt;span class="err"&gt;Secret&lt;/span&gt;     &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;Set&amp;gt;&lt;/span&gt;
  &lt;span class="err"&gt;Context&lt;/span&gt;    &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;from-internal&lt;/span&gt;
  &lt;span class="err"&gt;Host&lt;/span&gt;       &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;dynamic&lt;/span&gt;
  &lt;span class="err"&gt;Addr-&amp;gt;IP&lt;/span&gt;   &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;(null)&lt;/span&gt;
  &lt;span class="err"&gt;Defname&lt;/span&gt;    &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;agent_1002&lt;/span&gt;
  &lt;span class="err"&gt;Useragent&lt;/span&gt;  &lt;span class="err"&gt;:&lt;/span&gt; 
  &lt;span class="err"&gt;Reg.&lt;/span&gt; &lt;span class="err"&gt;Contact:&lt;/span&gt; &lt;span class="err"&gt;&amp;lt;Not&lt;/span&gt; &lt;span class="err"&gt;set&amp;gt;&lt;/span&gt;
  &lt;span class="err"&gt;Status&lt;/span&gt;     &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;UNKNOWN&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Key indicator&lt;/strong&gt;: If &lt;code&gt;Addr-&amp;gt;IP : (null)&lt;/code&gt; and &lt;code&gt;Reg. Contact: &amp;lt;Not set&amp;gt;&lt;/code&gt;, the peer has never registered.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 3: Check Network Connectivity and Firewall
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Verify UDP/TCP Port 5060 is Open
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check if Asterisk is listening&lt;/span&gt;
netstat &lt;span class="nt"&gt;-tulpn&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;asterisk | &lt;span class="nb"&gt;grep &lt;/span&gt;5060
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Expected output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight console"&gt;&lt;code&gt;&lt;span class="go"&gt;udp        0      0 0.0.0.0:5060            0.0.0.0:*                           12345/asterisk
tcp        0      0 0.0.0.0:5060            0.0.0.0:*                           12345/asterisk
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test Firewall from Client
&lt;/h3&gt;

&lt;p&gt;From the SIP client machine:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nc &lt;span class="nt"&gt;-u&lt;/span&gt; &lt;span class="nt"&gt;-zv&lt;/span&gt; &amp;lt;asterisk-server-ip&amp;gt; 5060
nc &lt;span class="nt"&gt;-zv&lt;/span&gt; &amp;lt;asterisk-server-ip&amp;gt; 5060
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If both fail, firewall is blocking. Check iptables (or firewalld):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# Check iptables rules&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;5060

&lt;span class="c"&gt;# If nothing, add rule (CentOS/RHEL with firewalld):&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--permanent&lt;/span&gt; &lt;span class="nt"&gt;--add-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5060/udp
&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--permanent&lt;/span&gt; &lt;span class="nt"&gt;--add-port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;5060/tcp
&lt;span class="nb"&gt;sudo &lt;/span&gt;firewall-cmd &lt;span class="nt"&gt;--reload&lt;/span&gt;

&lt;span class="c"&gt;# Or with iptables directly:&lt;/span&gt;
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; udp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5060 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-I&lt;/span&gt; INPUT &lt;span class="nt"&gt;-p&lt;/span&gt; tcp &lt;span class="nt"&gt;--dport&lt;/span&gt; 5060 &lt;span class="nt"&gt;-j&lt;/span&gt; ACCEPT
&lt;span class="nb"&gt;sudo &lt;/span&gt;service iptables save
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Test DNS Resolution
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;nslookup asterisk.example.com
dig asterisk.example.com
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If the client uses a hostname to register and DNS fails, registration fails silently.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 4: Enable SIP Debugging and Capture Registration Attempts
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Enable Verbose SIP Debugging
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"register&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;sip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or capture to a separate file:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on peer agent_1001"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real-World Debug Output: Successful Registration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;&amp;lt;--- SIP read from UDP:192.168.1.100:52341 ---&amp;gt;
REGISTER sip:asterisk.local SIP/2.0
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
From: &amp;lt;sip:agent_1001@asterisk.local&amp;gt;;tag=1928301774
To: &amp;lt;sip:agent_1001@asterisk.local&amp;gt;
Call-ID: a84b4c76e66710@192.168.1.100
CSeq: 314159 REGISTER
Contact: &amp;lt;sip:agent_1001@192.168.1.100:5060&amp;gt;
Expires: 3600
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Asterisk responds:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;----- Transmitting SIP response to UDP:192.168.1.100:52341 -----
SIP/2.0 200 OK
Via: SIP/2.0/UDP 192.168.1.100:5060;branch=z9hG4bK776asdhds
From: &amp;lt;sip:agent_1001@asterisk.local&amp;gt;;tag=1928301774
To: &amp;lt;sip:agent_1001@asterisk.local&amp;gt;;tag=as52a3c4a9
Call-ID: a84b4c76e66710@192.168.1.100
CSeq: 314159 REGISTER
Contact: &amp;lt;sip:agent_1001@192.168.1.100:5060&amp;gt;;expires=3600
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Real-World Debug Output: Failed Registration (No Credentials)
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight http"&gt;&lt;code&gt;&lt;span class="err"&gt;&amp;lt;--- SIP read from UDP:192.168.1.100:52341 ---&amp;gt;
REGISTER sip:asterisk.local SIP/2.0
...
Contact: &amp;lt;sip:agent_1002@192.168.1.100:5060&amp;gt;
...

[Asterisk checks credentials against sip-vicidial.conf]

----- Transmitting SIP response to UDP:192.168.1.100:52341 -----
SIP/2.0 401 Unauthorized
...
WWW-Authenticate: Digest realm="asterisk.local", nonce="..."
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Client should re-send REGISTER with Authorization header.&lt;/p&gt;

&lt;h3&gt;
  
  
  Disable Debug When Done
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug off"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 5: Check ViciDial Database Configuration
&lt;/h2&gt;

&lt;p&gt;ViciDial stores extensions and phone registrations in MySQL. Verify the extension is enabled.&lt;/p&gt;

&lt;h3&gt;
  
  
  Query ViciDial Extensions
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; vicidial &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT extension, voicemail_id, full_name, status
FROM vicidial_extensions
WHERE extension='1001';"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;+-----------+---------------+-----------+--------+
| extension | voicemail_id  | full_name | status |
+-----------+---------------+-----------+--------+
| 1001      | 1001          | John Doe  | ACTIVE |
+-----------+---------------+-----------+--------+
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Critical&lt;/strong&gt;: If status is not &lt;code&gt;ACTIVE&lt;/code&gt;, the extension is disabled. Check &lt;code&gt;vicidial_users&lt;/code&gt; too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; vicidial &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT user, full_name, status, phone_login_pin
FROM vicidial_users
WHERE user='1001';"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify SIP Registration in Database
&lt;/h3&gt;

&lt;p&gt;Check if the peer appears in the registration tracking table:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; vicidial &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT * FROM vicidial_sip_registration
WHERE extension='1001'&lt;/span&gt;&lt;span class="se"&gt;\G&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If empty, check the log table for failed attempts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;mysql &lt;span class="nt"&gt;-u&lt;/span&gt; vicidial &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT event_date, extension, description
FROM vicidial_log
WHERE extension='1001' AND description LIKE '%register%'
ORDER BY event_date DESC LIMIT 10;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 6: Verify Credentials Match
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Common Credential Mismatches
&lt;/h3&gt;

&lt;p&gt;The most frequent cause of registration failure is mismatched credentials.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;In sip-vicidial.conf:&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;agent_1001&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;defaultuser&lt;/span&gt;=&lt;span class="n"&gt;agent_1001&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;MySecurePassword123&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;Expected client configuration:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username: &lt;code&gt;agent_1001&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Password: &lt;code&gt;MySecurePassword123&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Registrar: &lt;code&gt;asterisk.local&lt;/code&gt; or IP&lt;/li&gt;
&lt;li&gt;Port: &lt;code&gt;5060&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;If client uses:&lt;/strong&gt;&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Username: &lt;code&gt;1001&lt;/code&gt; (without prefix)&lt;/li&gt;
&lt;li&gt;Password: &lt;code&gt;MySecurePassword1234&lt;/code&gt; (typo)&lt;/li&gt;
&lt;li&gt;Port: &lt;code&gt;5061&lt;/code&gt; (wrong port)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;→ Registration fails silently or returns 401.&lt;/p&gt;

&lt;h3&gt;
  
  
  Force Credential Check
&lt;/h3&gt;

&lt;p&gt;Temporarily enable authentication debugging:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core set debug 5"&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"auth&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;credential"&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core set debug 0"&lt;/span&gt;  &lt;span class="c"&gt;# Disable when done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 7: Check Expiration and Re-Registration Timers
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Verify Peer Expiration Settings
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show peer agent_1001"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"expire&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;refresh"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Output:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ini"&gt;&lt;code&gt;  &lt;span class="err"&gt;Expire&lt;/span&gt;        &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;3600&lt;/span&gt; &lt;span class="err"&gt;(sec)&lt;/span&gt;
  &lt;span class="err"&gt;Refresh&lt;/span&gt; &lt;span class="err"&gt;Timer&lt;/span&gt; &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;1800&lt;/span&gt; &lt;span class="err"&gt;(sec)&lt;/span&gt;
  &lt;span class="err"&gt;Reg.&lt;/span&gt; &lt;span class="err"&gt;Contact&lt;/span&gt;  &lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="err"&gt;sip:agent_1001@192.168.1.100:5060&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a peer registered hours ago but hasn't re-registered, the binding expires and "Peer is Not Registered" errors occur.&lt;/p&gt;

&lt;h3&gt;
  
  
  Set Shorter Re-registration Intervals in sip-vicidial.conf
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;agent_1001&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;password&lt;/span&gt;
&lt;span class="n"&gt;defaultuser&lt;/span&gt;=&lt;span class="n"&gt;agent_1001&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;internal&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;          ; &lt;span class="n"&gt;Keep&lt;/span&gt;-&lt;span class="n"&gt;alive&lt;/span&gt; &lt;span class="n"&gt;check&lt;/span&gt; &lt;span class="n"&gt;every&lt;/span&gt; &lt;span class="m"&gt;60&lt;/span&gt; &lt;span class="n"&gt;seconds&lt;/span&gt;
&lt;span class="n"&gt;defaultexpire&lt;/span&gt;=&lt;span class="m"&gt;3600&lt;/span&gt;      ; &lt;span class="n"&gt;Registration&lt;/span&gt; &lt;span class="n"&gt;validity&lt;/span&gt;: &lt;span class="m"&gt;1&lt;/span&gt; &lt;span class="n"&gt;hour&lt;/span&gt;
&lt;span class="n"&gt;minexpire&lt;/span&gt;=&lt;span class="m"&gt;120&lt;/span&gt;           ; &lt;span class="n"&gt;Minimum&lt;/span&gt; &lt;span class="n"&gt;allowed&lt;/span&gt; &lt;span class="n"&gt;expiration&lt;/span&gt;
&lt;span class="n"&gt;maxexpire&lt;/span&gt;=&lt;span class="m"&gt;7200&lt;/span&gt;          ; &lt;span class="n"&gt;Maximum&lt;/span&gt; &lt;span class="n"&gt;allowed&lt;/span&gt; &lt;span class="n"&gt;expiration&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Reload:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitor Live Registration Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;watch &lt;span class="nt"&gt;-n&lt;/span&gt; 1 &lt;span class="s2"&gt;"asterisk -rx 'sip show peer agent_1001' | grep -E 'Status|Reg. Contact'"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You should see the status update periodically. If it goes stale, re-registration is failing.&lt;/p&gt;




&lt;h2&gt;
  
  
  Step 8: Diagnose NAT and External IP Issues
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Problem: Peer Behind NAT with Wrong Contact IP
&lt;/h3&gt;

&lt;p&gt;When a peer is behind NAT, the SIP REGISTER Contact header contains the private IP (e.g., 192.168.1.100). Asterisk stores this. When Asterisk tries to send SIP traffic back, it fails because 192.168.1.100 is unreachable from outside the NAT.&lt;/p&gt;

&lt;h3&gt;
  
  
  Enable Symmetric RTP and IP Checking
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;force_rport&lt;/span&gt;
&lt;span class="n"&gt;symmetric_rtp&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;

[&lt;span class="n"&gt;agent_1001&lt;/span&gt;]
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;password&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;force_rport&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Use STUN for NAT Traversal
&lt;/h3&gt;

&lt;p&gt;Configure STUN server in sip-vicidial.conf:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;externip&lt;/span&gt;=&lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;50&lt;/span&gt;
&lt;span class="n"&gt;localnet&lt;/span&gt;=&lt;span class="m"&gt;192&lt;/span&gt;.&lt;span class="m"&gt;168&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;/&lt;span class="m"&gt;255&lt;/span&gt;.&lt;span class="m"&gt;255&lt;/span&gt;.&lt;span class="m"&gt;255&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or use STUN:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;stunaddr&lt;/span&gt;=&lt;span class="n"&gt;stun&lt;/span&gt;.&lt;span class="n"&gt;l&lt;/span&gt;.&lt;span class="n"&gt;google&lt;/span&gt;.&lt;span class="n"&gt;com&lt;/span&gt;:&lt;span class="m"&gt;19302&lt;/span&gt;
&lt;span class="n"&gt;stunrefreshinterval&lt;/span&gt;=&lt;span class="m"&gt;3600&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Check External IP Detection
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show settings"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"external&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;nat&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;stun"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 9: Examine SIP Request/Response Logs in Asterisk
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Check Full Call Trace with Verbose Logging
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core set verbose 5"&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"core set verbose 0"&lt;/span&gt; &lt;span class="c"&gt;# Disable when done&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Parse Key Messages
&lt;/h3&gt;

&lt;p&gt;Look for these indicators in &lt;code&gt;/var/log/asterisk/messages&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# GOOD: Registration accepted&lt;/span&gt;
chan_sip.c: Registration accepted &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s1"&gt;'agent_1001'&lt;/span&gt; &amp;lt;sip:agent_1001@...&amp;gt;

&lt;span class="c"&gt;# BAD: Invalid credentials&lt;/span&gt;
chan_sip.c: Failed to authenticate user &lt;span class="s1"&gt;'agent_1001'&lt;/span&gt;

&lt;span class="c"&gt;# BAD: Peer not configured&lt;/span&gt;
chan_sip.c: No matching SIP user or peer found &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="s1"&gt;'agent_1001'&lt;/span&gt;

&lt;span class="c"&gt;# BAD: Expiration&lt;/span&gt;
chan_sip.c: Registration of &lt;span class="s1"&gt;'agent_1001'&lt;/span&gt; expired
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Export Full Debug to File
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; /tmp/sip_debug.log 2&amp;gt;&amp;amp;1 &amp;amp;
&lt;span class="c"&gt;# Wait for activity, then:&lt;/span&gt;
asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug off"&lt;/span&gt;
&lt;span class="nb"&gt;cat&lt;/span&gt; /tmp/sip_debug.log | &lt;span class="nb"&gt;head&lt;/span&gt; &lt;span class="nt"&gt;-200&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Step 10: Test with SIP CLI Commands
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Send Manual REGISTER Request
&lt;/h3&gt;

&lt;p&gt;Use &lt;code&gt;sipsak&lt;/code&gt; (if installed) to simulate a registration:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;sipsak &lt;span class="nt"&gt;-r&lt;/span&gt; sip:agent_1001@asterisk.local &lt;span class="nt"&gt;-u&lt;/span&gt; agent_1001:MySecurePassword123
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Or install it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;yum &lt;span class="nb"&gt;install &lt;/span&gt;sipsak  &lt;span class="c"&gt;# CentOS/RHEL&lt;/span&gt;
apt-get &lt;span class="nb"&gt;install &lt;/span&gt;sipsak  &lt;span class="c"&gt;# Debian/Ubuntu&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Query Asterisk SIP Registry State
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show registry"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This shows &lt;strong&gt;outbound&lt;/strong&gt; registrations (when Asterisk registers to another server):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Host                           Username       Refresh State                Reg.Time
203.0.113.45:5060             vicidial_acc   105 Registered           Wed Jan 15 14:32:18 2024
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If a carrier registration shows &lt;code&gt;Request Sent&lt;/code&gt; or &lt;code&gt;Auth. Sent&lt;/code&gt;, it's stuck in the handshake.&lt;/p&gt;




&lt;h2&gt;
  
  
  Troubleshooting Checklist
&lt;/h2&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Issue&lt;/th&gt;
&lt;th&gt;Symptoms&lt;/th&gt;
&lt;th&gt;Solutions&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Peer never appears in &lt;code&gt;sip show peers&lt;/code&gt;&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Completely missing from list&lt;/td&gt;
&lt;td&gt;Check syntax with &lt;code&gt;sip reload&lt;/code&gt;, verify peer name, look for parse errors in logs&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Peer shows UNKNOWN&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Status is UNKNOWN, no registration&lt;/td&gt;
&lt;td&gt;Verify client is sending REGISTER, check firewall port 5060/UDP, check credentials&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Peer shows UNREACHABLE&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Status is UNREACHABLE&lt;/td&gt;
&lt;td&gt;Check &lt;code&gt;qualify=yes&lt;/code&gt;, verify reachability with ping/nc, check firewall ICMP&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;"Peer is Not Registered" dial error&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Error when calling peer&lt;/td&gt;
&lt;td&gt;Check if registration expired, verify re-registration interval, check database status&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;401 Unauthorized response&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Debug shows 401 replies&lt;/td&gt;
&lt;td&gt;Verify secret matches in config and client, check defaultuser, verify realm&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Contact stored as private IP behind NAT&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Calls work internally but not externally&lt;/td&gt;
&lt;td&gt;Enable &lt;code&gt;nat=force_rport&lt;/code&gt;, set &lt;code&gt;externip=&lt;/code&gt;, use &lt;code&gt;directmedia=no&lt;/code&gt;
&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Registration works, but qualifications fail&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Status changes to UNKNOWN periodically&lt;/td&gt;
&lt;td&gt;Check network connectivity, increase &lt;code&gt;qualifyfreq&lt;/code&gt;, verify UDP path open&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Dynamic peer IP never updates&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;Peer's host keeps old IP after network change&lt;/td&gt;
&lt;td&gt;Check &lt;code&gt;nat=yes&lt;/code&gt;, restart client, check Asterisk can receive OPTIONS ping&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;




&lt;h2&gt;
  
  
  Production Best Practices
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Recommended sip-vicidial.conf Configuration for Agents
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="n"&gt;general&lt;/span&gt;]
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;internal&lt;/span&gt;
&lt;span class="n"&gt;recordhistory&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;bindport&lt;/span&gt;=&lt;span class="m"&gt;5060&lt;/span&gt;
&lt;span class="n"&gt;bindaddr&lt;/span&gt;=&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;srvlookup&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;transport&lt;/span&gt;=&lt;span class="n"&gt;udp&lt;/span&gt;,&lt;span class="n"&gt;tcp&lt;/span&gt;
&lt;span class="n"&gt;allowguest&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;60&lt;/span&gt;
&lt;span class="n"&gt;defaultexpire&lt;/span&gt;=&lt;span class="m"&gt;3600&lt;/span&gt;
&lt;span class="n"&gt;minexpire&lt;/span&gt;=&lt;span class="m"&gt;120&lt;/span&gt;
&lt;span class="n"&gt;maxexpire&lt;/span&gt;=&lt;span class="m"&gt;7200&lt;/span&gt;
&lt;span class="n"&gt;externip&lt;/span&gt;=&lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;50&lt;/span&gt;
&lt;span class="n"&gt;localnet&lt;/span&gt;=&lt;span class="m"&gt;192&lt;/span&gt;.&lt;span class="m"&gt;168&lt;/span&gt;.&lt;span class="m"&gt;1&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;/&lt;span class="m"&gt;255&lt;/span&gt;.&lt;span class="m"&gt;255&lt;/span&gt;.&lt;span class="m"&gt;255&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;force_rport&lt;/span&gt;
&lt;span class="n"&gt;symmetric_rtp&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;rtptimeout&lt;/span&gt;=&lt;span class="m"&gt;300&lt;/span&gt;
&lt;span class="n"&gt;icesupport&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;

[&lt;span class="n"&gt;agent_template&lt;/span&gt;](!)
&lt;span class="n"&gt;type&lt;/span&gt;=&lt;span class="n"&gt;friend&lt;/span&gt;
&lt;span class="n"&gt;context&lt;/span&gt;=&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;internal&lt;/span&gt;
&lt;span class="n"&gt;disallow&lt;/span&gt;=&lt;span class="n"&gt;all&lt;/span&gt;
&lt;span class="n"&gt;allow&lt;/span&gt;=&lt;span class="n"&gt;ulaw&lt;/span&gt;,&lt;span class="n"&gt;alaw&lt;/span&gt;,&lt;span class="n"&gt;gsm&lt;/span&gt;
&lt;span class="n"&gt;directmedia&lt;/span&gt;=&lt;span class="n"&gt;no&lt;/span&gt;
&lt;span class="n"&gt;nat&lt;/span&gt;=&lt;span class="n"&gt;force_rport&lt;/span&gt;
&lt;span class="n"&gt;qualify&lt;/span&gt;=&lt;span class="n"&gt;yes&lt;/span&gt;
&lt;span class="n"&gt;qualifyfreq&lt;/span&gt;=&lt;span class="m"&gt;120&lt;/span&gt;
&lt;span class="n"&gt;defaultexpire&lt;/span&gt;=&lt;span class="m"&gt;3600&lt;/span&gt;
&lt;span class="n"&gt;mailbox&lt;/span&gt;=${&lt;span class="n"&gt;EXTEN&lt;/span&gt;}@&lt;span class="n"&gt;default&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then per-extension:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;[&lt;span class="m"&gt;1001&lt;/span&gt;](&lt;span class="n"&gt;agent_template&lt;/span&gt;)
&lt;span class="n"&gt;defaultuser&lt;/span&gt;=&lt;span class="m"&gt;1001&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;SecurePassword2024&lt;/span&gt;
&lt;span class="n"&gt;fullname&lt;/span&gt;=&lt;span class="n"&gt;John&lt;/span&gt; &lt;span class="n"&gt;Doe&lt;/span&gt;

[&lt;span class="m"&gt;1002&lt;/span&gt;](&lt;span class="n"&gt;agent_template&lt;/span&gt;)
&lt;span class="n"&gt;defaultuser&lt;/span&gt;=&lt;span class="m"&gt;1002&lt;/span&gt;
&lt;span class="n"&gt;secret&lt;/span&gt;=&lt;span class="n"&gt;SecurePassword2024&lt;/span&gt;
&lt;span class="n"&gt;fullname&lt;/span&gt;=&lt;span class="n"&gt;Jane&lt;/span&gt; &lt;span class="n"&gt;Smith&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Monitoring Script
&lt;/h3&gt;

&lt;p&gt;Create &lt;code&gt;/usr/local/bin/monitor_sip_registrations.sh&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="nv"&gt;ASTERISK_CLI&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;"/usr/bin/asterisk -rx"&lt;/span&gt;

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== SIP Registration Status ==="&lt;/span&gt;
&lt;span class="nv"&gt;$ASTERISK_CLI&lt;/span&gt; &lt;span class="s2"&gt;"sip show peers"&lt;/span&gt; | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"^[a-z0-9_]+"&lt;/span&gt; | &lt;span class="k"&gt;while &lt;/span&gt;&lt;span class="nb"&gt;read &lt;/span&gt;LINE&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;do
    &lt;/span&gt;&lt;span class="nv"&gt;PEER&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LINE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $1}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;STATUS&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="si"&gt;$(&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$LINE&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; | &lt;span class="nb"&gt;awk&lt;/span&gt; &lt;span class="s1"&gt;'{print $NF}'&lt;/span&gt;&lt;span class="si"&gt;)&lt;/span&gt;

    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"OK"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="o"&gt;[[&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="nv"&gt;$STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;!=&lt;/span&gt; &lt;span class="s2"&gt;"UNKNOWN"&lt;/span&gt; &lt;span class="o"&gt;]]&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="k"&gt;then
        &lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"WARNING: &lt;/span&gt;&lt;span class="nv"&gt;$PEER&lt;/span&gt;&lt;span class="s2"&gt; - &lt;/span&gt;&lt;span class="nv"&gt;$STATUS&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
    &lt;span class="k"&gt;fi
done

&lt;/span&gt;&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Expired Registrations (older than 1 hour) ==="&lt;/span&gt;
mysql &lt;span class="nt"&gt;-u&lt;/span&gt; vicidial &lt;span class="nt"&gt;-p&lt;/span&gt; asterisk &lt;span class="nt"&gt;-e&lt;/span&gt; &lt;span class="s2"&gt;"
SELECT extension, registration_date, NOW() FROM vicidial_sip_registration
WHERE TIMESTAMPDIFF(HOUR, registration_date, NOW()) &amp;gt; 1;"&lt;/span&gt; 2&amp;gt;/dev/null

&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;""&lt;/span&gt;
&lt;span class="nb"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"=== Failed Registration Attempts (Last 10) ==="&lt;/span&gt;
&lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-100&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-i&lt;/span&gt; &lt;span class="s2"&gt;"failed.*register&lt;/span&gt;&lt;span class="se"&gt;\|&lt;/span&gt;&lt;span class="s2"&gt;unauthorized"&lt;/span&gt; | &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Run as a cron job:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;0 &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; &lt;span class="k"&gt;*&lt;/span&gt; /usr/local/bin/monitor_sip_registrations.sh &lt;span class="o"&gt;&amp;gt;&amp;gt;&lt;/span&gt; /var/log/sip_monitor.log 2&amp;gt;&amp;amp;1
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Advanced Troubleshooting: Outbound Registration Issues
&lt;/h2&gt;

&lt;p&gt;If &lt;strong&gt;Asterisk is trying to register TO an external carrier&lt;/strong&gt; and shows "Peer is Not Registered":&lt;/p&gt;

&lt;h3&gt;
  
  
  Check Outbound Registration Config
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;register&lt;/span&gt; =&amp;gt; &lt;span class="n"&gt;vicidial_account&lt;/span&gt;:&lt;span class="n"&gt;VerySecurePassword123&lt;/span&gt;@&lt;span class="m"&gt;203&lt;/span&gt;.&lt;span class="m"&gt;0&lt;/span&gt;.&lt;span class="m"&gt;113&lt;/span&gt;.&lt;span class="m"&gt;45&lt;/span&gt;:&lt;span class="m"&gt;5060&lt;/span&gt;/&lt;span class="n"&gt;from&lt;/span&gt;-&lt;span class="n"&gt;pstn&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Verify Outbound Registration Status
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip show registry"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If stuck in &lt;code&gt;Request Sent&lt;/code&gt;:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check carrier endpoint is reachable&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   nc &lt;span class="nt"&gt;-zv&lt;/span&gt; 203.0.113.45 5060
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check firewall allows outbound SIP&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   &lt;span class="nb"&gt;sudo &lt;/span&gt;iptables &lt;span class="nt"&gt;-L&lt;/span&gt; &lt;span class="nt"&gt;-n&lt;/span&gt; | &lt;span class="nb"&gt;grep &lt;/span&gt;5060
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify carrier accepts registrations from your IP&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   Contact your carrier to whitelist your public IP
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Check authentication with carrier&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip set debug on"&lt;/span&gt;
   asterisk &lt;span class="nt"&gt;-rx&lt;/span&gt; &lt;span class="s2"&gt;"sip reload"&lt;/span&gt;
   &lt;span class="nb"&gt;tail&lt;/span&gt; &lt;span class="nt"&gt;-f&lt;/span&gt; /var/log/asterisk/messages | &lt;span class="nb"&gt;grep&lt;/span&gt; &lt;span class="nt"&gt;-E&lt;/span&gt; &lt;span class="s2"&gt;"register|auth|carrier_sip"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Test with SIPp if available&lt;/strong&gt;:
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;   sipp &lt;span class="nt"&gt;-sf&lt;/span&gt; /tmp/register.xml &lt;span class="nt"&gt;-s&lt;/span&gt; vicidial_account@203.0.113.45 203.0.113.45
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  Summary
&lt;/h2&gt;

&lt;p&gt;Resolving "Peer Is Not Registered" errors in production Asterisk/ViciDial systems requires systematic diagnosis:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Verify configuration syntax&lt;/strong&gt; — invalid peers won't load at all&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Confirm peer exists&lt;/strong&gt; — check &lt;code&gt;sip show peers&lt;/code&gt; output&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test network connectivity&lt;/strong&gt; — firewall must allow UDP/TCP 5060&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Enable debugging&lt;/strong&gt; — capture SIP REGISTER requests and responses&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Check database state&lt;/strong&gt; — ViciDial extensions must be ACTIVE&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Match credentials&lt;/strong&gt; — secret, defaultuser, and realm must align&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Monitor expiration&lt;/strong&gt; — registrations expire after the configured interval&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Handle NAT&lt;/strong&gt; — enable &lt;code&gt;nat=force_rport&lt;/code&gt;, set &lt;code&gt;externip=&lt;/code&gt;, disable &lt;code&gt;directmedia&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Review logs&lt;/strong&gt; — parse &lt;code&gt;/var/log/asterisk/messages&lt;/code&gt; for authentication/registration failures&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Test systematically&lt;/strong&gt; — isolate variables (network, config, credentials, firewall)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;When a peer shows "Peer is Not Registered" in your ViciDial call logs or Asterisk CLI, follow the 10-step process above. Most issues resolve at steps 2–3 (configuration/firewall) or step 6 (credentials). For edge cases, enable SIP debugging and parse the actual REGISTER request/response sequence.&lt;/p&gt;

&lt;p&gt;Keep this guide bookmarked. SIP registration is the foundation of ViciDial's agent connectivity. When it breaks, nothing works.&lt;/p&gt;

</description>
      <category>devops</category>
      <category>linux</category>
      <category>sip</category>
      <category>voip</category>
    </item>
  </channel>
</rss>
