Skip to content

Contact Management Guide

Overview

Contacts represent individual people within your CRM system. Unlike customers (which represent the business relationship), contacts are the actual people you interact with - decision makers, influencers, users, and stakeholders. This guide covers creating, managing, and maintaining contact data including duplicate detection and deduplication.

Contact vs Customer vs Lead

Understanding the distinction:

EntityWhat It RepresentsExample
LeadUnqualified potential customerWebsite visitor who downloaded whitepaper
CustomerBusiness relationship, accountAcme Corporation (the company)
ContactIndividual personJohn Smith, CTO at Acme Corporation
OpportunityPotential revenue$150K Platform Deal with Acme Corp

Relationships:

  • A Customer (Acme Corp) can have multiple Contacts (CTO, CFO, VP Ops)
  • A Contact can be associated with one Customer
  • Activities (calls, meetings) are logged with specific Contacts
  • Opportunities involve specific Contacts as decision makers

Contact Types and Roles

Job Roles

Common contact roles in business relationships:

Decision Makers:

  • CEO, President
  • CFO (budget authority)
  • CTO, CIO (technical authority)
  • VP/Director level

Influencers:

  • Department heads
  • Team leads
  • Subject matter experts
  • Technical evaluators

Users:

  • End users
  • Power users
  • Administrators
  • Champions

Gatekeepers:

  • Executive assistants
  • Procurement
  • Legal counsel

Creating Contacts

Create Contact

Endpoint: POST /api/v1/crm/contacts

Authentication: Required (Bearer token)

Request Body:

json
{
  "first_name": "John",
  "last_name": "Smith",
  "title": "Chief Technology Officer",
  "email": "john.smith@acmecorp.com",
  "phone": "+1-555-0200",
  "mobile": "+1-555-0201",
  "customer_id": 568,
  "department": "Technology",
  "role": "decision_maker",
  "is_primary": true,
  "status": "active",
  "address": {
    "street": "100 Enterprise Parkway",
    "city": "New York",
    "state": "NY",
    "postal_code": "10001",
    "country": "USA"
  },
  "social_profiles": {
    "linkedin": "https://linkedin.com/in/johnsmith",
    "twitter": "@johnsmith"
  },
  "communication_preferences": {
    "preferred_method": "email",
    "best_time": "morning",
    "timezone": "America/New_York",
    "opt_out_marketing": false
  },
  "tags": ["decision-maker", "technical", "executive"],
  "notes": "Primary technical decision maker. Very knowledgeable about integration requirements. Prefers detailed technical discussions.",
  "custom_fields": {
    "assistant_name": "Mary Johnson",
    "assistant_email": "mary.johnson@acmecorp.com",
    "direct_line": "+1-555-0202"
  }
}

Required Fields:

  • first_name - Contact's first name
  • last_name - Contact's last name
  • email - Email address (must be unique within customer)

Optional Fields:

  • customer_id - Associated customer
  • title - Job title
  • phone - Office phone
  • mobile - Mobile phone
  • department - Department name
  • role - Contact role
  • is_primary - Primary contact flag
  • status - Contact status (active, inactive)
  • address - Full address object
  • social_profiles - Social media links
  • communication_preferences - Communication settings
  • tags - Contact categorization
  • notes - Internal notes

Response (201 Created):

json
{
  "message": "Contact created successfully",
  "data": {
    "id": 123,
    "first_name": "John",
    "last_name": "Smith",
    "full_name": "John Smith",
    "title": "Chief Technology Officer",
    "email": "john.smith@acmecorp.com",
    "phone": "+1-555-0200",
    "mobile": "+1-555-0201",
    "customer_id": 568,
    "customer": {
      "id": 568,
      "customer_number": "CUST-000568",
      "company_name": "Acme Corporation"
    },
    "department": "Technology",
    "role": "decision_maker",
    "is_primary": true,
    "status": "active",
    "created_at": "2025-12-17T23:00:00Z"
  }
}

Listing and Filtering Contacts

Get All Contacts

Endpoint: GET /api/v1/crm/contacts

Query Parameters:

  • customer_id (integer) - Filter by customer
  • role (string) - Filter by contact role
  • department (string) - Filter by department
  • status (string) - Filter by status
  • is_primary (boolean) - Filter primary contacts only
  • search (string) - Search by name or email
  • per_page (integer) - Results per page (default: 25)
  • page (integer) - Page number
  • sort_by (string) - Sort field (created_at, last_name)
  • sort_direction (string) - Sort direction (asc, desc)
  • includes (string) - Relationships: customer, activities

