6.1 Overview

The Contacts section stores the people and organizations that may be called, messaged, enrolled in Campaigns, added to follow-up Sequences, or reviewed through Analytics.

The Contact-management workflow includes:

Creating Contacts
Editing Contact information
Viewing Contact activity
Click-to-call
Contact Lists
Contact Tags
CSV imports
CSV exports
Phone-number validation
AI-assisted data-quality review
Duplicate detection
Engagement scoring
Smart Scheduling information
Bulk management routes

The recommended Contact-data process is:

Collect approved Contact information
Format telephone numbers
Import or create Contacts
Review duplicates and data quality
Organize with Lists and Tags
Confirm consent and suppression status
Use in Calling Sessions or Campaigns
Update outcomes and follow-up information

The current application provides standard browser routes for Contacts, Lists, Tags, imports, exports, Phone validation, and calling sessions, along with API routes for bulk operations and data-quality analysis.

Contact Terminology

6.2 Master Contact

A Contact is the reusable master record for a person or organization.

A master Contact can be connected to:

Multiple Campaigns
Multiple Contact Lists
Multiple Contact Tags
Calls
Follow-up Sequences
CRM integrations
Smart Scheduling

6.3 Campaign Contact

A Campaign Contact represents a Contact’s participation in one specific Campaign.

Master Contact:
Reusable person or organization

Campaign Contact:
Campaign-specific copy or participation record

Campaign-specific status, Notes, attempts, and results can differ from the master Contact.

6.4 Contact List

A Contact List is a reusable group of Contacts.

Examples:

Current Customers
New Prospects
Detroit Leads
Webinar Registrants
August Follow-Up
Renewal Customers

A Contact can belong to more than one List.

6.5 Contact Tag

A Contact Tag is a reusable label.

Examples:

VIP
Spanish Speaking
Decision Maker
Requested Callback
Interested in Product A
Trade Show Lead

Tags provide flexible classification, while Lists are generally used as structured groups.

6.6 Status Versus Opt-Out

A Contact contains both:

Status
and
Opted-Out state

These values are separate.

Supported Contact Status values are:

active
inactive
blocked

The Contact can also contain:

opted_out = true or false
opted_out_at = date and time

A Contact should not be called merely because its Status says Active when it has separately opted out.

Contact Record Fields

6.7 Identity Fields

The Contact model can store:

First Name
Last Name
Phone Number
Email Address
Company
Job Title

6.8 Website and Social Fields

The model also supports:

Website
Facebook URL
Instagram URL
LinkedIn URL
X or Twitter URL

6.9 Communication Fields

Additional fields include:

Notes
Time Zone
Language
Custom Fields
Source

6.10 Operational Fields

The system can track:

Status
Opted-Out state
Opted-Out date
Total Campaigns
Total Calls
Successful Calls
Last Contacted At
Engagement Score

6.11 Quality and Scheduling Fields

The model can also store:

Data Quality Score
Quality Issues
AI Suggestions
Manually Verified
Quality Checked At
Optimal Call Time
Optimal Call Confidence
Best Call Hours

Not every stored field is displayed by the current Contact interface.

6.12 Contact Name Fallback

When neither First Name nor Last Name is present, the model’s full-name helper returns:

Unknown

The normal browser create form currently requires both First Name and Last Name, even though the backend model permits blank names.

Opening Contacts

6.13 Contacts Page

To open Contacts:

  1. Sign in.
  2. Open Contacts in the Sidebar.
  3. Select All Contacts.
  4. Wait for the Contact table to load.

The page address is:

/contacts

6.14 KYC Requirement

Normal Contact-management routes are inside the Basic KYC-protected area.

A Customer generally requires:

Approved Basic or Business KYC

when KYC is globally enabled.

6.15 Permission Requirements

Common Contact permissions include:

contacts.view
contacts.create
contacts.edit
contacts.delete
contacts.import
contacts.export

A user may be able to view Contacts without being permitted to create, edit, delete, import, or export them.

Contact Ownership

6.16 Administrator Scope

Administrators can generally view Contacts across the platform.

6.17 Customer Scope

A Customer normally sees Contacts whose:

user_id = Customer User ID

6.18 Agent Scope

An Agent’s normal Contact list uses:

user_id = Agent’s parent Customer ID

This allows the Agent to view the parent Customer’s Contact records.

6.19 Agent Restrictions

The Contact policy currently prevents an Agent from:

Editing Contacts
Deleting Contacts

even when the Agent can view and call the parent Customer’s Contacts.

6.20 Agent Creation Behavior

The ordinary Contact create action stores a Contact under the parent Customer when the signed-in user is an Agent.

This keeps manually created Agent Contacts visible in the shared Customer workspace.

The CSV import process currently behaves differently and is discussed later in this chapter.

Contacts Page Controls

6.21 Primary Actions

The Contacts page contains controls for:

Contacts Help
Start Calling
Check Valid Numbers
Import
Add Contact
Search

6.22 Contacts Help

The Help action explains basic Contact-management concepts within the interface.

It does not modify Contact data.

6.23 Start Calling

Start Calling opens the Contact Calling Session.

The session provides a guided one-at-a-time Contact workflow.

6.24 Check Valid Numbers

Check Valid Numbers examines every Contact Phone Number in the current owner’s Contact collection.

It does not validate only the rows visible on the current page.

6.25 Import

The Import action opens the Contact Import dialog.

The separate /contacts-import page currently redirects back to Contacts and instructs the user to use the integrated import feature.

6.26 Add Contact

Add Contact opens:

/contacts/create

Searching Contacts

6.27 Search Fields

The Contacts search can match:

First Name
Last Name
Email Address
Phone Number
Company

6.28 Running a Search

To search:

  1. Enter a Name, Email Address, Phone Number, or Company.
  2. Select Search or submit the search field.
  3. Review the filtered results.
  4. Clear the field and search again to return to all Contacts.

6.29 Partial Search

Search uses partial matching.

Examples:

Search:
Dan

Possible result:
Danielle Johnson

Search:
313555

Possible result:
+13135550198

6.30 Phone Formatting Differences

A search can be affected by:

Country code
Plus sign
Spaces
Parentheses
Hyphens

When an exact Phone Number does not match, search by a shorter numeric portion.

Contact List Filters

6.31 List Filter Chips

When Contact Lists exist, the page displays filters such as:

