← All Tutorials

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

ViciDial Administration Intermediate 15 min read #100 Published · Updated

Learn to deactivate inactive leads, reset call counts, purge bad data, and safely delete lists without breaking agent workflows or violating call compliance rules.

Prerequisites

You need the following to work through this guide:

If you're running ViciDial in Docker or a custom build, adjust paths accordingly. This guide assumes a standard Linux installation at /var/www/html/vicidial/ with MySQL at localhost.

Understanding ViciDial list states and the lead lifecycle

Before you modify or delete leads, understand how ViciDial tracks them.

Lead statuses in vicidial_list table

The vicidial_list table stores all contacts. The status column determines what happens to each lead:

Each status flows through your dialplan. Understanding which status blocks dialing prevents accidents when you reset or deactivate in bulk.

The difference between reset, deactivate, and delete

Reset: Changes status back to NEW, clears phone attempts, lets dialer call again. Useful for bad data or testing.

Deactivate: Changes status to INACTIVE. Dialer never calls it. Phone remains in list. Useful for GDPR/TCPA compliance or known bad numbers.

Delete: Removes the row from vicidial_list entirely. Cannot be undone without backup. Use only for test data or spam.

Deleting is irreversible. Deactivation is safer. Reset is reversible if you have transaction logs.

Method 1: Deactivate leads via the web admin interface

The safest method for small batches is the ViciDial admin panel.

Access the admin panel and locate list management

Open your browser and navigate to your ViciDial admin URL. It is usually:

http://<your-vicidial-server>/vicidial/admin.php

Log in with an admin account. From the left sidebar, find "Manage Lists" or "List Management".

Filter leads by status or criteria

On the List Management page, select your list from the dropdown. Then set filters:

Apply the filter. The page displays matching leads.

Bulk deactivate from the interface

Select the checkbox "Select all visible" at the top of the results table. A dropdown menu appears offering actions:

Choose "Change Status" and select INACTIVE from the submenu. A confirmation page appears. Review the count of affected leads. Click Confirm.

The status change is immediate. No database restart needed.

This method is slow for lists larger than a few thousand leads because the web interface processes one page at a time. For large lists, use SQL directly.

Method 2: Reset and deactivate leads using direct SQL commands

SQL is faster and more precise. This is the method used in production for nightly bulk operations.

Connect to the vicidial database

SSH into your ViciDial server and access MySQL:

mysql -u root -p asterisk

When prompted, enter your MySQL root password. You see the mysql> prompt.

Verify you are in the asterisk database:

SELECT DATABASE();

Output should show asterisk. If not, run:

USE asterisk;

Deactivate leads by status

To mark all NEW leads in a specific list as INACTIVE:

UPDATE vicidial_list
SET status = 'INACTIVE'
WHERE list_id = '101'
AND status = 'NEW';

Check the result. MySQL returns the number of rows affected. If the count seems wrong, run a SELECT first to preview:

SELECT COUNT(*) FROM vicidial_list
WHERE list_id = '101'
AND status = 'NEW';

This query counts without changing data. Run it before the UPDATE to make sure your WHERE clause is correct.

Deactivate by last call date

To deactivate leads that were never called or not called in the last 90 days:

UPDATE vicidial_list
SET status = 'INACTIVE'
WHERE list_id = '101'
AND (last_local_call_time IS NULL
OR last_local_call_time < DATE_SUB(NOW(), INTERVAL 90 DAY));

This helps clean up stale leads without removing them from the database.

Reset leads back to NEW status

To reset all ACTIVE leads in a list back to NEW so they can be dialed again:

UPDATE vicidial_list
SET status = 'NEW',
    call_count = 0,
    last_local_call_time = NULL
WHERE list_id = '101'
AND status = 'ACTIVE';

Setting call_count to 0 tells the dialer this lead has never been attempted. The dialer will call it as a fresh lead. Be cautious: if agents see the same person twice, they may hang up or complain.

Reset leads with a specific phone number or pattern

To reset all leads with a phone number matching a pattern:

UPDATE vicidial_list
SET status = 'NEW',
    call_count = 0
WHERE list_id = '101'
AND phone_number LIKE '555%';

