Keep a canonical record of every person you've ever talked to — with custom fields per channel, duplicate merging, and bulk CSV import — so every chat opens with context.

TL;DR

  • What it is — the CRM's contact directory. Every chat links to a contact; every contact belongs to a channel-specific template that defines its custom fields.
  • Who it's for — every inbox user benefits automatically. Admins use this module for bulk imports, merges, segmentation, and custom-field design.
  • Top outcome — never start a conversation without the guest's history, and never send a campaign to the wrong audience because of dirty data.

At a glance

Plan tierAll paid tiers.
Who can use itAccount Owners, Admins, and Users.
ChannelsContacts are scoped per channel (WhatsApp Official, WhatsApp Unofficial, Email, Web Chat), each with its own custom-field template.
IntegrationsContact fields feed Campaigns audience filters. Bulk Import uses the same import engine.
Top limits25 / 50 / 100 rows per page · 100 max per API fetch · 5,000 max per bulk-create request · 10 MB CSV file · phone 7 – 15 digits · country code 1 – 4 digits.
APIYes — partner API for listing, fetching, bulk-creating, merging, and deleting contacts.

How to find it

Sidebar → Contacts.

Direct URL: https://lodgestory.com/crm/contacts

Related settings: Settings → Contact Fields (/crm/settings/contacts) defines the custom-field templates used here. Different module — see Contact Fields.

Bulk import. A bulk-import dialog is available here on the Contacts page, and Bulk Import is a separate workspace module with a richer import-plus-schedule flow. The key difference: the Contacts dialog creates contact records, while the Bulk Import module creates chats (and can schedule a first message at the same time).

📸 [SCREENSHOT: contacts-nav.png — sidebar with Contacts highlighted]

What is Contacts?

The problem it solves

Every channel, by default, identifies a person only by a phone number or an email. WhatsApp gives you +91... and nothing else; email gives you an address and maybe a display name. Without a proper contact database, agents retype guest names into every reply, campaigns misfire to the wrong segments, and duplicates multiply across channels until the same guest has three different records.

Contacts is the single source of truth under every chat. It captures standard identity (name, phone, country code, email), lets you add channel-specific custom fields (booking reference, loyalty tier, VIP flag), supports CSV import with duplicate detection, and lets you merge duplicates by hand with an audited merge trail.

What you get

  • One contact per person, per channel. Uniqueness is enforced by phone + country code.
  • Custom fields per channel. Each channel has its own contact template. Fields can be text, email, number, phone, select, checkbox, date, or long text. Required flags are enforced.
  • CSV bulk import with validation. Four-step wizard: Upload → Preview → Import → Results. Up to 5,000 contacts per request; invalid rows are flagged with their specific problem and returned in an error-report CSV.
  • Filters and segmentation. Five built-in filter dimensions, plus custom-field filters with operators like contains, starts with, is empty, greater than, before.
  • Merge duplicates. Pick a primary and any number of secondaries; choose which value wins per field; secondaries are removed; all linked chats move to the primary.
  • Soft-delete only. Deleted contacts are hidden but preserved — no accidental hard loss.

How it's different

  • Channel-scoped custom fields. Most systems use one global field list; here every channel defines its own, because a B2B email contact cares about different things than a B2C WhatsApp contact.
  • Flexible fields without schema changes. Add, rename, or remove a custom field on a template without any migration step.
  • Merge is transactional and surgical. Chat links move correctly to the primary; overlapping links (primary already linked to that chat) are dropped cleanly. No orphaned records, no duplicated chat-contact links.

Customer scenarios

  • New property onboarding. Operator migrates from a legacy system. Uploads a 4,000-row CSV of past guests. The preview validates every row against the channel's template, flags malformed phones and duplicates, and imports the valid rows. Downstream campaigns can target these contacts immediately.
  • Duplicate cleanup. A single guest appears three times — different spellings, slightly different phone formatting. An admin searches the name, opens all three, picks a primary, picks which fields win, and merges. Past WhatsApp chats from all three are now on one record.
  • VIP segmentation. An admin adds a custom field VIP tier (None / Silver / Gold / Platinum) to the WhatsApp template. Front-desk flags top guests. A campaign targets VIP tier = Gold or Platinum via the custom-field filter.

How it fits with the rest of Lodgestory

Contacts is the guest record that Home shows in the right panel. Campaigns filter their audience on contact fields. Bulk Import is the chat-plus-schedule workspace that shares the underlying import engine. Contact Fields defines the templates. Tickets and Calls reference contacts indirectly via the chat.

📸 [SCREENSHOT: contacts-landing.png — contacts list with filters, columns, and bulk-action bar]

Core concepts