All Contacts
[List Name]
Not in any list

6.32 All Contacts

All Contacts removes the List-specific filter.

The number displayed on the chip is based on the currently returned Contact pagination total.

When another search is active, the value can represent the searched result rather than the complete Contact database.

6.33 Specific List

Selecting a List displays Contacts connected to that List.

6.34 Not in Any List

Selecting:

Not in any list

returns Contacts that currently have no Contact List assignment.

6.35 Pagination Filter Limitation

The current pagination action preserves the Search value but does not consistently preserve the selected Contact List filter.

After selecting another page, the view can return to All Contacts.

Confirm the active List chip after pagination.

Backend Filters Not Exposed in the Current Page

6.36 Additional Supported Filters

The Contact controller supports query filters for:

Status
Opted-Out state
Tag
List
Minimum Engagement Score
Sorting
Page size

The current main browser page visibly exposes only:

Search
Contact List

6.37 No Visible Status Filter

The current page does not provide a normal dropdown for:

Active
Inactive
Blocked

6.38 No Visible Opt-Out Filter

There is no visible main-page filter for:

Opted Out
Not Opted Out

6.39 No Visible Tag Filter

Existing Tags are not displayed as a main Contact filter in the current browser interface.

6.40 No Visible Engagement Filter

Although the backend can filter by a minimum Engagement Score, the main page does not expose that control.

Contacts Table

6.41 Table Columns

The current Contacts table displays:

Name
Phone
Email
Company
Website
Lists
Status
Actions

6.42 Name

The Name column combines:

First Name
+
Last Name

6.43 Phone

The Phone column displays the saved Phone Number.

Telephone numbers should be stored in E.164 format whenever possible.

6.44 Email

A blank Email Address is displayed as an empty or unavailable value.

Email is optional in the normal create form.

6.45 Company

Company is optional.

It can be used in Search and Campaign personalization.

6.46 Website

The Website value can open as an external link.

Confirm that the saved URL belongs to the intended organization before opening it.

6.47 Lists

The Lists column displays the Contact Lists assigned to the Contact.

A Contact can display more than one List.

6.48 Status

The Status column displays the stored Contact Status.

The table does not separately show the opted_out value.

A Contact can therefore appear Active in the table while having a separate opt-out flag.

6.49 Call Action

The Phone icon starts a Contact-aware calling workflow.

It is available only when the browser Softphone Device is registered.

Selecting the icon:

Loads the Contact into the Softphone
Loads the Phone Number
Expands the global Softphone
Prepares the Contact for click-to-call

The user must still select Call in the Softphone.

6.50 View Action

The Eye icon opens the Contact Details page.

6.51 No Direct Edit or Delete in the Row

The current main table does not display direct:

Edit
Delete

buttons in each row.

Open the Contact Details page to reach Edit.

A normal Delete control is not clearly exposed in the current browser workflow.

6.52 No Row Selection

The current main Contacts table does not display selection checkboxes.

Bulk backend routes exist, but the main browser table does not connect them to a visible bulk-action toolbar.

6.53 Hidden Information

The main table does not display:

Tags
Job Title
Notes
Time Zone
Language
Opt-Out date
Engagement Score
Data Quality Score
Optimal Call Time
Social profiles

Contact Pagination

6.54 Default Page Size

The Contacts page returns approximately:

25 Contacts per page

by default.

6.55 Page Controls

The interface displays page numbers near the current page.

Use the controls to move through the Contact collection.

6.56 No Page-Size Selector

The controller accepts a page-size parameter, but the current page does not provide a visible per-page selector.

Creating a Contact

6.57 Opening the Form

From Contacts, select:

Add Contact

The form opens at:

/contacts/create

6.58 Visible Contact Fields

The current create form contains:

First Name
Last Name
Phone Number
Email
Company
Website
Facebook
Instagram
LinkedIn
X or Twitter
Notes
Add to Lists

6.59 First and Last Name

The browser form requires both:

First Name
Last Name

The backend technically permits them to be blank, creating a current frontend-and-backend validation difference.

6.60 Phone Number

Phone Number is required.

The recommended format is:

+13135550198

The backend accepts an optional plus sign followed by up to 15 digits, with the first digit after the plus sign not equal to zero.

6.61 Global Phone Uniqueness

The database currently makes phone_number unique across the entire platform rather than unique within each Customer account.

This means two separate Customer accounts cannot normally create Contacts using the same Phone Number.

Possible error:

This phone number is already registered in the system.

This is a significant current multitenant limitation.

6.62 Email Address

Email is optional but must be valid when entered.

6.63 Website and Social URLs

Website and social fields must contain valid URLs when provided.

Recommended:

https://example.com

rather than:

example

6.64 Notes

Notes can contain information required for approved sales, service, or follow-up activity.

Do not store:

Passwords
API credentials
Full payment-card data
Authentication codes
Unnecessary sensitive personal data

6.65 Add to Lists

Select one or more existing Contact Lists.

The Contact is attached to those Lists after creation.

6.66 No Visible Tag Selection

The backend create action can accept Tag IDs, but the current create page does not display a Tag selector.

6.67 Fields Not Exposed by the Create Form

The current form does not provide controls for:

Job Title
Time Zone
Language
Status
Opted-Out state
Custom Fields
Source
Tags
Engagement Score
Quality information
Optimal Call Time

6.68 Saving the Contact

To create a Contact:

  1. Enter First Name.
  2. Enter Last Name.
  3. Enter an E.164 Phone Number.
  4. Add optional information.
  5. Select Contact Lists where required.
  6. Review consent and suppression requirements.
  7. Select Create Contact once.

6.69 Creation Result

On success, the application displays:

Contact created successfully.

and opens the Contact Details page.

6.70 Contact Source

A Contact created through the browser is assigned a source similar to:

manual

6.71 CRM Event

The standard create process can dispatch a Contact-added event for configured CRM integrations.

CSV imports currently follow a different processing path and may not dispatch the same event.

Cross-Account List and Tag Validation Limitation

6.72 Submitted IDs

The backend confirms that submitted List and Tag IDs exist.

It does not consistently verify that every submitted List or Tag belongs to the same Customer as the Contact.

Normal users should select only the Lists and Tags shown through their own interface and should never manipulate submitted IDs.

This ownership validation should be corrected for production multitenant security.