This is useful if you know a phone number range was entered incorrectly or is no longer valid for calling.

Check changes before committing

If you want to preview changes without applying them, wrap the command in a transaction:

START TRANSACTION;

UPDATE vicidial_list
SET status = 'INACTIVE'
WHERE list_id = '101'
AND status = 'NEW';

SELECT COUNT(*) FROM vicidial_list WHERE list_id = '101' AND status = 'INACTIVE';

ROLLBACK;

The ROLLBACK undoes the change. Run the same query with COMMIT instead of ROLLBACK to apply permanently.

Method 3: Delete leads and entire lists

Deletion is permanent. Back up first.

Backup the vicidial_list table before deletion

From the bash prompt, create a SQL dump:

mysqldump -u root -p asterisk vicidial_list > vicidial_list_backup_$(date +%Y%m%d_%H%M%S).sql

Enter your MySQL password. A file is created with a timestamp. Store this somewhere safe, not on the same disk as the database.

Delete individual leads by phone number

To delete a specific phone number from a list:

DELETE FROM vicidial_list
WHERE list_id = '101'
AND phone_number = '5551234567';

MySQL reports how many rows were deleted. If zero rows were deleted, the phone number did not exist in that list.

Delete all leads in a list

To delete every lead in a list:

DELETE FROM vicidial_list
WHERE list_id = '101';

This removes all contacts. The list itself remains in the vicidial_lists table and can be imported again.

Delete leads by status

To delete only INACTIVE leads to reclaim space:

DELETE FROM vicidial_list
WHERE list_id = '101'
AND status = 'INACTIVE';

This is useful for removing do-not-call contacts or cleaned-up data.

Verify deletion and check referential integrity

After deletion, confirm the list count:

SELECT COUNT(*) FROM vicidial_list WHERE list_id = '101';

Check if any orphaned records exist in vicidial_log (the call history table):

SELECT COUNT(*) FROM vicidial_log
WHERE list_id = '101'
AND lead_id NOT IN (SELECT lead_id FROM vicidial_list);

If this count is non-zero, you have call records for leads that no longer exist. This is harmless but leaves dead data. To clean it:

DELETE FROM vicidial_log
WHERE list_id = '101'
AND lead_id NOT IN (SELECT lead_id FROM vicidial_list);

Method 4: Reset leads using the CLI tools

ViciDial ships with command-line scripts in /usr/share/astguiclient/. Use these for automation in cron jobs.

List available CLI tools

Navigate to the tools directory:

ls -la /usr/share/astguiclient/ | grep -E '\.pl$'

You see Perl scripts. The main ones for list management are:

Run ADMIN_reset_list.pl to reset call counts

This script resets the call_count field for all leads in a list:

/usr/share/astguiclient/ADMIN_reset_list.pl --list-id 101

The script does not prompt. It immediately resets. Output is minimal. To see what it does, run with verbose flag if supported:

perl /usr/share/astguiclient/ADMIN_reset_list.pl --list-id 101 --verbose

Check the /var/log/astguiclient/ logs to see what was executed:

tail -f /var/log/astguiclient/ADMIN_reset_list.log

Logs are not always written, so check the database to confirm:

SELECT COUNT(*), AVG(call_count), MAX(call_count) FROM vicidial_list WHERE list_id = '101';

If all call_count values are now 0 or lower than before, the reset worked.

Schedule list resets in cron

To reset a list every night at 2 AM:

crontab -e

Add this line:

0 2 * * * /usr/share/astguiclient/ADMIN_reset_list.pl --list-id 101 >> /var/log/astguiclient/cron_reset.log 2>&1

Save and exit. The script runs daily. Check the log file to confirm success:

tail /var/log/astguiclient/cron_reset.log

Method 5: Bulk import status changes from CSV

If you have a list of lead IDs and new statuses in a spreadsheet, import them via CSV.

Prepare the CSV file

Create a CSV with three columns: list_id, lead_id, status.

list_id,lead_id,status
101,50001,INACTIVE
101,50002,INACTIVE
101,50003,NEW
102,50100,HOLD

Save as leads_update.csv.

Use ADMIN_phonebook_manager.pl to import

The phonebook manager script can import and update leads:

/usr/share/astguiclient/ADMIN_phonebook_manager.pl \
  --import-csv leads_update.csv \
  --action update

Check the output for errors. If successful, verify in the database:

SELECT lead_id, status FROM vicidial_list WHERE lead_id IN (50001, 50002, 50003);

If the script fails or is unavailable in your version, fall back to writing a bash loop that runs SQL UPDATE statements for each row.

Bash loop for CSV import

Create a file update_leads.sh:

#!/bin/bash

while IFS=',' read -r list_id lead_id status; do
  if [ "$list_id" != "list_id" ]; then
    mysql -u root -p'yourpassword' asterisk -e \
      "UPDATE vicidial_list SET status='$status' WHERE list_id=$list_id AND lead_id=$lead_id;"
  fi
done < leads_update.csv

echo "Import complete."

Make it executable:

chmod +x update_leads.sh
./update_leads.sh

This updates the database row by row. It is slower than a single SQL statement but works when the CLI tools are missing or incompatible.

Managing list state during agent campaigns

Agents dial from lists. If you modify a list while agents are on calls, cache inconsistencies can occur.

Pause the dialer before bulk changes

To stop the dialer from assigning new leads:

Log into the admin panel and navigate to Campaign Management. Find your campaign and click Pause. The dialer stops pulling new leads from queues. Agents on active calls continue.

Wait for current calls to finish or hang them up manually. Then run your SQL updates. Finally, Resume the campaign.

Alternatively, from the CLI, check the status using Asterisk:

asterisk -rx "vicidial show dialers"

This shows active dialers. If your ViciDial version supports it, you can restart the dialer:

service vicidial restart

This stops all campaigns. Agents are logged out. Campaigns resume after restart.

Clear the agent session cache

If an agent remains logged in after you modify a list, their local cache may be stale. Force a logout:

UPDATE vicidial_users SET logged_in = 0 WHERE user='agentname';

The agent must log back in. On login, they fetch fresh list data.

Monitor lead assignment with vicidial_log

After resuming campaigns, check that leads are being called:

SELECT DATE(call_date), COUNT(*) FROM vicidial_log
WHERE list_id = '101'
AND call_date > DATE_SUB(NOW(), INTERVAL 1 HOUR)
GROUP BY DATE(call_date);

This shows calls in the last hour grouped by date. If the count is zero or very low, the dialer may not be working correctly.

Compliance and audit trails

Deactivating or deleting leads must be logged for GDPR, TCPA, or internal policy compliance.

Log all manual changes to a separate table

Create an audit table to track who changed what:

CREATE TABLE IF NOT EXISTS vicidial_lead_audit (
  audit_id INT AUTO_INCREMENT PRIMARY KEY,
  timestamp TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
  changed_by VARCHAR(50),
  list_id INT,
  lead_id INT,
  old_status VARCHAR(20),
  new_status VARCHAR(20),
  reason TEXT
);

Before running a bulk UPDATE, log it:

INSERT INTO vicidial_lead_audit (changed_by, list_id, old_status, new_status, reason)
SELECT 'admin', list_id, status, 'INACTIVE', 'Stale leads, not called in 90 days'
FROM vicidial_list
WHERE list_id = '101'
AND status = 'NEW'
AND (last_local_call_time IS NULL OR last_local_call_time < DATE_SUB(NOW(), INTERVAL 90 DAY));

UPDATE vicidial_list
SET status = 'INACTIVE'
WHERE list_id = '101'
AND status = 'NEW'
AND (last_local_call_time IS NULL OR last_local_call_time < DATE_SUB(NOW(), INTERVAL 90 DAY));

Query the audit table to see all changes:

SELECT * FROM vicidial_lead_audit ORDER BY timestamp DESC LIMIT 100;

Export a compliance report

Before deactivating a large batch, export the affected leads:

mysql -u root -p asterisk -e \
  "SELECT lead_id, phone_number, status, last_local_call_time FROM vicidial_list WHERE list_id='101' AND status='NEW';" \
  > leads_to_deactivate_$(date +%Y%m%d).csv

Store this file with your compliance records. It proves which numbers you stopped calling and when.

Troubleshooting

