Reader setup
Before you evaluate
Use this to set expectations, limits and implementation boundaries before changing anything.
- A running VICIdial install holding an approved inactive synthetic list
- Read-only database access — see vicidial-read-only-database-account if you do not have one yet
- The target VICIdial revision, which the Admin screen prints as its VERSION and BUILD line
- What you will prove
- A documented custom-field test plan and verified schema boundary.
- Safety boundary
- This article never authorizes production schema or lead changes.
Reader path
How to use this article
- Use it when: You are designing a change and want reliable limits before implementation.
- Expected result: Separate what is known, unknown, and unsafe before you execute.
- Start here: Use it as an evidence review before changing architecture, security, or reporting behavior.
Start with the list, not a guessed column
Fast answer: each VICIdial list (a named lead collection) can have one custom-field set, with definitions in vicidial_lists_fields and values in a dynamically created custom_<list_id> table. An API is an application programming interface: inspect both tables on the target before reading, importing, or changing data.
This is a schema decision deep dive, not an exact Admin UI how-to. Names, types, options and defaults are generated at runtime, and the demonstrated system has source support but its custom-fields feature flag is disabled. Source presence is evidence of implementation, not proof that a target has enabled or configured it.
Terms are defined in vicidial-terminology-for-complete-beginners.
- Prerequisite: use an authorized read-only database account and an inactive synthetic test list.
- Non-goal: do not alter production definitions, values, imports or schema from this article.
- Record revision, database engine/version, timezone and authorized test-list ID.
- Capture sanitized SHOW CREATE TABLE and SHOW INDEX output.
Visual walkthrough
Follow three real demo screens
Captured on an isolated VICIdial demo: Administration screens on September 24, 2026, and the idle Agent screen on August 11, 2026. Each caption states its own capture time, and every sanitized image helps you recognize a related screen; none proves that this article's call, command, or result occurred.Identify the owning campaign

Find the Lists workspace

Inspect one list without opening a lead

Design fields as an interface contract
Choose stable field names, bounded values and explicit required/default behavior before an import template or downstream integration exists. A label is for people; a field name becomes a dependency for loaders, forms, exports and any approved API client.
Use the card below in a change ticket before creating a test field. FIELD_NAME is a stable machine-readable name, TYPE is the approved input type, and SENSITIVE is a data-classification decision. Success is a complete, owner-approved card; a blank owner, retention rule or allowed value means stop before configuration.
Avoid placing secrets, payment data, health data or free-form sensitive notes into call URLs or casually exported custom fields. Document ownership, retention and masking before a field becomes operationally relied upon.
- Validate label, field name, type, options, length and default in a test list.
- Test agent display and approved webform/script consumers.
- Have the privacy owner approve any sensitive-data purpose.
FIELD_NAME: preferred_contact_windowTYPE: SELECTALLOWED_VALUES: morning | afternoonSENSITIVE: noOWNER: operationsRETENTION: approved policy referenceThis sample is a template or reading aid, not a terminal command. There is no output to show.
- Before you run it
- Copy into the test-list change ticket; replace each all-caps label with an approved non-sensitive value.
- Success looks like
- Every field has a type, owner and retention decision.
- Stop if
- Stop and escalate when any value, owner or retention rule is unknown.
Prove the write path with synthetic data
Use the documented Non-Agent API function and target revision rather than constructing parameter names from a database column. API behavior, permissions and output modes vary by function; a successful HTTP response is not enough evidence of the intended custom-field write.
Start on an inactive test list with a synthetic lead, then verify the standard lead record, the matching custom row and the agent-facing result. URL-encode values at the client boundary and treat plain-text ERROR responses as failures even when a requested format is JSON.
SHOW CREATE TABLE vicidial_lists_fields;SHOW CREATE TABLE custom_<LIST_ID>;SHOW INDEX FROM custom_<LIST_ID>;Captured demo response · 2026-09-24 22:25 UTC. The displayed command is the command that ran; a safe subset label means it was filtered, redacted, or fixture-scoped. Replays only after you select Replay transcript.
- Before you run it
- Run through the read-only credential file (mysql --defaults-extra-file=/etc/vicidial-readonly.cnf -e "..."; see vicidial-read-only-database-account if you do not have one yet); replace <LIST_ID> with its approved numeric list ID.
- Success looks like
- The custom table definition and indexes match the approved test-field design.
- Stop if
- Stop if the table is absent, belongs to another list, or differs from the plan.
Make list copies and renumbers real migrations
Copying a list or changing its list ID changes the schema relationship as well as lead membership. Inventory definitions, values, import mappings, exports, callbacks, campaign eligibility and any external consumer before moving a production population.
Build a deterministic mapping from old list and field names to new list and field names. Rehearse the mapping on synthetic data, compare non-sensitive counts and field null rates, and stop if the target schema differs from the approved plan.
- Freeze or isolate the test population during the rehearsal.
- Validate an import, an API update and an agent edit after migration.
- Keep the original list untouched until acceptance is complete.
Back up both halves and define the stop point
A lead-table backup without the dynamic table, definitions and mappings is incomplete. Take a restorable, access-controlled backup and verify restoration into an isolated environment before a broad alteration or migration.
Stop and roll back when schema comparison, expected counts, sample reads or agent rendering disagree. Independent verification means a reviewer who did not perform the change compares the approved mapping, backup evidence and sanitized before/after totals.
- Include definitions, custom tables and relevant loader mappings in backup scope.
- Record evidence state: source present, demo enabled/disabled, or independently tested.
- Run equivalent tests on every production revision and list family before rollout.
Evidence ledger
Verification basis
- In this lab, custom fields are list-scoped dynamic tables (vicidial_lists_fields plus custom_<list_id>); the feature was present but not enabled at the time of writing.
- No production custom-field rows, credentials, backups or migration result counts were reviewed for this article.
Primary references
Sources
- VICIdial Custom FieldsVICIdial · accessed September 23, 2026
- VICIdial Non-Agent APIVICIdial · accessed September 23, 2026