Viewing a Contact

6.73 Opening Contact Details

Select the Eye icon on the Contacts table.

The address is:

/contacts/[Contact ID]

6.74 Contact Header

The page displays:

Contact Name
Contact details
Contacts Help
Call Contact
Back
Edit

6.75 Call Contact

Call Contact loads the Contact into the global Softphone.

It is enabled when the Softphone Device is registered.

6.76 Contact Information

The Details page can display:

Phone Number
Email Address
Company
Website
Facebook
Instagram
LinkedIn
X or Twitter
Notes

6.77 Information Not Displayed

The current Details interface does not clearly display:

Status
Opted-Out state
Tags
Contact Lists
Job Title
Time Zone
Language
Custom Fields
Source
Engagement Score
Total Campaigns
Total Calls
Successful Calls
Optimal Call Time

although some of these are loaded or stored.

6.78 Lists and Tags Loaded but Hidden

The backend loads the Contact’s Lists and Tags for the Details request.

The current page does not render them in the primary visible Contact-information sections.

Recent Calls on Contact Details

6.79 Recent Calls Table

The Contact page includes a Recent Calls table with:

Date and Time
Direction
Status
Disposition
Duration
View

6.80 Recent Call Limit

The controller retrieves up to:

20 recent Calls

linked directly through the Call’s contact_id.

6.81 Campaign Calls

Older Campaign Call records that lack a direct contact_id may not appear even when they represent the same person.

6.82 Duration Field Mismatch

The backend selects:

duration_seconds

while the page expects a property named:

duration

The displayed Recent Call duration can therefore be blank or undefined in the current build.

6.83 Contact Campaign Data Not Shown

The controller also prepares Campaign and activity information.

The current page does not visibly render the complete Campaign participation or activity timeline.

Editing a Contact

6.84 Opening Edit

From Contact Details, select:

Edit

The page opens:

/contacts/[Contact ID]/edit

6.85 Editable Fields

The current Edit page contains the same primary fields as Create:

First Name
Last Name
Phone Number
Email
Company
Website
Facebook
Instagram
LinkedIn
X or Twitter
Notes

6.86 Lists Cannot Be Changed in Edit

The current Edit page does not display Contact List assignments.

Existing List membership remains unchanged because the backend synchronizes Lists only when List IDs are submitted.

Use Contact Lists or an approved bulk process to change List membership.

6.87 Tags Cannot Be Changed in Edit

The current Edit page does not display Tag assignments.

6.88 Status Cannot Be Changed in Edit

The current Edit page does not expose:

Active
Inactive
Blocked

6.89 Opt-Out Cannot Be Changed in Edit

The form also does not expose:

Opted Out
Opted-Out Date

This means the normal browser Edit page cannot fully manage Do-Not-Call suppression.

An approved Administrator or API-based process is currently required to update these fields reliably.

6.90 Correction to the Post-Call DNC Workflow

Chapter 4 explained that a Do Not Call Disposition must be followed by a separate Contact-status update.

The deeper Contact review shows that the current standard Edit form does not provide that Status or Opt-Out control.

Therefore, the present safe procedure is:

Record Do Not Call Disposition
Notify the authorized Customer manager or Administrator
Update suppression through an approved administrative or API process
Confirm the Contact is excluded from future calling

6.91 Saving Changes

After reviewing the Contact, select Save Changes.

On success:

Contact updated successfully.

appears and the Contact Details page opens.

6.92 CRM Update Event

The standard Edit process compares changed fields and can dispatch a Contact-updated event to configured CRM integrations.

Deleting Contacts

6.93 Soft Deletion

The Contact model uses soft deletion.

Deleting a Contact generally:

Hides it from normal queries
Preserves its database record
Records a deleted timestamp

6.94 No Visible Delete Button

The current primary Contact pages do not clearly expose a standard Delete button.

The backend delete route exists and can be used by authorized workflows.

6.95 Phone Number Reuse After Deletion

Because the Phone Number remains in a soft-deleted row and the database Phone Number constraint is globally unique, deleting a Contact can continue to prevent recreation of that Phone Number.

An Administrator may need to restore or permanently resolve the original record.

6.96 Agent Deletion

Agents cannot delete the parent Customer’s Contacts under the current Contact policy.

6.97 Historical Relationships

Before deleting a Contact, review:

Campaign participation
Call records
Contact Lists
Tags
Follow-up Sequences
CRM records
Compliance history

Contact Calling Session

6.98 Opening the Calling Session

Select:

Start Calling

The page address is:

/contacts/calling-session

6.99 Eligible Contacts

The Calling Session includes Contacts whose:

Status = active
and
Opted Out = false or null

Blocked, Inactive, and Opted-Out Contacts are excluded from this particular workflow.

6.100 Contactability Inconsistency

The Contact model’s general canBeContacted() helper considers a Contact contactable when it is:

Not opted out
and
Not blocked

That helper does not explicitly exclude Inactive Contacts.

The guided Calling Session is stricter because it requires Status Active.

Other workflows must be reviewed carefully so Inactive Contacts are not called unintentionally.

6.101 Calling Order

Contacts are ordered by:

Oldest Last Contacted date first
Then oldest creation date first

Contacts that have never been contacted can appear early in the session.

6.102 List Selection

The Calling Session can be limited to a Contact List.

Selecting another List reloads the session with Contacts belonging to that group.

6.103 Current Contact Card

The session can display:

Contact Name
Phone Number
Email
Company
Website
Notes
Last Contacted
Total Calls
Current position
Total Contacts

6.104 Session Navigation

The user can move with:

Previous
Next
Skip

6.105 Calling

Select Call to load the current Contact into the Softphone.

The Softphone must be registered.

6.106 Automatic Advance

After the linked Post-Call Disposition workflow completes, the Calling Session can move to the next Contact.

6.107 Session Progress Is Browser-Local

The current Contact index and progress are maintained in the page state.

A refresh or reopening the session can reset the user to the beginning of the ordered Contact collection.

6.108 All Matching Contacts Loaded

The Calling Session retrieves the entire matching Contact set rather than using normal pagination.

Very large Contact collections can make the page slower.

Use a focused Contact List for controlled calling sessions.

6.109 List Name Ownership Limitation

The Contact query remains owner-scoped, but the selected List record itself is loaded by ID without a complete ownership restriction.

