Skip to content

CRM Contacts

CRM Contacts represent people your organization interacts with — customers, prospects, partners, or any external individuals. Each contact belongs to a tenant and can optionally be linked to an Account.

Contact Grid

The grid displays all contacts for the current tenant with columns for name, email, phone, company (account), status, source, assigned agent, and tags.

Grid Actions

  • Add to List — Select contacts and click the Add to List toolbar button to add them to a static List.
  • Add/Remove Tag — Right-click selected contacts to add or remove tags in bulk.
  • Assign to Queue — Right-click selected contacts to assign them to a queue. This sets their visibility to “Queue” and assigns the selected queue, making them visible only to agents in that queue.
  • Delete Selected — Remove selected contacts.

Filtering

The filter bar supports these criteria:

FilterDescription
StatusActive, Inactive, or Do Not Contact
SourceHow the contact was acquired
AccountFilter by linked account
Has ActivitiesShow only contacts with or without activity history
TagsSearch by tag text (substring match)

Activity Timeline Badge

The grid shows an Activities badge on each contact indicating the total number of activities and interactions (e.g., “6 Activities”). Click the badge to open the contact’s timeline view, which merges CRM activities and messaging interactions in chronological order. From the timeline, you can view full conversation history for any interaction.

Create/Edit Contact

Basic Information

FieldDescription
First NameContact’s first name (required)
Last NameContact’s last name (required)
EmailEmail address
PhonePrimary phone number
MobileMobile phone number
TitleJob title
DepartmentDepartment within their organization

Classification

FieldDescription
AccountLink to a CRM Account (company)
SourceHow the contact was acquired: Web Form, Referral, Trade Show, Cold Call, Website, Import, Directory Import, API, Manual, Social Media, Lead Conversion
StatusCurrent status: Active, Inactive, or Do Not Contact
VisibilityControls who can see this contact: All (visible to everyone), Queue (visible only to members of the assigned queue), or Owner (visible only to the assigned user). Default: All
Assigned QueueThe queue whose members can see this contact. Only shown when Visibility is set to “Queue”
Assigned ToAgent or user responsible for this contact. When Visibility is “Owner”, only this user can see the contact
Preferred ChannelPreferred communication channel
LanguageContact’s preferred language
TimezoneContact’s timezone
TagsMultiple tags for categorization and filtering

Lists & Notes

FieldDescription
ListsRead-only field showing names of static Lists this contact belongs to
NotesFree-text area for additional information about the contact

External CRM

FieldDescription
External CRM IDIdentifier in an external CRM system
External CRM ProviderName of the external CRM (e.g., Salesforce, HubSpot)

Custom Fields

If Custom Fields have been defined for contacts, they appear in a collapsible “Custom Fields” section at the bottom of the form. These fields are tenant-specific and can include text, numbers, dates, dropdowns, checkboxes, and text areas.

CSV Import

Use Import CSV in the contacts toolbar to bring contacts in from spreadsheets exported from another CRM, a directory, or any tabular source. The import runs as a three-step wizard:

Step 1 — Upload

  • Choose a .csv file from your workstation.
  • Delimiter defaults to auto-detect (comma, semicolon, tab, pipe). Override when your file uses a non-standard separator.
  • Uncheck First row is a header only when the CSV has no header row.
  • Optional Load saved template selects a previously saved mapping profile and pre-fills the next step.

Uploads are parsed with CSV.pm and staged under the signed-in user’s scratch directory. No contacts are written until you confirm in Step 3.

Step 2 — Map fields

Each CSV column is shown as a row with a sample of its first few values and an editable Target field dropdown. The server pre-fills each row using a built-in alias map (for example, First Name, FName, and given_name all map to first_name). You can adjust any row, including mapping to:

  • Core contact fields: first_name, last_name, email, phone, mobile, title, department, status, source, preferred_channel, language, timezone, notes, assigned_to, external_crm_id, external_crm_provider, visibility, assigned_queue.
  • Special virtual fields: _tag (semicolon-separated tags) and _list (row’s list name, used with list_mode=per_row).