Example Request:

bash
GET /api/v1/crm/contacts?customer_id=568&role=decision_maker&per_page=50

Response (200 OK):

json
{
  "data": [
    {
      "id": 123,
      "full_name": "John Smith",
      "title": "Chief Technology Officer",
      "email": "john.smith@acmecorp.com",
      "phone": "+1-555-0200",
      "customer": {
        "id": 568,
        "company_name": "Acme Corporation"
      },
      "role": "decision_maker",
      "is_primary": true,
      "status": "active",
      "created_at": "2025-01-15T10:00:00Z"
    }
  ],
  "meta": {
    "current_page": 1,
    "per_page": 50,
    "total": 5
  }
}

Viewing Contact Details

Endpoint: GET /api/v1/crm/contacts/{id}

Query Parameters:

  • includes (string) - Relationships: customer, activities, opportunities

Response (200 OK):

json
{
  "data": {
    "id": 123,
    "first_name": "John",
    "last_name": "Smith",
    "full_name": "John Smith",
    "title": "Chief Technology Officer",
    "email": "john.smith@acmecorp.com",
    "phone": "+1-555-0200",
    "mobile": "+1-555-0201",
    "customer": {
      "id": 568,
      "customer_number": "CUST-000568",
      "company_name": "Acme Corporation",
      "status": "active"
    },
    "department": "Technology",
    "role": "decision_maker",
    "is_primary": true,
    "status": "active",
    "address": {
      "street": "100 Enterprise Parkway",
      "city": "New York",
      "state": "NY",
      "postal_code": "10001",
      "country": "USA"
    },
    "social_profiles": {
      "linkedin": "https://linkedin.com/in/johnsmith",
      "twitter": "@johnsmith"
    },
    "communication_preferences": {
      "preferred_method": "email",
      "best_time": "morning",
      "timezone": "America/New_York"
    },
    "activities_count": 47,
    "last_activity_at": "2025-12-15T14:30:00Z",
    "tags": ["decision-maker", "technical", "executive"],
    "notes": "Primary technical decision maker. Very knowledgeable about integration requirements.",
    "created_at": "2025-01-15T10:00:00Z",
    "updated_at": "2025-12-15T16:00:00Z"
  }
}

Updating Contacts

Endpoint: PUT /api/v1/crm/contacts/{id} or PATCH /api/v1/crm/contacts/{id}

Request Body (partial update):

json
{
  "title": "Senior Vice President, Technology",
  "phone": "+1-555-0299",
  "notes": "Promoted to SVP. Now oversees both IT and Engineering. Expanded decision-making authority.",
  "tags": ["decision-maker", "technical", "executive", "promoted"]
}

Response (200 OK):

json
{
  "message": "Contact updated successfully",
  "data": {
    "id": 123,
    "title": "Senior Vice President, Technology",
    "phone": "+1-555-0299",
    "updated_at": "2025-12-17T23:30:00Z"
  }
}

Contact Status Management

Activate Contact

Endpoint: POST /api/v1/crm/contacts/{id}/activate

Response (200 OK):

json
{
  "message": "Contact activated successfully",
  "data": {
    "id": 123,
    "status": "active",
    "updated_at": "2025-12-17T23:45:00Z"
  }
}

Deactivate Contact

Endpoint: POST /api/v1/crm/contacts/{id}/deactivate

Request Body (optional):

json
{
  "reason": "Contact left company"
}

Response (200 OK):

json
{
  "message": "Contact deactivated successfully",
  "data": {
    "id": 123,
    "status": "inactive",
    "deactivation_reason": "Contact left company",
    "updated_at": "2025-12-17T23:50:00Z"
  }
}

Duplicate Detection

Find Duplicate Contacts

Endpoint: GET /api/v1/crm/contacts/duplicates

Query Parameters:

  • match_by (string) - Matching criteria: email, phone, name, or comma-separated combination
  • customer_id (integer) - Limit search to specific customer
  • fuzzy (boolean) - Enable fuzzy name matching (80% similarity threshold)
  • include_confidence (boolean) - Include confidence scores
  • suggest_merge (boolean) - Suggest primary contact for merging
  • per_page (integer) - Results per page