Do not alter List IDs in the URL.

Contact Lists

6.110 Opening Contact Lists

From the Sidebar:

Contacts
→ Contact Lists

The page address is:

/contact-lists

6.111 List Purpose

Contact Lists are intended to organize Contacts for:

Campaign preparation
Calling Sessions
Imports
Segmentation
Follow-up
Reporting

6.112 List Fields

A List contains:

Name
Description
Owner
Contact relationships
Created and updated timestamps

6.113 Contact Lists Table

The List page displays:

Name
Description
Contact Count
Date
Actions

6.114 Creating a List

Select:

Add List

or open:

/contact-lists/create

Enter:

Name
Description — optional

6.115 List Name

Name is required and can contain up to 255 characters.

The current database rules do not require List names to be unique.

Two Lists can therefore have the same Name.

Use descriptive unique names operationally.

6.116 List Description

Description is optional.

Example:

Prospects collected during the July community workshop.

6.117 Viewing a List

Select View to open the List Details page.

The page shows the List’s Contacts and controls for adding or removing members.

6.118 Adding Contacts

The List Details page supports adding selected Contacts that belong to the owner’s Contact collection.

The backend uses a nonduplicating attachment process, so adding an existing member again should not create another identical List relationship.

6.119 Removing Contacts

Removing a Contact from a List removes only the List relationship.

It does not delete the master Contact.

6.120 Contact in Multiple Lists

Removing a Contact from one List does not remove it from other Lists.

6.121 Editing a List

An Edit route exists at:

/contact-lists/[List ID]/edit

The main List table does not prominently display Edit in every current view, but it can be reached through the List workflow.

6.122 Deleting a List

Deleting a List removes the List record and its relationships.

The master Contact records remain.

6.123 No Soft Delete for Lists

Contact Lists do not use the Contact model’s soft-deletion behavior.

Treat List deletion as permanent through the normal user interface.

6.124 List Ownership

Customers see their own Lists.

Agents use the parent Customer’s List collection.

6.125 List Membership Security Limitation

The add and remove operations validate that submitted Contact IDs exist, but they do not consistently verify that every submitted Contact belongs to the List owner.

Use only Contacts displayed by the normal interface.

This server-side ownership validation should be strengthened.

6.126 Large Lists

List Details can load all current members and all available Contacts.

Large Contact collections can make the page slower because the List workflow is not fully paginated.

Contact Tags

6.127 Opening Tags

The Tag page exists at:

/contact-tags

It is not currently displayed as a primary Sidebar item.

6.128 Tag Fields

A Tag contains:

Name
Color
Owner
Contact relationships

6.129 Default Color

When no color is provided, the backend uses:

#3b82f6

6.130 Tag Name Uniqueness

A Tag Name must be unique within the same owner’s Tag collection.

The same Tag Name can exist for a different Customer account.

6.131 Tags Table

The Tag index can display:

Tag
Contacts
Created
Actions

6.132 Create and Edit Route Limitation

The Tag interface contains links for creating and editing Tags.

The installed route list contains:

GET /contact-tags
POST /contact-tags
PUT /contact-tags/[Tag]
DELETE /contact-tags/[Tag]

It does not contain normal GET routes for:

/contact-tags/create
/contact-tags/[Tag]/edit

The Create and Edit links can therefore open a Not Found page in the current build.

6.133 Backend Tag Creation Still Exists

The backend can create a Tag when an authorized interface submits:

Name
Optional hexadecimal Color

but the standard create form route is incomplete.

6.134 Tag Deletion

The Tag index provides a Delete action.

Review affected Contact classification before deleting a Tag.

6.135 Tags Missing from Contact Forms

The current Create and Edit Contact pages do not display Tag selectors.

6.136 Tags During Import

Existing Tags can be selected in the Contact Import dialog.

This is currently one of the main visible methods for assigning Tags to multiple Contacts.

6.137 Bulk Tag Route

The backend provides:

POST /contacts/bulk/tag

It adds Tags without removing existing Tags.

The current Contacts table does not expose the row selection needed to use this feature through the normal page.

Importing Contacts

6.138 Opening Import

From Contacts, select:

Import

The integrated Import Contacts dialog opens.

6.139 Import Stages

The dialog progresses through:

Upload
Mapping
Importing
Completed

6.140 Supported File Type

The visible browser file selector is designed for:

CSV

The backend also permits text-delimited input, but CSV is the supported user workflow.

6.141 Maximum File Size

The current import permits files up to approximately:

50 MB

6.142 Maximum Rows

The interface describes support for up to:

100,000 rows

Large imports require additional caution because the current deployment processes queued work synchronously.

6.143 Downloading the Template

The Import dialog provides a sample template.

The template filename is:

contacts-import-template.csv

6.144 Template Columns

The template contains:

first_name
last_name
phone_number
email
company
notes

The included sample rows use international Phone Numbers beginning with +.


Import Mapping

6.145 Mapping Purpose

Mapping tells AIUNIFY which CSV column corresponds to each Contact field.

6.146 Available Mappings

The current dialog supports:

First Name
Last Name
Phone Number
Email
Company
Notes
Skip

6.147 Required Phone Mapping

A CSV column must be mapped to:

Phone Number

before the import can proceed.

6.148 Automatic Mapping

The dialog attempts to recognize headers containing terms such as:

first name
last name
phone
mobile
cell
email
mail
company
organization
note
comment

Review every mapping before import.

6.149 Preview Rows

The CSV parser reads a small sample for mapping.

The dialog generally displays the first sample value under each source column.

It does not provide a complete row-by-row validation preview.

6.150 Skip a Column

Select:

Skip

for any source column that should not be imported.

Import Options

6.151 Skip Duplicate Phone Numbers

The dialog displays:

Skip duplicate phone numbers

and enables it by default.

6.152 Duplicate Toggle Does Not Reach the Backend

The current Import dialog does not include the skipDuplicates state in the submitted form data.

The checkbox therefore has no effect on the actual import.

6.153 Existing Same-Owner Contacts Are Updated

When the import finds an existing Contact with the same owner and Phone Number, it updates that Contact instead of skipping it.

This occurs regardless of the visible duplicate checkbox.

6.154 Import Result Meaning

The success count combines:

New Contacts created
+
Existing Contacts updated

The completion screen does not separately show how many were created versus updated.

