Omnix

Contact Schema & Merge Rules

This document details the structure of the ContactInfo object used in the findOrCreateContact endpoint and other messaging API methods. It also explains how the system handles duplicates and merges profiles when overlapping identifiers are detected.


Contact Schema Structure

A contact record consists of three main blocks: Identifiers, Profile, and Context.

{
  "contactId": "con_789012",
  "identifiers": {
    "phone": "+15551234567",
    "email": "[email protected]",
    "externalId": "ext_cust_9481"
  },
  "profile": {
    "firstName": "John",
    "lastName": "Doe",
    "avatarUrl": "https://example.com/avatars/johndoe.png"
  },
  "context": {
    "tier": "gold",
    "signupDate": "2026-01-15T08:00:00Z",
    "accountManager": "usr_agent_42"
  }
}

1. Identifiers (Match Keys)

Identifiers are the unique keys used to look up existing contact records in your workspace.

  • phone: Must be in standard E.164 format. Used for SMS, WhatsApp, and Voice matching.
  • email: Must be a valid email format. Used for Email channel matching.
  • externalId: A custom ID from your external CRM or database (e.g. Salesforce Contact ID, your internal User ID).

2. Profile (Display details)

Contains standard display fields used by agents in the Unified Inbox.

  • firstName, lastName: Display name details.
  • avatarUrl: Custom profile image.

3. Context (Metadata)

An open-ended dictionary (Record<string, any>) of custom attributes. You can store any structured JSON here (e.g. tier, membership type, active cart items). These are visible inside the Omnix agent interface and can be used in Workflow Automations.


Merge Rules

When you call findOrCreateContact, Omnix queries existing contacts by matching against any of the provided identifiers:

                  [ Call findOrCreateContact ]
                               |
            Does any identifier (phone/email/externalId)
                 match an existing record?
                /                         \
             [YES]                        [NO]
               |                            |
       Match found.                 Create new contact.
   Apply updates & merge.

Overwrite vs. Append behavior:

  1. Identifiers: If a matched contact is missing an identifier that you provided in the API call (e.g., they had a phone but no email, and you provided both), the new identifier is appended to their record.
  2. Profile: Existing profile fields are only overwritten if the new payload contains non-empty values.
  3. Context: Key-value pairs are shallow-merged. New keys are added; existing keys are updated with the new values. Other existing keys are left unchanged.

Conflict Resolution

If a call to findOrCreateContact provides two identifiers that belong to two separate contacts (e.g., phone belongs to Contact A, while email belongs to Contact B), the system will:

  1. Match the contact based on the externalId first if provided.
  2. Fall back to matching the phone number first.
  3. Keep the records separate and log a warning on the matched profile indicating a potential identifier conflict. Contacts are not automatically merged to prevent data pollution.