Columns left on (Ignore) are skipped. Click Next to continue.

Step 3 — Review & import

  • On duplicate match — Update existing (default) or Skip. Matches are detected using Match keys (any of email, phone, mobile, external_crm_id).
  • Add to list — No list, an Existing list, or a New list created on the fly.
  • Dry run — Parse everything and report counts without writing. Recommended for first imports.
  • Save this mapping as a template — Persists the field mapping plus the options above in crm_import_maps, so future imports of the same source can select it in Step 1.

When you click Import the wizard reports imported / updated / skipped / error counts. Failed rows stay available as a CSV download at /api/crm-contacts/{tenant}/import-errors?token=... for the duration of the session, so you can correct them and re-import.

REST API

The same pipeline is available for automation:

  • POST /api/crm-contacts/{tenant}/import — inline CSV body with mapping_json.
  • POST /api/crm-contacts/{tenant}/import-preview — header + sample rows, no write.
  • GET|POST|PUT|DELETE /api/crm-import-maps/{tenant}[/id] — manage saved mappings.

See the Scalar UI under Configuration → Tools → OpenAPI for full request / response schemas.

Thirdlane Connect Integration

Thirdlane Connect exposes the same contacts under the Customers tab.

  • A list dropdown above the contact list lets agents scope the sidebar to any static or dynamic CRM list, with live contact counts. “All contacts” returns the tenant-wide set.
  • Search, alphabetical jump, and pagination all respect the selected list.
  • The Upload CSV icon in the sidebar header (visible to users with CRM edit or manage permission) opens a lightweight CSV upload modal that calls the same /api/crm-contacts/{tenant}/import endpoint. Use it for quick in-app imports; for column mapping and saved templates use the PBX Manager wizard described above.

Worked example: import 500 contacts from a HubSpot export

You exported a contacts.csv from HubSpot and want it in the CRM without creating duplicates, tagged and added to a list for a later campaign.

  1. Upload (Step 1). Click Import CSV, choose contacts.csv, leave Delimiter on auto-detect and First row is a header checked. Click Next.
  2. Map fields (Step 2). The server auto-maps obvious columns (First Name -> first_name, Email -> email, etc.). Fix the rest by hand: map HubSpot’s Phone Number to phone, Company you can ignore here (accounts are separate), and point a Segment column at the virtual _tag field so each row’s tags import too. Leave unwanted columns on (Ignore). Click Next.
  3. Review (Step 3). Set On duplicate match to Update existing and Match keys to email (unique and stable - safer than name). Under Add to list, choose New list and name it HubSpot Import Jul 2026. Turn Dry run ON for this first pass.
  4. Dry run. Click Import. The wizard reports something like “480 imported, 15 updated, 5 errors”. Download the error CSV from the link, fix those 5 rows (usually a missing/odd email), and note the counts look right.
  5. Real import. Re-open the wizard, and this time load the mapping you just used - tick Save this mapping as a template on the dry run so it is available - turn Dry run OFF, and click Import for real.
  6. Verify. Filter the grid by the new HubSpot Import Jul 2026 list; the imported contacts appear with their tags. They are now ready to target from a Campaign.

For automation, the same thing is available as POST /api/crm-contacts/{tenant}/import with a mapping_json body - see the REST API note above.

Best practices

  • Populate phone and mobile in E.164 format. Consistent numbers (for example +14155551234) let inbound and outbound calls match the right contact automatically for caller lookup and activity logging.
  • Link contacts to an Account. This rolls their activity up to the company level and gives everyone a shared view.
  • Use Visibility deliberately. Leave it on All for shared customer data; use Queue or Owner only when a contact should be restricted to a specific team or person.
  • Dry-run large imports. On the first import of a new source, enable Dry run to catch mapping and duplicate-match problems before writing any records.
  • Choose match keys that are unique. For re-imports, match on email or external_crm_id rather than name to avoid creating duplicates.