Problem: Leads still appear in agent screen after marking INACTIVE

Cause: Agent session cache not cleared. Dialer or agent application is cached.

Solution: Log the agent out or force a session refresh:

UPDATE vicidial_users SET logged_in = 0 WHERE user='agentname';
UPDATE vicidial_user_sessions SET session_alive = 'N' WHERE user='agentname';

Kill the agent's PHP session on the web server:

rm -f /tmp/vicidial_sessions/*agentname*

Have the agent log out and back in. The agent screen refreshes list data on login.

Problem: Call counts are not resetting

Cause: The status is being changed but call_count field is not cleared, or the dialer is not picking up the reset.

Solution: Manually clear call_count:

UPDATE vicidial_list SET call_count = 0 WHERE list_id = '101' AND status = 'NEW';

Restart the dialer process:

service vicidial restart

Verify the change with a SELECT:

SELECT lead_id, call_count, status FROM vicidial_list WHERE list_id = '101' LIMIT 5;

Problem: Deletion query takes too long and locks the database

Cause: vicidial_list is large (100K+ rows) and the DELETE statement is blocking other queries.

Solution: Delete in smaller batches:

DELETE FROM vicidial_list WHERE list_id = '101' AND status = 'INACTIVE' LIMIT 10000;

Run this repeatedly until all rows are gone. Check progress:

watch -n 5 "mysql -u root -p'password' asterisk -e 'SELECT COUNT(*) FROM vicidial_list WHERE list_id=101;'"

This command refreshes every 5 seconds, showing the row count shrinking.

Alternatively, use the ADMIN tools:

/usr/share/astguiclient/ADMIN_archiver.pl --archive-list-id 101

This archives and removes old list data without locking the live table.

Problem: MySQL error "Duplicate entry" when importing CSV

Cause: A lead_id already exists in the list and you are trying to insert instead of update.

Solution: Use INSERT...ON DUPLICATE KEY UPDATE:

INSERT INTO vicidial_list (list_id, lead_id, phone_number, status)
VALUES (101, 50001, '5551234567', 'NEW')
ON DUPLICATE KEY UPDATE status = 'NEW';

This updates the status if the lead exists, or inserts if it does not.

Problem: Asterisk logs show "Unknown lead" errors after deletion

Cause: The dialer assigned a lead_id that no longer exists in vicidial_list, then the agent tried to call it.

Solution: Check for gaps in lead_id assignment:

SELECT COUNT(*) FROM vicidial_log WHERE list_id = '101' AND lead_id NOT IN (SELECT lead_id FROM vicidial_list);

If the count is high, orphaned log records exist. Clean them:

DELETE FROM vicidial_log WHERE list_id = '101' AND lead_id NOT IN (SELECT lead_id FROM vicidial_list);

Then restart the dialer to reload the list:

service vicidial restart

Problem: Web admin interface hangs when loading a large list

Cause: The list has millions of leads and the admin page tries to display them all.

Solution: Do not use the web interface. Use SQL or CLI tools instead.

For viewing, add a LIMIT to the SQL query:

SELECT * FROM vicidial_list WHERE list_id = '101' LIMIT 100;

To deactivate, use SQL directly, not the web admin.

Summary

You now know five methods to manage ViciDial lists in production: the web admin interface, direct SQL, CLI tools, CSV import, and batch scripting. The safest approach for small changes is the admin panel. For large bulk operations, SQL is faster and less error-prone.

Before making any change to a production list, back up the vicidial_list table. Deactivation is safer than deletion because it preserves the lead record. Reset call_count and status only when you intend for leads to be dialed again. Always pause campaigns or log out agents before bulk modifications to avoid cache conflicts.

Log all major changes to an audit table for compliance. Monitor the vicidial_log table after changes to confirm the dialer is working. If locks or slowdowns occur, use batch deletes with LIMIT or the ADMIN archiver tool.

Test all changes on a non-production list first. Check the database directly with SELECT queries before running UPDATE or DELETE statements. Verify agent screens reflect changes after modifications are complete. If issues arise, check the Asterisk logs at /var/log/asterisk/messages and the ViciDial CLI logs at /var/log/astguiclient/.

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