← All Tutorials

How to Manage ViciDial Lists: Deactivate, Reset and Delete Leads

ViciDial Administration Intermediate 11 min read #100 Published · Updated

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

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.

  1. Open http://your-server/vicidial/admin.php
  2. Go to Admin > Leads > Search
  3. Select your list_id from the dropdown
  4. Filter by phone number, vendor_lead_id, or status
  5. Click the checkboxes next to leads you want to modify
  6. Select Change Status from the bulk action menu
  7. Set the new status to SKIP (not yet dialed again) or DROP (remove from pool entirely)
  8. 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:

  1. Go to Admin > Campaign and select your campaign
  2. Scroll to List Management
  3. Click Reset List Status
  4. Choose the new status from the dropdown
  5. 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.

Stuck on something specific?

Book a free 30-minute call. I run ViciDial centers across 3 countries and can usually unblock your setup in one session — or build it for you.

Book a Free Consultation