Master ViciDial disposition codes, implement custom statuses, configure agent workflows, and troubleshoot disposition-related issues in production call center environments.
Prerequisites
Before configuring disposition statuses in ViciDial, ensure you have:
- ViciDial 2.14+ installed and running (this guide applies to 2.14–2.15+)
- Root or administrative database access to the asterisk MySQL database
- SSH access to your ViciDial server for command-line operations
- Agent login credentials for testing agent-facing UI changes
- PhpMyAdmin or MySQL CLI for direct database queries
- Backup of your asterisk database before making changes
- Understanding of call disposition workflows in your organization
- Access to ViciDial admin panel (/vicidial/admin.php)
Verify your setup with:
mysql -u root -p asterisk -e "SELECT VERSION();"
asterisk -rx "core show version"
ps aux | grep vicidial
What Are ViciDial Disposition Statuses?
Disposition statuses represent the outcome of a call recorded in your call center. When an agent ends a call, they select a disposition code that categorizes what happened: "Sold," "No Answer," "Callback," "Wrong Number," etc.
ViciDial stores these dispositions in the database and uses them for:
- Call analytics and reporting (conversion rates, abandonment tracking)
- Compliance and call tagging (for recording regulations, quality assurance)
- Callback queuing (disposition rules can auto-schedule future calls)
- Lead status tracking (updating CRM integration feeds)
- Agent performance metrics (which agents achieve higher sales rates)
- Dial plan routing (different dispositions trigger different behaviors)
Every call logged in vicidial_log must have a valid disposition from the vicidial_statuses table.
The ViciDial Statuses Table Structure
The core disposition data lives in the vicidial_statuses table. Understanding its schema is essential for custom configuration.
Default Table Schema
DESCRIBE vicidial_statuses;
Output:
| Field | Type | Null | Key | Default |
|------------------|--------------|------|-----|---------|
| status | varchar(6) | NO | PRI | NULL |
| status_name | varchar(20) | NO | | NULL |
| status_details | varchar(255) | YES | | NULL |
| scheduled_status | char(1) | NO | | N |
| customer_viewable| char(1) | NO | | N |
| agent_viewable | char(1) | NO | | Y |
| lead_status_id | int(11) | YES | | NULL |
| callback_type | varchar(20) | YES | | NULL |
| scheduled_callback| char(1) | NO | | N |
Column Definitions
| Column | Purpose | Example |
|---|---|---|
status |
6-char code, primary key | SALE, CALLB |
status_name |
Display name (20 chars max) | Sale, Callback |
status_details |
Long description for clarity | Successful sale completed |
scheduled_status |
'Y' if status schedules callbacks | Y |
customer_viewable |
'Y' if visible on customer portal | N |
agent_viewable |
'Y' if agent can select it | Y |
lead_status_id |
Maps to external CRM/lead table | 1, 2, etc. |
callback_type |
Type of callback: SAME_AGENT, ANY_AGENT, VOICEMAIL |
SAME_AGENT |
scheduled_callback |
'Y' if auto-schedules for future | Y |
Default ViciDial Disposition Statuses
ViciDial ships with these standard dispositions:
SELECT status, status_name, scheduled_status, agent_viewable
FROM vicidial_statuses
ORDER BY status;
Common defaults:
| SALE | Sale | N | Y |
| CALLB | Callback | Y | Y |
| XFER | Transfer | N | Y |
| AFAX | Answering Machine | N | Y |
| IGVM | IVR/Voicemail | N | Y |
| XFAX | Transfer Fax | N | Y |
| DROP | Dropped Call | N | N |
| RING | No Answer/Ring | N | Y |
| BUSY | Busy Signal | N | Y |
| INTL | International | N | Y |
| INVALID | Invalid Number | N | Y |
| NOTINT | Not Interested | N | Y |
| ABANDON | Agent Abandoned | N | N |
| VLCM | Voicemail/IVR | N | Y |
| REVIEW | Review | N | Y |
| DLEADS | DNC/Bad Lead | N | Y |
| DNCS | Do Not Call List | N | Y |
| PAID | Paid | N | Y |
Not all defaults are visible to agents—some (like DROP, ABANDON) are system-assigned.
Adding Custom Disposition Statuses
Most call centers need custom statuses beyond ViciDial's defaults. Common examples:
WARM– Warm lead for follow-upSURVEY– Customer completed surveyDISPUTE– Payment dispute or refundDCNTCT– Do Not Contact (different from DNC list)RESCHL– Rescheduled appointmentPARTIAL– Partial sale or trial signup
Method 1: Via ViciDial Web Admin Panel
Login to
/vicidial/admin.phpNavigate: System > Statuses
Click Add New Status
Fill in:
- Status Code:
WARM(6 chars max, uppercase) - Status Name:
Warm Lead(20 chars max) - Status Details:
Prospect interested, needs follow-up(optional) - Scheduled Status: Toggle if this triggers callbacks
- Agent Viewable:
Yes(so agents can select it) - Customer Viewable:
No(for internal use only)
- Status Code:
Click Save
Method 2: Direct Database Insert (Recommended for Scripting/Bulk)
INSERT INTO vicidial_statuses
(status, status_name, status_details, scheduled_status, customer_viewable, agent_viewable, callback_type, scheduled_callback)
VALUES
('WARM', 'Warm Lead', 'Prospect interested, needs follow-up', 'N', 'N', 'Y', NULL, 'N'),
('SURVEY', 'Survey Completed', 'Customer completed survey', 'N', 'N', 'Y', NULL, 'N'),
('DISPUTE', 'Dispute', 'Customer reports payment issue', 'Y', 'N', 'Y', 'SAME_AGENT', 'Y'),
('DCNTCT', 'Do Not Contact', 'Customer requests no contact', 'N', 'N', 'Y', NULL, 'N'),
('RESCHL', 'Rescheduled', 'Appointment rescheduled', 'Y', 'N', 'Y', 'SAME_AGENT', 'Y'),
('PARTIAL', 'Trial Signup', 'Customer signed up for trial', 'Y', 'N', 'Y', 'ANY_AGENT', 'Y');
Always test in a development environment first.
Verify insertion:
SELECT status, status_name, scheduled_status, agent_viewable
FROM vicidial_statuses
WHERE status IN ('WARM', 'SURVEY', 'DISPUTE', 'DCNTCT', 'RESCHL', 'PARTIAL');
Method 3: Via Script (Bash + MySQL)
Create /tmp/add_dispositions.sql:
USE asterisk;
INSERT INTO vicidial_statuses (status, status_name, status_details, scheduled_status, agent_viewable, callback_type, scheduled_callback)
VALUES ('WARM', 'Warm Lead', 'Interested prospect', 'N', 'Y', NULL, 'N');
INSERT INTO vicidial_statuses (status, status_name, status_details, scheduled_status, agent_viewable, callback_type, scheduled_callback)
VALUES ('SURVEY', 'Survey', 'Completed survey', 'N', 'Y', NULL, 'N');
-- Add more as needed...
Execute:
mysql -u root -p < /tmp/add_dispositions.sql
Or without interactive password prompt:
mysql -u root -p"YOUR_PASSWORD" < /tmp/add_dispositions.sql
Mapping Dispositions to Lead Statuses
ViciDial can integrate dispositions with external lead management systems via lead_status_id. This field links a disposition to a status in your CRM or lead database.
Understanding lead_status_id
The lead_status_id column in vicidial_statuses maps to the vicidial_list.lead_status field. When an agent selects a disposition, that lead's status updates accordingly.
Query available lead statuses:
SELECT DISTINCT lead_status FROM vicidial_list LIMIT 20;
Common lead_status values:
NEW– New leadCALL– Ready for callCALLBACK– Scheduled callbackSALE– Sale completedDNCS– Do not call
Mapping Example
Link your custom "WARM" disposition to lead status CALLBACK:
UPDATE vicidial_statuses
SET lead_status_id =
(SELECT COALESCE(MAX(CAST(lead_status AS UNSIGNED)), 0) + 1 FROM vicidial_list)
WHERE status = 'WARM';
-- Or explicitly:
UPDATE vicidial_statuses
SET lead_status = 'CALLBACK'
WHERE status = 'WARM';
Configuring Scheduled Callbacks
When an agent selects a "Callback" or custom disposition marked for scheduling, ViciDial can automatically insert that lead back into the queue for a future date/time.
Enable Scheduling on a Disposition
UPDATE vicidial_statuses
SET scheduled_status = 'Y',
callback_type = 'SAME_AGENT',
scheduled_callback = 'Y'
WHERE status = 'DISPUTE';
Callback Types
| Type | Behavior |
|---|---|
SAME_AGENT |
Callback scheduled only for original agent |
ANY_AGENT |
Any available agent can take callback |
VOICEMAIL |
Auto-dial with voicemail |
How Callbacks Work in Production
- Agent dials lead, conversation occurs
- Agent selects "DISPUTE" disposition
- ViciDial UI prompts agent for callback date/time
- Record inserted into
vicidial_callbackstable - Vicidial dialer process checks table periodically
- At scheduled time, call re-queued to appropriate agent/queue
Verify callback records:
SELECT lead_id, phone_number, callback_datetime, callback_type
FROM vicidial_callbacks
WHERE callback_datetime > NOW()
LIMIT 10;
Agent-Facing Disposition UI Customization
How agents interact with dispositions is configured in /agc/vicidial.php (the agent client).
Controlling Disposition Visibility
In vicidial_statuses, toggle agent access:
-- Hide a disposition from agents (system-assigned only)
UPDATE vicidial_statuses
SET agent_viewable = 'N'
WHERE status = 'ABANDON';
-- Show a disposition to agents
UPDATE vicidial_statuses
SET agent_viewable = 'Y'
WHERE status = 'WARM';
Grouping Dispositions (Using Status Details)
While ViciDial doesn't have built-in grouping, you can use status_details to organize codes in documentation:
UPDATE vicidial_statuses
SET status_details = 'SALES_GROUP: Prospect converted to customer'
WHERE status = 'SALE';
UPDATE vicidial_statuses
SET status_details = 'SALES_GROUP: Prospect interested but not ready'
WHERE status = 'WARM';
UPDATE vicidial_statuses
SET status_details = 'REJECTION_GROUP: Lead not interested in product'
WHERE status = 'NOTINT';
Agents see this in tooltips/hover text in some UI versions.
Custom Disposition Dropdown Order
ViciDial sorts dispositions alphabetically by status_name. To customize order, some deployments use numeric prefixes:
UPDATE vicidial_statuses
SET status_name = '01 - Sale'
WHERE status = 'SALE';
UPDATE vicidial_statuses
SET status_name = '02 - Callback'
WHERE status = 'CALLB';
UPDATE vicidial_statuses
SET status_name = '99 - Abandoned'
WHERE status = 'ABANDON';
Note: This affects sorting but requires agents to ignore numeric prefix when reading.
Disposition Rules & Automation
ViciDial can automatically trigger actions based on disposition selection. Configuration happens in vicidial_disposition_rules table.
View Existing Rules
SELECT rule_id, disposition, pause_after_call, seconds_pause, pause_type
FROM vicidial_disposition_rules;
Common Automation: Force Pause After Sale
Require agents to pause (e.g., for documentation) after recording a sale:
INSERT INTO vicidial_disposition_rules
(disposition, pause_after_call, seconds_pause, pause_type)
VALUES
('SALE', 'Y', 60, 'AFTER_SALE_PAUSE');
This forces a 60-second pause on agents after they log a sale disposition.
Automatic DNC List Addition
Some dispositions automatically add numbers to DNC (Do Not Call) list:
This is typically handled in the dialer code, but can be logged by disposition:
-- Log which dispositions hit DNC
SELECT COUNT(*), disposition
FROM vicidial_log
WHERE disposition IN ('DNCS', 'DLEADS')
GROUP BY disposition;
Reporting & Analytics by Disposition
Most call centers track KPIs by disposition. Common queries:
Disposition Summary Today
SELECT disposition, COUNT(*) as calls,
ROUND(COUNT(*) * 100.0 / (SELECT COUNT(*) FROM vicidial_log WHERE call_date >= CURDATE()), 2) as pct
FROM vicidial_log
WHERE call_date >= CURDATE()
GROUP BY disposition
ORDER BY calls DESC;
Sales Conversion Rate by Agent
SELECT user,
SUM(CASE WHEN disposition = 'SALE' THEN 1 ELSE 0 END) as sales,
COUNT(*) as total_calls,
ROUND(SUM(CASE WHEN disposition = 'SALE' THEN 1 ELSE 0 END) * 100.0 / COUNT(*), 2) as conversion_pct
FROM vicidial_log
WHERE call_date >= DATE_SUB(CURDATE(), INTERVAL 7 DAY)
GROUP BY user
ORDER BY sales DESC;
Callbacks Scheduled vs. Completed
SELECT disposition,
COUNT(*) as dispositions_selected,
SUM(CASE WHEN disposition IN ('CALLB', 'DISPUTE', 'RESCHL') THEN 1 ELSE 0 END) as callbacks_scheduled
FROM vicidial_log
WHERE call_date >= DATE_SUB(CURDATE(), INTERVAL 30 DAY)
GROUP BY disposition;
Time to Disposition (Handle Time)
SELECT disposition,
COUNT(*) as calls,
ROUND(AVG(LENGTH_OF_CALL), 2) as avg_seconds,
MAX(LENGTH_OF_CALL) as longest_call
FROM vicidial_log
WHERE call_date >= CURDATE()
GROUP BY disposition
ORDER BY avg_seconds DESC;
ViciDial Configuration Files (Advanced)
For full customization, some settings live in config files, though most disposition logic is database-driven.
Relevant Config Paths
Asterisk extensions (call routing by disposition):
/etc/asterisk/extensions-vicidial.conf
SIP configuration:
/etc/asterisk/sip-vicidial.conf
ViciDial web config:
/var/www/html/vicidial/vicidial_settings.php
Example: Disable Disposition Selection for Certain Agents
While not in config files, you can restrict agent groups by modifying the agent record:
-- Agent 'john' can ONLY select SALE or CALLB
-- This requires custom UI mod, but data structure allows it
UPDATE vicidial_users
SET agent_group = 'SALES_ONLY'
WHERE user = 'john';
Then query agents during call to enforce:
SELECT allowed_statuses FROM vicidial_user_groups
WHERE group_name = 'SALES_ONLY';
This requires custom code in /agc/vicidial.php to implement.
Troubleshooting Disposition Issues
Issue 1: Agent Sees "Invalid Disposition" Error
Symptom: Agent logs call but gets error when selecting disposition.
Cause: Selected disposition code doesn't exist in vicidial_statuses or is not viewable.
Solution:
# Check if disposition is in database
mysql -u root -p asterisk -e \
"SELECT status, agent_viewable FROM vicidial_statuses WHERE status = 'WARM';"
# If missing, add it:
mysql -u root -p asterisk -e \
"INSERT INTO vicidial_statuses (status, status_name, agent_viewable) VALUES ('WARM', 'Warm Lead', 'Y');"
# If hidden, make it visible:
mysql -u root -p asterisk -e \
"UPDATE vicidial_statuses SET agent_viewable = 'Y' WHERE status = 'WARM';"
Then reload ViciDial dialer:
/usr/share/astguiclient/ADMIN_reload_vicidial_agent.pl
Issue 2: Callbacks Not Triggering
Symptom: Agent selects callback disposition but lead doesn't re-queue.
Cause: scheduled_callback not set to 'Y' or callback type not configured.
Solution:
-- Verify callback disposition config
SELECT status, scheduled_status, scheduled_callback, callback_type
FROM vicidial_statuses
WHERE status = 'CALLB';
-- Should show: CALLB | Y | Y | SAME_AGENT or ANY_AGENT
-- If not, update:
UPDATE vicidial_statuses
SET scheduled_status = 'Y', scheduled_callback = 'Y', callback_type = 'SAME_AGENT'
WHERE status = 'CALLB';
-- Verify callback queue
SELECT * FROM vicidial_callbacks WHERE callback_datetime > NOW() LIMIT 5;
Check ViciDial dialer logs:
tail -f /var/log/asterisk/messages | grep -i callback
Issue 3: Custom Disposition Not Appearing in Dropdown
Symptom: New custom disposition added but agents don't see it in UI.
Cause:
- Disposition not viewable to agents
- Agent screen needs cache cleared
- Database not synchronized to all dialer nodes
Solution:
# Verify viewable flag
mysql -u root -p asterisk -e \
"SELECT status, status_name, agent_viewable FROM vicidial_statuses WHERE status = 'SURVEY';"
# Ensure it's viewable
mysql -u root -p asterisk -e \
"UPDATE vicidial_statuses SET agent_viewable = 'Y' WHERE status = 'SURVEY';"
# Clear agent screen cache
rm -rf /tmp/vicidial_*.cache
# Reload dialer
/usr/share/astguiclient/ADMIN_reload_vicidial_dialer.pl
Restart Asterisk if needed:
asterisk -rx "core restart graceful"
Issue 4: Disposition Assignment Causing Call Log Errors
Symptom: Calls logged but disposition missing or NULL in vicidial_log.
Cause: Agent disconnected before selecting disposition, or default disposition not configured.
Solution:
-- Check for NULL dispositions
SELECT call_id, user, phone_number, disposition
FROM vicidial_log
WHERE disposition IS NULL OR disposition = ''
LIMIT 20;
-- Set a default disposition if missing
UPDATE vicidial_log
SET disposition = 'REVIEW'
WHERE disposition IS NULL AND call_date >= CURDATE();
Then investigate why disposition wasn't captured (check Asterisk logs):
tail -100 /var/log/asterisk/messages | grep -i "disposition\|agent\|call"
Issue 5: Disposition Count Mismatch in Reports
Symptom: Total calls ≠ sum of disposition counts.
Cause: Inbound calls, test calls, or dropped calls logged without disposition.
Solution:
-- Find unmatched calls
SELECT COUNT(*) as total_calls FROM vicidial_log WHERE call_date >= CURDATE();
SELECT COUNT(*) as calls_with_disposition FROM vicidial_log
WHERE call_date >= CURDATE() AND disposition IS NOT NULL AND disposition != '';
-- Calls without disposition
SELECT COUNT(*) as calls_no_disposition FROM vicidial_log
WHERE call_date >= CURDATE() AND (disposition IS NULL OR disposition = '');
-- Check call types
SELECT call_type, COUNT(*) FROM vicidial_log
WHERE call_date >= CURDATE() GROUP BY call_type;
Filter inbound calls if they shouldn't count:
-- Outbound only
SELECT disposition, COUNT(*) FROM vicidial_log
WHERE call_date >= CURDATE() AND call_type = 'OUT'
GROUP BY disposition;
Best Practices for Disposition Management
Name codes clearly: Use descriptive
status_namevalues (e.g.,Warm LeadnotWL). Agents need instant recognition.Keep codes ≤6 characters: ViciDial schema limits to 6 chars. Choose meaningful abbreviations.
Audit new dispositions: Before deploying custom statuses, verify they don't conflict with existing codes or external integrations.
Test callback logic: Always test scheduled callbacks in staging with dummy leads before production deployment.
Document for agents: Create a quick reference (PDF or printed) with all dispositions, definitions, and when to use each.
Monitor disposition drift: Track if agents use dispositions as intended. Run quarterly audits.
Use status_details for context: Leverage the optional field to provide business rules or examples.
Version control database changes: Maintain SQL migration scripts in Git for disaster recovery.
Restrict sensitive statuses: Ensure
agent_viewable = 'N'for system-only codes likeDROP,ABANDON.Test UI changes thoroughly: Disposition changes affect agent workflow; test with small agent group first.
Summary
ViciDial disposition statuses are fundamental to call center operations. They categorize call outcomes, drive analytics, and automate workflows like callback scheduling.
Key takeaways:
- Dispositions live in
vicidial_statusestable — the single source of truth for call outcomes - Custom statuses are easy to add — either via web UI or direct SQL insert
- Agent visibility is controlled — set
agent_viewableflag to show/hide dispositions - Scheduled callbacks integrate with dispositions —
scheduled_statusandcallback_typefields enable auto-queuing - Reporting by disposition is powerful — track KPIs like conversion rate, handle time, and callback completion
- Troubleshooting is database-first — most issues resolve via verification and configuration of the statuses table
- Production deployments require testing — validate custom dispositions in staging before rollout to live agents
For advanced integrations (external CRM sync, custom disposition rules, dynamic agent workflows), ViciDial's database-first architecture supports nearly any customization.
Additional Resources
- ViciDial Official Documentation: https://vicidial.org/
- Asterisk Command Reference:
asterisk -rx "help" - MySQL Reference: https://dev.mysql.com/doc/
- ViciDial Admin Guides:
/vicidial/admin.phpbuilt-in help - Community Forums: ViciDial forums for peer support