TermWhat it means
ContactOne record for one person on one channel. Standard fields (name, phone, email) plus any custom fields the template defines.
Linked chatA link between a contact and a chat. One chat can only link to one contact; one contact can link to many chats.
Contact templateThe custom-field list for contacts on a specific channel. Each channel has its own.
Custom fieldA field on the template — text, email, number, phone, select, checkbox, date, or long text. Can be required.
MergeCombining duplicate contacts into one, choosing which fields win and reassigning all linked chats to the primary.
Soft deleteHiding a contact without hard-deleting it. Deleted contacts don't appear in lists or pickers.

Quick Start — import contacts and merge duplicates in 5 minutes

Step 1 — Open Contacts

Sidebar → Contacts or https://lodgestory.com/crm/contacts.

Step 2 — Open the bulk import dialog

Click Bulk import at the top right. The four-step wizard opens.

📸 [SCREENSHOT: contacts-qs-2.png — bulk import wizard]

Step 3 — Upload a CSV

Pick the destination channel (this decides which template's custom fields map in). Download the Sample CSV to see the expected columns. Drag your CSV file onto the upload zone (10 MB max).

Step 4 — Review the preview

Rows are validated:

  • First name is required.
  • Phone must be 7–15 digits.
  • Country code is 1–4 digits (defaults to 91 if not provided).
  • Email must look like an email.
  • Custom fields must match their declared types.

Use the Valid / Errors / All tabs to inspect results.

What you'll see next: a preview table with valid rows in green and invalid rows in red with the specific reason.

Step 5 — Import

Click Import. The wizard shows the progress and then displays the Results tab — counts of created, skipped duplicates, and errors, plus a download button for an error-detail CSV.

Step 6 — Merge duplicates

Back on the list, search for a guest you suspect is duplicated. Select two or more records; the bulk-action bar shows Merge. Pick the primary record; for each differing field choose which record's value wins. Click Merge.

What you'll see next: the primary record retained, secondaries hidden, and the primary now holding all linked chats.

How it works

When you upload a CSV, Lodgestory:

  1. Parses the file client-side and matches column headers to the standard fields and the template's custom fields.
  2. Validates every row (required fields, phone and country-code formats, custom-field types).
  3. On import, checks for existing contacts on the destination channel by phone + country code and skips duplicates.
  4. Inserts valid rows in batches and returns a results summary.

When you merge duplicates, Lodgestory:

  1. Validates that the primary isn't in the secondaries list.
  2. Moves every chat linked to a secondary to the primary (or drops overlapping links cleanly).
  3. Combines custom field values in the order you chose (primary → secondaries → your overrides).
  4. Applies any standard-field overrides you picked.
  5. Hides the secondaries (soft-delete).

Everything is applied atomically — if the merge fails validation, nothing changes.

Features in depth

Contacts list

Paginated table. Sortable by first name, last name, email, phone, created date, and updated date. Configurable columns: seven standard plus any custom field from any template in the organisation.

Default page size is 25; pick 50 or 100 if you prefer. Each request returns at most 100 rows.

Filters

Five built-in dimensions plus custom-field filters:

DimensionOptions
ChannelSingle-channel select — scopes to that channel's template
Has chatsYes / No / All
Date rangeCreated after / Created before
Custom fieldAny field from any template — operators: equals, not equals, contains, starts with, is empty, is not empty, greater than, less than, before, after
SearchFree text across first name, last name, phone, email

Custom-field filters combine with AND.

Contact detail drawer

Click any row. Shows the summary (name, email, phone with country code), every custom field from the contact's template, a Linked Chats section, created / updated timestamps, and the creator.

Edit mode toggles inline edit for standard and custom fields. Save writes the change immediately.

Linked Chats supports Link chat (search and attach any chat in the organisation) and Unlink chat (remove the link without deleting either side).

Create dialog

Click + Create contact:

  • Channel selector (required) — decides which template's custom fields appear.
  • First name (required).
  • Last name, phone, country code, email — optional.
  • Custom fields from the selected template, with their own required-field rules.

Bulk import (wizard)

Four steps:

  1. Upload — pick the destination channel, download the sample CSV, drag-drop your file (10 MB max).
  2. Preview — row-by-row validation with normalisation (strips spaces and hyphens from phones; defaults country code to 91 when missing). Three tabs: All, Valid, Errors. Within-file duplicates flagged here.
  3. Importing — the system checks for existing contacts on the channel and skips duplicates while inserting new rows in batches.
  4. Results — counts of created, skipped duplicates, and errors, plus an error-detail CSV download.

Key limits:

  • Max 5,000 contacts per import request.
  • CSV ≤ 10 MB.
  • Duplicate strategy: skip (default) or error-out on the first duplicate.

Merge contacts

Select two or more in the list → Merge in the bulk-action bar.

  1. Pick a primary — this record is retained.
  2. For every differing field, pick the winning value (primary, any secondary, or a manual override).
  3. Review the summary — how many secondaries will be hidden, how many linked chats will move, how many will be dropped for overlap.
  4. Confirm.

Delete (single and bulk)

Detail drawer → Delete, or bulk-select → Delete. Always soft — the contact is hidden and the chat links removed (the chats themselves remain). Transactional for bulk.

Custom-field filter builder

In the filters panel. Pick any field from any template, pick an operator, pick a value. Add more conditions for AND logic.

Linked Chats

Inside the contact drawer. Shows every chat ever linked to this contact, with channel, type, and last-message time. Click a row to open the chat in Home — useful when preparing for an outbound message or a call.

Roles and permissions

All authenticated users in the organisation can work with contacts:

ActionAccount OwnerAdminUser
View contacts
Create a contact
Edit a contact
Delete a contact
Merge contacts
Link / unlink a chat
Bulk import
Configure contact templates (Settings)

Cross-module workflows

Migration from a legacy CRM

An admin exports past guests from a legacy system, renames columns to match the Lodgestory sample CSV, and imports in one pass. Errors flagged by the preview (malformed phones, missing required custom fields) are fixed in the CSV and re-uploaded. Valid rows land, duplicates are skipped. A bulk-delete of obvious test or junk rows cleans up.

Modules involved: Contacts → Bulk Import → Contact Fields.

Campaign targeting by custom field

Marketing wants to message VIP tier = Gold guests. They open Contacts, add a filter for the VIP tier custom field, confirm the segment size, and hand the list to a Campaign broadcast.

Modules involved: Contact Fields → Contacts → Campaigns.

Inbound message → contact auto-link

When a message arrives on a new phone number or email, Lodgestory creates or updates a contact automatically and links it to the chat. The new contact appears in your list the same way any other does. This module's job starts at viewing and editing that contact, not creating it from inbound messages.

Limits a user will run into

LimitValue
Bulk create per request5,000 rows
Rows per page (UI)25 / 50 / 100 (default 25)
Max per API request100 rows
CSV file max size10 MB
Phone digits7 – 15
Country code digits1 – 4
Custom fields per contactNo limit
Chats per contactNo limit

Errors & FAQ

You seeLikely reasonWhat to do
"Contact not found"Wrong ID or already deletedVerify the ID; note that soft-deleted contacts are hidden from lists
"Maximum 5000 contacts per request"Upload over the capSplit the CSV
"Primary contact cannot be in the secondary list"Invalid merge inputPick distinct primary and secondaries
"Primary contact not found"Primary was deleted between selection and mergePick a different primary
"First name is required"Missing required field at createFill in the first name
"File too large. Maximum size is 10MB."CSV over the size capSplit the CSV
"Missing required column: firstName"CSV header mismatchUse the sample CSV as a template
"No data rows found in CSV"File has headers onlyAdd rows
"Failed to parse CSV"Encoding or quoting issueRe-export as UTF-8 with standard CSV quoting

Frequently asked

How is duplication detected?
By phone + country code, scoped to the channel's template. Two contacts with the same phone but different country codes are not duplicates. Email isn't used as a duplicate key.

Why did my CSV import skip rows I thought were new?
Those rows had the same phone + country code as existing contacts on the destination channel, so they were skipped under the default Skip duplicates strategy.

Can I hard-delete a contact?
Not from the UI. Soft-deleted contacts are hidden from lists and pickers but preserved. Contact support for a permanent delete.

Why doesn't my new custom field show up in existing contacts?
New template fields are available for newly created or edited contacts immediately. Existing rows won't have a value until someone edits them.

I merged the wrong way — can I undo?
No automated undo. Secondaries are soft-deleted; support can restore them and then you can re-merge. Plan merges carefully on records with many linked chats.

Can I export my contacts?
The Contacts workspace page doesn't have a native export. Use Reports for a full CSV export with filters.

Why aren't contacts created automatically when a new message arrives?
They are — but by the inbound message-ingest path. This module is for managing contacts, bulk creation, and merges after the fact.

Related modules & next steps

  • Home (Unified Inbox) — the contact record powers the guest-details panel.
  • Contact Fields — define the per-channel custom-field templates used here.
  • Bulk Import — the standalone workspace for chat creation and first-outbound scheduling.
  • Campaigns — target segments using contact and custom-field filters.
  • Reports — export contacts as CSV.
  • Tickets — linked to contacts indirectly via the chat.