6.155 Add Tags

Select one or more existing Tags to attach to imported Contacts.

6.156 Add to Lists

Select one or more Contact Lists to attach to imported Contacts.

6.157 Tag and List Ownership Limitation

Submitted Tag and List IDs are not fully validated against the Contact owner.

Use only options displayed by the current account’s interface.

Import Phone Normalization

6.158 Ten-Digit Numbers

A ten-digit number without a plus sign is converted to a U.S. number:

3135550198
+13135550198

6.159 Other Numbers Without a Plus Sign

Other digit lengths are generally prefixed with:

+

This does not guarantee that the result is a valid international number.

6.160 International Imports

Store international Phone Numbers in complete E.164 format before importing.

Example:

+442079460000

Do not rely on automatic country inference.

6.161 Rows Without Phone Numbers

A row without a usable Phone Number does not create a Contact.

The processed-row counter can still advance even though the row is not counted as a successful or failed Contact.

The displayed totals can therefore appear inconsistent.

6.162 Limited Phone Validation During Import

The import normalizes characters but does not run the full Contact Phone Validation workflow on every imported row.

Run Check Valid Numbers after import.

Import Processing

6.163 Import Storage

The uploaded file is stored in an imports directory and connected to a Contact Import tracking record.

6.164 Processing Batches

The import processes Contacts in batches of approximately:

500 rows

6.165 Progress Updates

Progress is updated periodically, approximately every 100 processed rows.

6.166 Current Queue Mode

The production runtime currently reports:

Queue driver: sync

Although the Import dialog describes background processing, the import job currently runs during the web request.

Large files can therefore:

Keep the request open
Take a long time to respond
Reach server or proxy timeouts
Appear frozen

6.167 Polling

After receiving an Import ID, the dialog checks import status approximately every two seconds.

Under the synchronous queue mode, much of the import can already be complete before the browser receives that ID.

6.168 Closing the Dialog

The dialog states that the user can close it and will be notified when processing completes.

The actual import job used by this route does not create the same in-app completion Notification implemented by another unused import job.

Do not rely on an automatic Notification.

6.169 No Import History Page

The current user interface does not provide a durable Contact Import history page.

Closing the modal stops its local polling and resets the dialog.

Record the result before closing it.

6.170 Imported Source Field

The current processing job does not explicitly store:

source = csv_import

Imported Contacts can have a blank or default source value.

6.171 CRM Integration Events

The current import processor creates or updates Contacts directly.

It does not clearly dispatch the same Contact-added or Contact-updated CRM events used by the standard browser forms.

A CSV import may therefore not synchronize to an external CRM automatically.

Agent Import Ownership Defect

6.172 Agent-Owned Import Record

The Contact Import record uses the signed-in User ID.

For an Agent, this is the Agent’s own ID rather than the parent Customer ID.

6.173 Imported Contacts Stored Under Agent

The processing job creates new Contacts using the Contact Import’s User ID.

An Agent’s imported Contacts can therefore be stored under the Agent instead of the parent Customer.

6.174 Imported Contacts Disappear from Agent View

The Agent’s normal Contact index searches the parent Customer’s Contact ownership.

An Agent-created CSV import can succeed and then appear to vanish because the new Contacts belong to the Agent User ID.

Agents should not perform production imports until this ownership mismatch is corrected.

Cross-Account Phone Duplicate Import

6.175 Owner-Scoped Duplicate Check

The import job checks for an existing Phone Number under the import owner.

6.176 Global Database Constraint

The database Phone Number constraint is global.

When another Customer already owns that Phone Number, the owner-scoped check finds nothing, but the database can still reject creation.

The row is then recorded as failed.

Import Completion

6.177 Completion Information

The completion screen can report:

Processed rows
Successful rows
Failed rows
Errors

6.178 Error Limit

The import tracking process keeps a limited set of row errors rather than displaying every error from an extremely large file.

6.179 Review After Import

After completion:

  1. Record the success and failure totals.
  2. Return to Contacts.
  3. Search for several known records.
  4. Confirm Phone formatting.
  5. Confirm Lists.
  6. Confirm Tags.
  7. Run Phone validation.
  8. Review duplicate Contacts.
  9. Test one Contact in the Softphone.
  10. Review CRM synchronization where required.

Exporting Contacts

6.180 Export Route

The Contact export is available at:

/contacts-export

6.181 No Visible Export Button

The current main Contacts page does not display a normal Export button.

The export route exists but may require:

Direct approved route access
Administrator-provided link
Integrated API process

6.182 Export Ownership

Export scope follows:

Administrator:
All Contacts

Customer:
Customer-owned Contacts

Agent:
Parent Customer-owned Contacts

6.183 Export Filters

The export can apply:

Search
Status
Opted-Out state
Tag
Contact List

6.184 Minimum Score Not Applied

The main index backend supports a minimum Engagement Score filter.

The export does not apply that same minimum-score parameter.

6.185 Unassigned List Export Defect

The Contact index specially recognizes:

list_id = unassigned

The export does not implement the same special handling.

Attempting to export the Not in any list view can produce an incorrect result or error.

6.186 Export Filename

The filename follows a pattern similar to:

contacts-2026-07-26-143500.csv

6.187 Export Columns

The CSV includes:

Phone Number
First Name
Last Name
Email
Company
Job Title
Status
Opted Out
Total Campaigns
Total Calls
Engagement Score
Last Contacted
Created At


6.188 Information Excluded from Export

The standard export does not include:

Website
Social URLs
Notes
Time Zone
Language
Custom Fields
Tags
Lists
Successful Calls
Source
Opted-Out date
Data Quality Score
Quality Issues
AI Suggestions
Optimal Call Time
Best Call Hours

6.189 Export Size Behavior

The export retrieves the complete matching Contact collection and builds the CSV in memory.

Very large exports can consume significant server memory.

Use narrower filters for large Contact databases.

6.190 Export Security

Contact exports can contain personally identifiable information.

Store them only in:

Approved encrypted storage
Controlled company drive
Authorized CRM
Secure reporting environment

Phone Number Validation

6.191 Opening Validation

From Contacts, select:

Check Valid Numbers

The system validates the owner’s complete Contact collection.

6.192 Validation Summary

The result displays:

Total
Valid
Invalid

6.193 Invalid Contact Table

Invalid results can show:

