Guide

Keeping Your Contact List Clean and Deduplicated

7 minute read · Updated August 16, 2026

A contact list earns its keep by being searchable. The moment the same person appears four times with three spellings of their company, it stops being a record of who you talk to and becomes a chore that people work around.

MyLiveChat keeps contacts alongside the conversations they came from, which makes them useful, and it deliberately keeps the model small. Understanding that small model is most of the work, and it explains the one behaviour that surprises people after their second import.

Three lists and two views

A contact belongs to exactly one of three lists: leads, users, or spam. That is the whole taxonomy, and a contact cannot be in two of them at once.

On top of those lists sit two views that are not lists at all. The default view shows everything that is not spam, which is why the count you see there is smaller than leads plus users plus spam. The companies view shows the contacts that have a company name filled in, again excluding spam, and its headline number counts distinct company names rather than contacts.

That distinction matters when the numbers look wrong. Two hundred contacts across forty companies is not a contradiction; it is the same data counted two ways.

Adding a contact by hand defaults it to leads. If you send it to a list name the system does not recognise, it quietly lands in leads too. Moving contacts in bulk is stricter and rejects an unknown list outright, which is a small inconsistency worth knowing if you ever drive this from a script.

Spam is a hiding place, not a delete

Moving a contact to spam does not remove it. It stays in the database, keeps its tags and its history, and simply stops appearing in the default view and the companies view.

This is the right tool for the form-filler who left a fake address and the bot that started forty chats overnight. You get a quieter list without destroying anything, and if you were wrong you move the contact back.

It is the wrong tool for a genuine contact who asked to be removed. That is a deletion, and it should be an actual deletion.

What search actually looks at

The search box matches against five fields: name, email, phone, company name, and tags. It is a substring match, so a fragment in the middle of a value will find it, and a partial phone number works.

It does not search conversation transcripts, ticket bodies, or notes. A contact you remember only by something they said will not surface here, and that is the single most common reason people conclude the search is broken. Search the transcripts for the conversation, then open the contact from there.

Because tags are searchable, they are the cheapest way to make a contact findable by something the schema has no field for. A tag such as renewal-q3 or enterprise-trial turns into a working filter immediately.

Importing: the header row decides everything

The importer reads the first line of what you paste as a header, and it recognises a fixed set of names. Name accepts name, fullname, or full_name; email accepts email or email_address; phone accepts phone or mobile; company accepts company, companyname, or company_name; and there are plain country and tags columns.

Anything else in the header is ignored without comment. That is the failure mode to watch for, because an export whose column is called Email Address with a space, or Work Phone, will import as though that column were not there at all, and you will get a list of contacts with the names filled in and nothing else.

The import is rejected outright only if the header contains none of name, email, or phone. Rows where all three of those are blank are skipped silently, so trailing empty lines are harmless.

One more limit worth respecting: rows are split on line breaks before the quoting is parsed, so a quoted field containing a newline inside it will break that row apart. Strip line breaks out of note-like columns before you paste.

Everything in a single import goes into a single list. If you are bringing in both customers and prospects, that is two imports.

Nothing is deduplicated

This is the one to remember. Every data row in an import becomes a new contact, unconditionally. There is no match on email, no merge, no skip-if-present, and no warning.

Import the same file twice and you have every contact twice. Import a fresh export from the same source a month later and you have duplicates of everyone who was already there, plus the new arrivals mixed in among them.

Adding a contact by hand does the same thing, so entering somebody who already exists produces a second record rather than updating the first.

It is worth being clear that this is specific to contacts. The ticket and help-article importers do deduplicate, keyed on where the record came from, so experience with those is exactly the wrong intuition to bring here.

The practical rule is to deduplicate before you paste, in the spreadsheet, where you have the tools to do it. Sort by email, remove the repeats, and keep a note of the date you last imported so the next export can be filtered to records created since. If duplicates have already happened, search for the address, select the copies, and delete them, keeping whichever record has the most complete company and tag data.

Bulk tagging replaces, it does not add

Selecting a set of contacts and applying a tag overwrites whatever tags those contacts already had. It is not an append.

Tagging thirty contacts as webinar-may will therefore erase the enterprise and renewal tags that some of them were carrying, and there is no undo. Given that tags are one of the five searchable fields, this can quietly cost you the ability to find a segment you spent months building.

Work around it by keeping bulk tagging for contacts that are genuinely new or genuinely untagged, and by treating any bulk tag on an established selection as a rewrite that needs the full intended tag string, not just the one you are adding.

Deleting is permanent

Deletion removes the rows. There is no archive, no recycle bin, and no undo, and deletes are scoped to your own site so there is no wider blast radius, but within your list the removal is final.

Because of that, spam is the better first move whenever you are not certain. Hide it, look again in a week, and delete when you are sure. The exception is a genuine erasure request, where deleting is the point; see the guidance on privacy and data requests in live chat for what else needs to happen alongside it.

One more thing to know before you tidy: several fields are silently truncated when they are stored, with names, email addresses, and company names cut at two hundred characters, phone numbers at sixty, country at eighty, and the whole tag string at five hundred. Long tag lists are the realistic risk, since a selection with many tags can lose the ones at the end without any warning.

A routine that keeps it usable

Deduplicate in the spreadsheet before every import, and record the date. Import prospects and customers separately so each lands in the right list. Move obvious junk to spam the same week it arrives, rather than letting it accumulate until the list is not worth opening.

Agree a small tag vocabulary and write it down, because tags are only searchable if everyone spells them the same way. Six agreed tags beat forty improvised ones.

Then push the value back where it is useful. Contacts are most valuable when they are reachable from the systems your team already works in, which is what the CRM and CDP integrations are for.

What to measure

Count distinct email addresses against total contacts. The gap is your duplicate rate, and if it is climbing after each import the pre-import cleanup is not happening.

Track how many contacts have neither a company nor a tag. Those are records that will never be found by anything except an exact name search, and a large share of them means the capture step upstream is collecting too little to be worth storing.

Watch the spam list too. A spam count growing faster than leads is a signal about your forms and your widget targeting, not about the contact list, and it is usually cheaper to fix at the source.

Put it into practice

MyLiveChat gives you live chat, AI answers and a shared helpdesk in one place. Free plan, no card required.

Free forever for 1 agent

Give every visitor an instant way to reach you.

Launch live chat, connect your knowledge base, and add AI answers when you are ready. No credit card, no trial clock.