Example - Find Email Duplicates:

bash
GET /api/v1/crm/contacts/duplicates?match_by=email&include_confidence=true&suggest_merge=true

Response (200 OK):

json
{
  "data": [
    {
      "match_criteria": "email",
      "match_value": "john.smith@acmecorp.com",
      "contacts": [
        {
          "id": 123,
          "first_name": "John",
          "last_name": "Smith",
          "email": "john.smith@acmecorp.com",
          "phone": "+1-555-0200",
          "created_at": "2025-01-15T10:00:00Z"
        },
        {
          "id": 145,
          "first_name": "John",
          "last_name": "Smith",
          "email": "john.smith@acmecorp.com",
          "phone": "+1-555-0201",
          "created_at": "2025-06-20T14:00:00Z"
        }
      ],
      "confidence_score": 85.0,
      "suggested_primary_id": 123,
      "merge_reason": "Oldest contact with is_primary flag"
    }
  ],
  "meta": {
    "current_page": 1,
    "total": 12,
    "per_page": 15
  }
}

Example - Fuzzy Name Matching:

bash
GET /api/v1/crm/contacts/duplicates?match_by=name&fuzzy=true

This will find contacts like:

  • "John Smith" and "Jon Smith" (typo)
  • "Robert Johnson" and "Bob Johnson" (nickname)
  • "Mary Anne" and "Mary Ann" (spelling variation)

Merging Contacts

Endpoint: POST /api/v1/crm/contacts/merge

Request Body:

json
{
  "primary_contact_id": 123,
  "duplicate_contact_ids": [145, 167],
  "merge_strategy": "keep_primary",
  "field_preferences": {
    "phone": "primary",
    "mobile": "duplicate_145",
    "notes": "combine"
  },
  "transfer_activities": true,
  "delete_duplicates": true
}

Merge Strategies:

  • keep_primary - Keep all primary contact data, discard duplicates
  • keep_newest - Keep most recently updated data
  • manual - Specify field preferences explicitly

Response (200 OK):

json
{
  "message": "Contacts merged successfully",
  "data": {
    "merged_contact_id": 123,
    "merged_from_ids": [145, 167],
    "activities_transferred": 23,
    "opportunities_updated": 2,
    "duplicates_deleted": true,
    "merge_summary": {
      "fields_from_primary": 12,
      "fields_from_duplicates": 3,
      "fields_combined": 2
    }
  }
}

Bulk Operations

Endpoint: POST /api/v1/crm/contacts/bulk-actions

Supported Actions:

  • update_status - Change status for multiple contacts
  • assign_customer - Assign contacts to customer
  • add_tags - Add tags to contacts
  • remove_tags - Remove tags
  • delete - Delete multiple contacts

Example - Update Status:

json
{
  "action": "update_status",
  "contact_ids": [123, 124, 125],
  "parameters": {
    "status": "inactive",
    "reason": "Company restructuring - contacts no longer relevant"
  }
}

Response (200 OK):

json
{
  "message": "Bulk action completed successfully",
  "data": {
    "action": "update_status",
    "processed": 3,
    "successful": 3,
    "failed": 0
  }
}

Business Scenarios

Scenario 1: Mapping Organization Structure

Context: Enterprise customer with multiple stakeholders

Workflow:

bash
# 1. Create decision makers
POST /api/v1/crm/contacts
{
  "first_name": "Sarah",
  "last_name": "CEO",
  "title": "Chief Executive Officer",
  "email": "sarah.ceo@bigcorp.com",
  "customer_id": 570,
  "role": "decision_maker",
  "is_primary": true,
  "department": "Executive",
  "tags": ["executive", "final-authority"]
}

POST /api/v1/crm/contacts
{
  "first_name": "Michael",
  "last_name": "CFO",
  "title": "Chief Financial Officer",
  "email": "michael.cfo@bigcorp.com",
  "customer_id": 570,
  "role": "decision_maker",
  "department": "Finance",
  "tags": ["executive", "budget-authority"]
}

# 2. Create champion/influencer
POST /api/v1/crm/contacts
{
  "first_name": "David",
  "last_name": "Director",
  "title": "Director of IT",
  "email": "david.director@bigcorp.com",
  "customer_id": 570,
  "role": "champion",
  "department": "IT",
  "tags": ["champion", "technical", "advocate"],
  "notes": "Internal champion. Strong advocate for our solution. Key to driving adoption."
}