Contact
Phone Number
Issue
Suggested Fix
Confidence
Notes
Edit

6.194 Validation Scope

The current process checks all Contacts for the owner.

There is no visible option to validate only:

Selected Contacts
Current page
Current Search
Current List

6.195 What Validation Actually Checks

The current Phone Validation service primarily checks:

Characters
Plus sign
Digit count
Basic international formatting

It does not confirm that the telephone number:

Is assigned
Can receive calls
Belongs to the Contact
Is a mobile or landline
Is reachable
Has consent

6.196 Length Rule

After cleaning, a number is generally considered structurally acceptable when it contains approximately:

7 through 15 digits

6.197 U.S. Defaults

When a number lacks a plus sign, the service commonly assumes:

Country code +1

This can incorrectly reformat non-U.S. numbers.

6.198 Suggested Fixes

Examples include:

10 digits:
Add +1 with high confidence

11 digits beginning with 1:
Add + with high confidence

International 00 prefix:
Replace with + with medium confidence

Other missing +:
Assume +1 with medium confidence

6.199 “AI-Powered” Label Limitation

The interface and controller comments describe the suggestions as AI-powered.

The reviewed implementation generates these Phone fixes using deterministic formatting rules rather than an OpenRouter AI request.

6.200 Suggestions Are Not Automatically Applied

The validation result does not save the suggested Phone Number.

The user must:

  1. Review the suggestion.
  2. Copy it where appropriate.
  3. Open Edit.
  4. Confirm the Contact and country.
  5. Save the corrected number.

6.201 Re-Validate

After corrections, select Re-Validate to scan the Contact collection again.

6.202 No Validation History

Phone validation results are not stored as a lasting Contact-validation status.

The next validation run recalculates the results.

6.203 Performance

The validation request processes every Contact synchronously.

Large Contact databases can take longer and risk request timeouts.

6.204 Administrator Scope Limitation

The normal Contact index allows Administrators to view all Contacts.

Phone validation determines the owner ID as the signed-in Administrator’s ID rather than using the Administrator’s global scope.

An Administrator can therefore validate only Contacts directly owned by the Administrator account through this action, not all platform Contacts.

AI Data Quality Check

6.205 Opening Data Quality

Open a Contact Details page.

The page displays:

AI Data Quality Check

Select:

Check Data Quality

6.206 Provider Requirement

The Data Quality service uses OpenRouter.

A valid OpenRouter configuration is required.

6.207 Quality Results

The analysis can include:

Quality Score
Valid or Invalid assessment
Duplicate Risk
Issues
Severity
Original values
Suggested values

6.208 Quality Score

The score is measured from:

0 through 100

General display categories are:

80–100:
High quality

60–79:
Medium quality

Below 60:
Low quality

6.209 Stored Analysis

Running a quality check can store:

Data Quality Score
Quality Issues
AI Suggestions
Quality Checked At

even before the user applies suggested changes.

6.210 Duplicate Risk

The quality card can display:

Low
Medium
High

Duplicate Risk is part of the AI analysis response.

It is separate from the backend’s exact duplicate-finding endpoint.

6.211 Selecting Suggestions

The interface allows the user to visually select individual suggestions.

6.212 Selected-Field Limitation

The frontend passes a list of approved fields when applying suggestions.

The backend apply endpoint does not use that list.

It applies all stored AI suggestions.

Therefore:

Selected suggestions in the interface
Only suggestions applied by the backend

Do not select Apply unless every displayed suggestion is acceptable.

6.213 Manually Verified Flag

After AI suggestions are applied, the backend marks:

manually_verified = true

even though the values were generated and applied through AI.

The flag should not be interpreted as proof that a human independently verified every field.

6.214 No Undo

The quality workflow does not provide:

Undo
Version history
Before-and-after restore
Approval audit

Record important original values before applying suggestions.

6.215 Agent Authorization Limitation

The Contact Details policy allows an Agent to view a parent Customer Contact.

The Data Quality API requires the Contact’s User ID to equal the signed-in User ID, except for Administrators.

An Agent can see the Data Quality Card but receive:

Unauthorized

when checking a parent-owned Contact.

6.216 Duplicate Endpoint

The API also contains a duplicate-finding endpoint that compares Contacts belonging to the same owner.

Possible matching signals include:

Exact Phone Number
Exact Email Address
Similar or matching Name

6.217 Duplicate Finder Is Not Fully Connected

The standard Contact Quality Card displays the AI-provided Duplicate Risk.

It does not clearly run or display the complete duplicate-finder endpoint results.

6.218 Batch Quality Routes

The API supports batch cleaning for up to approximately:

100 Contacts

per request.

The current main Contacts table does not provide a connected batch-quality selection interface.

6.219 Import Quality Preview Component

The source includes a Contact Import Quality Preview component.

The active Import dialog does not use it.

CSV imports proceed without the user seeing that quality-review step.

6.220 Import Preview API Limitations

The separate quality-preview API expects response fields that do not fully match the Data Quality service’s current result structure.

Its high-confidence auto-apply logic also passes inconsistent function arguments.

It should not be considered production-ready until tested and corrected.

Engagement Score

6.221 Purpose

Engagement Score estimates how actively and successfully the Contact has interacted with Campaigns and Calls.

6.222 Score Inputs

The current calculation uses:

Successful Call rate
Recency of last Contact
Number of Campaigns

6.223 No Call History

When Total Calls equals zero:

Engagement Score = 0

6.224 Successful Call Contribution

Successful Call rate contributes up to approximately:

60 points

6.225 Recency Contribution

Recent activity can contribute:

Contacted within 7 days:
20 points

Within 30 days:
15 points

Within 90 days:
10 points

More than 90 days:
5 points

6.226 Campaign Contribution

Campaign participation contributes up to approximately:

20 points

based on the number of Campaigns.

6.227 Score Visibility

The Engagement Score is stored and can be exported.

The current main Contacts table and Contact Details page do not display it.

6.228 Score Limitations

Engagement Score is not:

Consent
Customer value
Credit score
Likelihood of legal eligibility
Guaranteed sales intent

Use it only as an operational prioritization signal.

Smart Scheduling Contact Data

6.229 Scheduling Fields

Contacts can store:

Optimal Call Time
Optimal Call Confidence
Best Call Hours
Time Zone

6.230 Optimization Routes

The API provides operations for:

