Remove dead, duplicate, or problem leads from your ViciDial campaigns by deactivating, resetting status, or purging records directly from the database or admin panel.
ViciDial stores all lead data in the vicidial_list table. You remove or reset leads by changing their status field (typically to "SKIP", "DROP", or bulk deleting), running bulk operations through the admin interface, or executing direct database queries. The method you choose depends on whether you want to preserve the record for audit purposes or erase it completely.
Tested on ViciDial 2.14 (SVN 3555+), Asterisk 16/18, MariaDB 10.5+.
Prerequisites
- SSH access to the ViciDial server or root/database admin credentials
- Database credentials (usually in /etc/astguiclient.conf or /root/.my.cnf)
- Admin-level user account in ViciDial web UI (http://your-server/vicidial/admin.php)
- A backup of your vicidial_list table before running bulk deletes
- Understanding of your campaign's list structure and active call flow
Database and table reference
The vicidial_list table holds all lead records. Key columns relevant to deactivation and deletion:
lead_id (primary key, auto-increment)
list_id (campaign list identifier)
phone_number (dialed number)
status (ACTIVE, DEAD, SKIP, QUEUE, INBOUND, DROP, etc.)
vendor_lead_id (external ID, if present)
date_created (timestamp)
date_last_call (timestamp of most recent attempt)
The vicidial_closer_log table records agent call outcomes. Leads with a status other than ACTIVE are skipped by the dialer.
Method 1: Deactivate leads via the web admin panel
The simplest method for small batches is the admin UI. Log in with an account that has ADMIN privileges.
- Open http://your-server/vicidial/admin.php
- Go to Admin > Leads > Search
- Select your list_id from the dropdown
- Filter by phone number, vendor_lead_id, or status
- Click the checkboxes next to leads you want to modify
- Select Change Status from the bulk action menu
- Set the new status to SKIP (not yet dialed again) or DROP (remove from pool entirely)
- Click Apply
This method is safe because it only changes the status field. The record remains in the database for compliance and reporting.
If you want to change the status of all leads in a list at once, use the List Tools section:
- Go to Admin > Campaign and select your campaign
- Scroll to List Management
- Click Reset List Status
- Choose the new status from the dropdown
- Confirm the action
This action is irreversible and affects all leads in that list instantly. Stop all agents from working that list first.
Method 2: Reset leads via SQL (bulk status change)
Direct database manipulation is faster for large lists (1000+ leads). Always back up the vicidial_list table before running bulk updates.
Backup the table
mysqldump -u root -p asterisk vicidial_list > /backup/vicidial_list_$(date +%Y%m%d_%H%M%S).sql
Mark all leads in a list as SKIP (do not call again, keep in database)
UPDATE vicidial_list
SET status = 'SKIP'
WHERE list_id = 101
AND status IN ('ACTIVE', 'QUEUE');
Replace 101 with your actual list_id. This prevents the dialer from calling these leads while preserving the record.
Mark leads as DROP (remove from active dialing pool entirely)
UPDATE vicidial_list
SET status = 'DROP'
WHERE list_id = 101
AND status IN ('ACTIVE', 'QUEUE');
Reset status by date (e.g., all leads not called in 30 days)
UPDATE vicidial_list
SET status = 'SKIP'
WHERE list_id = 101
AND (date_last_call < DATE_SUB(NOW(), INTERVAL 30 DAY)
OR date_last_call IS NULL);
Apply changes from the command line
mysql -u root -p asterisk -e "UPDATE vicidial_list SET status = 'SKIP' WHERE list_id = 101 AND status = 'ACTIVE';"
Run this command with proper escaping if you are inside a shell script.
Method 3: Delete leads permanently
Permanent deletion removes the record from the database entirely. Use this only when required by compliance (e.g., GDPR requests) or for test data cleanup. Deleted leads cannot be recovered without a backup restore.
Delete all leads from a specific list
DELETE FROM vicidial_list
WHERE list_id = 101;
This is irreversible. Confirm you have a backup first.
Delete leads matching a phone pattern
DELETE FROM vicidial_list
WHERE list_id = 101
AND phone_number LIKE '555%';
Delete leads created before a specific date
DELETE FROM vicidial_list
WHERE list_id = 101
AND date_created < '2023-01-01 00:00:00';
Delete by vendor_lead_id (external reference)
If you receive a deletion request with an external ID:
DELETE FROM vicidial_list
WHERE vendor_lead_id = 'EXT_ID_12345'
AND list_id = 101;
Verify deletion count before executing
Preview how many rows will be affected without deleting:
SELECT COUNT(*) FROM vicidial_list
WHERE list_id = 101
AND phone_number LIKE '555%';
Method 4: Reset the status of already-dialed leads
Leads with statuses like CALLED, LEFT MESSAGE, or NO ANSWER can be reset to ACTIVE to allow re-dialing. This is common after a dialer issue or when campaign rules change.
Reset all leads with a final status back to ACTIVE
UPDATE vicidial_list
SET status = 'ACTIVE',
date_last_call = NULL
WHERE list_id = 101
AND status IN ('CALLED', 'NO ANSWER', 'LEFT MESSAGE', 'TRANSFER', 'DROP', 'DEAD');
Setting date_last_call to NULL tells ViciDial to treat these as untouched, allowing them back into the dialing queue.
Reset leads with retry logic (less aggressive)
Keep the date_last_call but change status to ACTIVE:
UPDATE vicidial_list
SET status = 'ACTIVE'
WHERE list_id = 101
AND status IN ('NO ANSWER', 'LEFT MESSAGE');
This preserves the call history while allowing re-attempt. ViciDial will respect call-throttling rules based on date_last_call.
Method 5: Remove duplicates by phone number
Duplicate phone numbers in a list consume dialer resources and may irritate leads. Identify and remove them:
Find duplicate phone numbers
SELECT phone_number, COUNT(*) as count
FROM vicidial_list
WHERE list_id = 101
GROUP BY phone_number
HAVING COUNT(*) > 1
ORDER BY count DESC;
Delete duplicates, keeping the oldest (by lead_id)
DELETE FROM vicidial_list
WHERE lead_id NOT IN (
SELECT MIN(lead_id) FROM (
SELECT MIN(lead_id)
FROM vicidial_list
WHERE list_id = 101
GROUP BY phone_number
) AS keep_leads
)
AND list_id = 101;
This query is memory-intensive on very large lists. For lists with 500k+ leads, delete in batches.
Delete duplicates in batches (safer for large lists)
DELETE FROM vicidial_list
WHERE lead_id IN (
SELECT lead_id FROM vicidial_list
WHERE list_id = 101
GROUP BY phone_number
HAVING COUNT(*) > 1
LIMIT 1000
);
Run this several times until no duplicates remain.
Method 6: Purge leads tied to a specific campaign
If an entire campaign is ending or corrupted, remove all associated leads:
SELECT list_id FROM vicidial_lists WHERE campaign_id = 'CAMPAIGN_123';
Then delete all leads from those lists:
DELETE FROM vicidial_list
WHERE list_id IN (
SELECT list_id FROM vicidial_lists WHERE campaign_id = 'CAMPAIGN_123'
);
This removes the leads but keeps the list definitions. The list is now empty and ready for new leads.
Why does ViciDial mark calls as DEAD?
ViciDial marks a lead DEAD when the dialer encounters a disconnected number, invalid area code, or unrecoverable phone error in three or more consecutive attempts. Once status is DEAD, the dialer skips that lead. Check the vicidial_closer_log table for the reason codes associated with those calls. DEAD status is a safety mechanism to save dialer resources.
How to reload the dialer after bulk changes
After updating the vicidial_list table via SQL, the running dialer process may not see the changes immediately. Stop and restart the dialer:
/usr/share/astguiclient/VICIDIAL_restart_dialer.pl
Or restart the entire ViciDial service:
systemctl restart vicidial
Check that the dialer is running:
ps aux | grep -i dialer
The process vicidial_auto_dial.pl should be active. If not, check /var/log/astguiclient/DIALER_DIE.log for errors.
Handling agent callbacks and manual dials
Leads with status CALLBACK or MANUAL are set aside for agent recall. Changing their status requires care:
Convert pending callbacks to SKIP
Callbacks scheduled but never dialed can be skipped:
UPDATE vicidial_list
SET status = 'SKIP'
WHERE list_id = 101
AND status = 'CALLBACK'
AND date_last_call < DATE_SUB(NOW(), INTERVAL 7 DAY);
This preserves recent callbacks but removes stale ones.
Remove leads in the DNC (do not call) list
ViciDial maintains a separate vicidial_dnc_list table. If a lead is added to the DNC list, it will not be called even if status is ACTIVE:
SELECT * FROM vicidial_dnc_list
WHERE phone_number = '5551234567';
To remove a number from DNC:
DELETE FROM vicidial_dnc_list
WHERE phone_number = '5551234567';
Troubleshooting
Problem: Leads are still being called after I set status to SKIP
The dialer process may have cached the list in memory. Run:
/usr/share/astguiclient/VICIDIAL_restart_dialer.pl
Then monitor /var/log/astguiclient/dialer_log.txt to confirm the dialer reloaded the list:
tail -f /var/log/astguiclient/dialer_log.txt | grep "Loading list"
Problem: delete failed with "Lock wait timeout exceeded"
The database has a lock from another process. Check for long-running queries:
SHOW PROCESSLIST;
Kill the blocking query (replace PID with the process ID):
KILL PID;
Then retry the delete. For large deletes, increase innodb_lock_wait_timeout in /etc/my.cnf:
[mysqld]
innodb_lock_wait_timeout = 120
Restart MySQL and retry.
Problem: I want to undo a bulk delete
If the delete was recent (minutes ago), restore from backup:
mysql -u root -p asterisk < /backup/vicidial_list_20240115_143022.sql
If the backup is older, you may recover deleted records from binary logs. Contact your DBA.
Problem: Leads disappear from reports after deletion
Once a lead_id is deleted from vicidial_list, any associated records in vicidial_closer_log or vicidial_dnc_list are orphaned. The reports may break if they join on lead_id. Before deleting, export those records to audit tables:
CREATE TABLE vicidial_list_deleted_backup LIKE vicidial_list;
INSERT INTO vicidial_list_deleted_backup
SELECT * FROM vicidial_list
WHERE list_id = 101
AND status = 'DROP';
Then delete from the live table. The backup table preserves the data for forensics.
Problem: reset or delete query is very slow
Large tables (millions of rows) may lock the database during an UPDATE or DELETE. Use pt-online-schema-change or batch the operation:
for i in {1..100}; do
mysql -u root -p asterisk -e "DELETE FROM vicidial_list WHERE list_id = 101 AND status = 'DROP' LIMIT 10000;"
sleep 2
done
This deletes in chunks of 10,000 every 2 seconds, avoiding lock timeouts.
Frequently asked questions
Can I restore deleted leads from ViciDial?
No. Once a lead is deleted from vicidial_list, it cannot be recovered unless you restore the entire database from a backup. ViciDial does not maintain a soft-delete or trash mechanism. Always export or back up before deleting production data.
What status should I use: SKIP, DROP, or DEAD?
SKIP prevents re-dialing but keeps the record visible in reports and list tools. DROP removes the lead from the active dialing pool but preserves the database row. DEAD is assigned automatically by the dialer when a number is confirmed unreachable. For manual removal, use SKIP or DROP depending on whether you want to preserve reporting data.
How long does it take to reset 100,000 leads?
A simple status update on 100k leads typically completes in 5-30 seconds, depending on your database server's disk speed and load. A DELETE operation on the same set may take 2-5 minutes because the database must also free table space and update indexes. Test on a replica or during low-traffic hours.
Can I schedule automatic list cleanup or lead expiration?
Yes. Create a cron job that runs a cleanup script:
0 2 * * * mysql -u root -p asterisk -e "UPDATE vicidial_list SET status = 'DROP' WHERE date_last_call < DATE_SUB(NOW(), INTERVAL 90 DAY) AND status = 'NO ANSWER';" >> /var/log/vicidial_cleanup.log 2>&1
This runs at 2 AM daily and marks No Answer leads older than 90 days as DROP. Adjust the interval and status values to match your campaign rules.
How do I bulk import and re-dial a previously failed list?
Export the list to CSV, modify the status column to ACTIVE, and re-import via the admin panel. Or, run a targeted reset:
UPDATE vicidial_list SET status = 'ACTIVE', date_last_call = NULL WHERE list_id = 101 AND date_created > '2024-01-01';
Set date_last_call to NULL to treat leads as untouched. The dialer will respect call-throttle settings and call them again.
Summary
ViciDial lead management involves four primary actions: deactivation (changing status to SKIP or DROP via the admin panel or SQL), resetting the call history of already-dialed leads, removing duplicates, and permanent deletion. The method chosen depends on scale and compliance requirements. For batch operations and production campaigns, direct SQL queries on vicidial_list are faster than the web UI but require a backup first and a dialer restart afterward. Always verify row counts with a SELECT query before executing DELETE, and batch large deletions in chunks to avoid database lock timeouts. After any bulk change, restart the dialer process and monitor the dialer_log.txt to confirm the list reloaded. Preserving audit tables and backups protects against accidental data loss and supports regulatory compliance.