# 3. Create end users
POST /api/v1/crm/contacts
{
  "first_name": "Jennifer",
  "last_name": "Manager",
  "title": "Operations Manager",
  "email": "jennifer.manager@bigcorp.com",
  "customer_id": 570,
  "role": "user",
  "department": "Operations",
  "tags": ["end-user", "power-user"]
}

Scenario 2: Handling Contact Changes

Context: Contact changed roles or left company

Workflow:

bash
# Scenario A: Contact promoted
PATCH /api/v1/crm/contacts/123
{
  "title": "Senior Vice President, Technology",
  "department": "Executive",
  "role": "decision_maker",
  "notes": "Promoted from CTO to SVP Technology. Now reports directly to CEO. Expanded authority over all technical decisions."
}

# Scenario B: Contact left company
POST /api/v1/crm/contacts/124/deactivate
{
  "reason": "Left company for new opportunity"
}

# Create replacement contact
POST /api/v1/crm/contacts
{
  "first_name": "New",
  "last_name": "Person",
  "title": "Chief Technology Officer",
  "email": "new.person@acmecorp.com",
  "customer_id": 568,
  "role": "decision_maker",
  "is_primary": true,
  "notes": "Replaced John Smith who left company. Need to rebuild relationship and understand priorities.",
  "tags": ["new-contact", "relationship-building"]
}

# Update customer notes
PATCH /api/v1/crm/customers/568
{
  "notes": "Key contact change: John Smith (CTO) left company, replaced by New Person. Need to re-establish relationship and understand any strategy changes."
}

Scenario 3: Cleaning Up Duplicates

Context: Quarterly data cleanup - find and merge duplicates

Workflow:

bash
# 1. Find email duplicates
GET /api/v1/crm/contacts/duplicates?match_by=email&include_confidence=true&suggest_merge=true

# 2. Find phone duplicates
GET /api/v1/crm/contacts/duplicates?match_by=phone&include_confidence=true

# 3. Find fuzzy name matches
GET /api/v1/crm/contacts/duplicates?match_by=name&fuzzy=true

# 4. Review suggested merges and merge
POST /api/v1/crm/contacts/merge
{
  "primary_contact_id": 123,
  "duplicate_contact_ids": [145],
  "merge_strategy": "keep_primary",
  "transfer_activities": true,
  "delete_duplicates": true
}

# 5. Bulk cleanup obviously inactive contacts
POST /api/v1/crm/contacts/bulk-actions
{
  "action": "delete",
  "contact_ids": [150, 151, 152],
  "reason": "Duplicate contacts with no associated activities"
}

Best Practices

1. Complete Contact Information

Always Capture:

  • Full name (first and last)
  • Job title (specific, not generic)
  • Direct email (not shared mailbox)
  • Direct phone/mobile
  • Department
  • Role in buying process
  • Reporting structure

2. Identify Decision Roles

Map the Decision Unit:

  • Economic Buyer (budget authority)
  • Technical Buyer (technical approval)
  • Champion (internal advocate)
  • Influencers (input providers)
  • Users (end users)
  • Blockers (potential objectors)

3. Keep Contacts Current

Regular Updates:

  • Monitor for job changes (LinkedIn)
  • Update after significant interactions
  • Deactivate departed contacts
  • Add new contacts as discovered
  • Update communication preferences

4. Prevent Duplicates

Prevention Strategies:

  • Search before creating
  • Use email as unique identifier
  • Standardize naming conventions
  • Regular duplicate scans
  • Team training on data entry

5. Document Relationships

Track:

  • Who reports to whom
  • Who influences decisions
  • Personal relationships
  • Historical context
  • Communication preferences
  • Best practices for engagement

Integration Points

With Customer Module

  • Contacts linked to customers
  • Customer activities include contact interactions
  • Customer health influenced by contact engagement

With Opportunity Module

  • Opportunities specify decision makers
  • Contact activities tracked per opportunity
  • Stakeholder mapping for complex deals

With Activity Module

  • All activities reference specific contacts
  • Contact timeline shows all interactions
  • Communication history preserved

Documentation for SynthesQ CRM/ERP Platform