Calculating one Contact’s optimal time
Batch optimizing Contacts
Campaign scheduling optimization

6.231 Current Contact Page Limitation

The main Contact Details page does not display or edit the optimal-time fields.

Smart Scheduling is primarily accessed through Analytics and Campaign workflows.

Bulk Contact Operations

6.232 Available Backend Operations

The browser backend provides:

Bulk add Tags
Bulk add to List
Bulk delete

The API also supports bulk create, update, and delete.

6.233 No Main Bulk Toolbar

The current Contacts table has no checkboxes or connected bulk toolbar.

These operations are not normally accessible from the visible Contacts page.

6.234 Bulk Tag Behavior

Bulk Tag:

Adds selected Tags
Preserves existing Tags
Does not remove Tags

6.235 Bulk List Behavior

Bulk Add to List adds selected Contacts to one List.

It does not remove them from other Lists.

6.236 Bulk Delete Behavior

Bulk Delete soft-deletes the selected Contacts.

6.237 Agent Restrictions

Because Agents cannot update or delete parent-owned Contacts, normal Agent bulk Tag, List, or delete requests are rejected by Contact policy.

6.238 Bulk Ownership Security

The selected Contact collection is owner-scoped, but the submitted Tag or List ID is not consistently verified against that same owner.

Do not manipulate request IDs.

Contact Data Security

6.239 Personally Identifiable Information

Contact records can contain:

Names
Phone Numbers
Email Addresses
Companies
Social profiles
Websites
Notes
Call activity
Customer interests

Treat Contact data as protected business information.

6.240 Minimum Necessary Data

Store only the information required for an approved business purpose.

6.241 Notes Safety

Do not place in Notes:

Passwords
Social Security numbers
Full bank information
Full payment-card data
Medical details without authority
Private authentication information

6.242 Social Links

Confirm that social URLs belong to the Contact or business before saving them.

6.243 Export Safety

Contact CSV files should be deleted from local Downloads folders after they have been transferred to approved storage.

Suppression and Consent

6.244 Consent Is Separate from Data Quality

A structurally valid Phone Number does not prove permission to call it.

6.245 Review Before Calling

Confirm:

Consent or lawful basis
Permitted calling hours
Jurisdiction
Do-Not-Call status
Prior opt-out
Campaign purpose

6.246 DNC Field Limitations

The current Contact pages do not provide a complete normal-user suppression control.

Use an authorized documented process and confirm the result before launching a Campaign.

6.247 Lists and Tags Are Not Suppression Controls

A Tag such as:

Do Not Call

does not technically block the Contact unless the calling workflow explicitly excludes that Tag.

A List named:

Suppressed

also does not automatically prevent inclusion elsewhere.

Use the actual Status and opt-out fields through an approved process.

Troubleshooting Contact Access

6.248 Contacts Page Does Not Open

Check:

Authentication
KYC
contacts.view permission
Correct role
Parent Customer assignment for Agent

6.249 Agent Cannot Edit

The Contact policy intentionally prevents Agents from editing parent-owned Contacts.

Contact the Customer manager.

6.250 Contact Appears Under Wrong Account

Do not call or modify it.

Report the ownership issue to an Administrator.

Troubleshooting Contact Creation

6.251 Phone Number Already Registered

The current unique constraint applies platform-wide.

Search for an existing Contact under the authorized account and contact an Administrator when another Customer appears to own the same number.

6.252 Invalid Phone Number

Use:

+[country code][telephone number]

with no extension or text.

6.253 Social URL Rejected

Enter the complete URL beginning with:

https://

6.254 List Assignment Fails

Confirm that the List belongs to the current Customer and still exists.

Troubleshooting Contact Details

6.255 Recent Call Duration Is Blank

The page expects duration, while the backend returns duration_seconds.

Review Call History for the accurate duration.

6.256 Lists or Tags Do Not Appear

The backend loads them, but the current Details page does not render them.

Open Contact Lists or the Tag page.

6.257 Contact Campaign History Missing

The current Contact page does not display the complete Campaign activity data prepared by the controller.

Review Campaign Details and Call History.

Troubleshooting Lists

6.258 Duplicate List Names

List names are not required to be unique.

Rename them with a clear date, purpose, or region.

6.259 List Filter Disappears After Page Change

Pagination does not consistently retain the selected List.

Select the List again.

6.260 Contact Cannot Be Added

Confirm:

Contact exists
Contact belongs to the Customer
List belongs to the Customer
User has required access

6.261 Deleting List Removed Grouping

Deleting a List removes the grouping, not the master Contacts.

Search All Contacts to confirm the Contacts remain.

Troubleshooting Tags

6.262 Create Tag Opens Not Found

The current build does not register the GET Create route.

Tag creation requires a corrected interface or approved backend process.

6.263 Edit Tag Opens Not Found

The normal GET Edit route is also absent.

6.264 Duplicate Tag Name

Tag names must be unique for the same Customer.

Use a different Name or update the existing Tag.

Troubleshooting Imports

6.265 Import Appears Frozen

The current queue driver is synchronous.

Large imports can keep the web request open.

Do not upload the same file repeatedly.

6.266 Duplicate Checkbox Did Not Skip Records

The checkbox is not submitted to the backend.

Existing same-owner Contacts are updated.

6.267 Import Count Does Not Equal CSV Rows

Rows without usable Phone Numbers can increase processed progress without being recorded as success or failure.

6.268 Imported Contact Is Missing

For an Agent, the Contact may have been stored under the Agent User ID and excluded from the parent-owned Contact list.

6.269 Imported Fields Changed Existing Contacts

Matching Phone Numbers update existing same-owner records.

Review before importing a CSV that contains blank or outdated values.

6.270 No Completion Notification

The active import job does not create the promised in-app Notification.

Keep the modal open where practical and record the result.

6.271 Import Failed on Another Account’s Number

The platform-wide Phone Number uniqueness rule can reject a number already stored by another Customer.

6.272 CRM Did Not Receive Imported Contacts

The current CSV processor does not clearly dispatch the normal Contact CRM events.

Use the CRM integration logs and approved synchronization process.

Troubleshooting Exports

6.273 Export Button Missing

The current page does not display one.

The backend route remains /contacts-export.

6.274 Not-in-Any-List Export Fails

The export does not understand the special unassigned List filter used by the Contact index.

6.275 Export Is Slow

The server loads the full matching Contact set into memory.

Use narrower filters.

6.276 Export Missing Notes or Lists

Those fields are not part of the current Contact CSV export.

Troubleshooting Phone Validation

6.277 Valid Number Still Cannot Be Called

The validator checks format, not reachability or provider permissions.

6.278 Non-U.S. Number Receives +1 Suggestion

The current rules assume U.S. formatting when country information is missing.

Correct it manually using the true E.164 country code.

6.279 Suggested Fix Is Wrong

Do not apply it.

Verify the original source or contact the person through an approved channel.

6.280 Validation Takes Too Long

The process scans all Contacts synchronously.

Use smaller Contact collections or an off-hours maintenance window.

Troubleshooting Data Quality

6.281 OpenRouter Error

Confirm OpenRouter configuration and service availability.

6.282 Agent Receives Unauthorized

Agents can view parent Contacts but cannot currently use the quality endpoint on those parent-owned records.

6.283 Only One Suggestion Was Selected but All Changed

The backend ignores the selected-field list and applies all stored suggestions.

Review every Contact field immediately.

6.284 Manually Verified Appears After AI Change

The current backend sets that flag after applying AI suggestions.

It does not prove independent human verification.

6.285 Duplicate Risk Disagrees with Records

The displayed Duplicate Risk comes from AI analysis and is not the same as the deterministic duplicate endpoint.

Search manually by Phone and Email.

Contact Preparation Checklist

6.286 Identity

Confirm:

First Name
Last Name
Company
Correct Contact owner

6.287 Telephone

Confirm:

E.164 format
Correct country code
No extension in Phone field
Number belongs to Contact
Phone validation reviewed

6.288 Consent

Confirm:

Lawful basis
Calling hours
Opt-out status
Do-Not-Call requirements
Campaign purpose

6.289 Organization

Confirm:

Correct Lists
Correct Tags
No unnecessary duplicates
Notes current

Import Checklist

6.290 Before Import

Confirm:

Backup or export completed
CSV headers reviewed
Phone Number mapped
International numbers formatted
Duplicate-update behavior understood
Correct Lists selected
Correct Tags selected
Agent ownership limitation understood

6.291 After Import

Confirm:

Success and failure totals recorded
Sample Contacts found
Existing Contacts not overwritten incorrectly
Phone validation completed
Lists correct
Tags correct
Duplicates reviewed
CRM synchronization reviewed

List Checklist

6.292 Creating a List

Confirm:

Unique descriptive Name
Purpose documented
Correct Contacts selected
Suppression Contacts excluded

6.293 Before Campaign Use

Confirm:

Contact count
Consent
Phone formatting
No duplicate Contact groups
Correct geographic or Time Zone grouping

Data Quality Checklist

6.294 Before Applying AI Suggestions

Confirm:

Original information recorded
Every suggestion reviewed
Phone country verified
Name spelling verified
Email verified
Company verified
All suggestions acceptable

Because the backend applies all stored suggestions, do not proceed when even one suggestion is questionable.

Current-Build Limitations

6.295 Confirmed Limitations

The reviewed Contact implementation currently includes these important limitations:

Phone Numbers are unique across the entire platform,
not per Customer

Soft-deleted Contacts can continue blocking
Phone Number reuse

Create and Edit forms expose fewer fields
than the Contact model supports

Contact Edit does not expose Status or Opt-Out

Contact Lists and Tags are loaded on Contact Details
but not displayed

Recent Contact Call duration uses a mismatched property

Contact index has no visible Tag, Status,
Opt-Out, or Engagement filter

List pagination can lose the current List filter

Main Contact table has no visible bulk selection

Contact Tag Create and Edit links lack GET routes

List and Tag attachment does not consistently
validate account ownership

Import duplicate checkbox is not submitted

Existing Contacts are updated rather than skipped

Current synchronous queue can block large imports

Agent imports can create Contacts under the Agent
instead of the parent Customer

Import does not provide reliable completion Notifications

Import does not clearly dispatch normal CRM events

Import quality preview exists but is not connected

Export has no visible main-page button

Unassigned Contact export is not correctly handled

Export loads all matching Contacts into memory

Phone validation checks formatting,
not real-world reachability

Phone suggestions default toward U.S. +1 formatting

Phone “AI” fixes are rule-based rather than AI-generated

Data Quality selected suggestions are ignored
and all stored suggestions are applied

AI-applied changes set Manually Verified to true

Agents can see parent Contacts but cannot run
the parent Contact quality check

No undo or version history exists
for AI-applied Contact changes

Chapter Completion

At the end of this chapter, the user should understand the difference among:

Master Contact
Campaign Contact
Contact List
Contact Tag

The user should understand how to open the Contacts page, search by Name, Phone Number, Email, or Company, filter by Contact List, interpret the Contact table, open Contact Details, prepare click-to-call, create a Contact, and edit the visible Contact fields.

The user should understand that the Contact model supports more information than the present forms expose, including:

Status
Opt-Out
Time Zone
Language
Custom Fields
Engagement Score
Data Quality
Optimal Call Time

The user should recognize that the current Contact Edit page does not provide a normal control for Status or Opt-Out. A Do Not Call Disposition alone is therefore not a complete suppression process.

The user should know how to create and manage Contact Lists, add or remove List members, and recognize that deleting a List does not delete its master Contacts.

The user should understand that Contact Tags exist but that their Create and Edit links are incomplete in the current build because the required GET routes are not registered.

The user should understand the full Contact Import workflow:

Choose CSV
Map fields
Select Lists and Tags
Review duplicate behavior
Import
Record results
Validate Phone Numbers
Review quality and duplicates

The user should recognize that the visible duplicate-skipping option currently has no effect and that matching same-owner Contacts are updated. The user should also recognize the Agent import ownership defect and the risks created by the current synchronous queue mode.

The user should know how Contact exports are structured, which fields they include, which fields they omit, and why large exports and exported personally identifiable information require careful handling.

The user should understand that Check Valid Numbers performs structural formatting checks rather than confirming whether a Phone Number is real, reachable, consenting, or assigned.

The user should understand how the AI Data Quality Card stores a score, issues, and suggestions. Most importantly, the user should know that selecting only certain suggestions does not limit the backend—the current apply action uses all stored suggestions.

Write Your Comment