Skip to content

Contacts API

The Contacts API allows you to manage contacts in your workspace. Contacts represent users, customers, or any individuals you interact with through your Cognipeer AI agents.

Authentication

Important: The Contacts API supports both authentication methods:

  • Personal Access Token (PAT) - For server-side applications
  • API Token (hookId) - For API channel-based access

This dual authentication support makes the Contacts API unique among SDK endpoints, allowing it to be used in both traditional server applications and API channel integrations.

Available Methods

contacts.create(options)

Create a new contact in your workspace.

Parameters:

  • options (CreateContactOptions):
    • email? (string): Contact's email address
    • integrationId? (string): External system identifier
    • name? (string): Contact's full name
    • phone? (string): Contact's phone number
    • metadata? (object): Additional metadata
    • properties? (object): Custom properties
    • tags? (string[]): Contact tags
    • status? (string): Contact status
    • Additional custom fields as needed

Returns: Promise<Contact>

Example:

typescript
const contact = await client.contacts.create({
  email: 'john.doe@example.com',
  name: 'John Doe',
  phone: '+1234567890',
  properties: {
    company: 'ACME Corp',
    position: 'CEO'
  },
  tags: ['vip', 'enterprise'],
  status: 'active'
});

console.log(`Created contact: ${contact._id}`);

With API Token:

typescript
// When using hookId for authentication
const client = new CognipeerClient({
  token: 'your-api-token',
  hookId: 'your-channel-hook-id'
});

const contact = await client.contacts.create({
  email: 'api-user@example.com',
  name: 'API User',
  integrationId: 'external-id-123'
});

contacts.get(options)

Retrieve a contact by email or integration ID.

Parameters:

  • options (GetContactOptions):
    • email? (string): Find contact by email
    • integrationId? (string): Find contact by integration ID

Note: Either email or integrationId must be provided.

Returns: Promise<Contact>

Example:

typescript
// Find by email
const contact = await client.contacts.get({ 
  email: 'john.doe@example.com' 
});

console.log(`Found contact: ${contact.name}`);
typescript
// Find by integration ID
const contact = await client.contacts.get({ 
  integrationId: 'ext-12345' 
});

console.log(`Contact email: ${contact.email}`);

Error Handling:

typescript
try {
  const contact = await client.contacts.get({ 
    email: 'nonexistent@example.com' 
  });
} catch (error) {
  if (error.message.includes('not found')) {
    console.log('Contact does not exist');
  }
}

contacts.update(options)

Update an existing contact by email or integration ID.

Parameters:

  • options (UpdateContactOptions):
    • email? (string): Identify contact by email
    • integrationId? (string): Identify contact by integration ID
    • data (object): Fields to update
      • name? (string): Update contact name
      • email? (string): Update email address
      • phone? (string): Update phone number
      • metadata? (object): Update metadata
      • properties? (object): Update custom properties
      • tags? (string[]): Update tags
      • status? (string): Update status
      • Additional custom fields

Note: Either email or integrationId must be provided to identify the contact.

Returns: Promise<Contact>

Example:

typescript
// Update by email
const updatedContact = await client.contacts.update({
  email: 'john.doe@example.com',
  data: {
    name: 'John Smith',
    phone: '+1987654321',
    properties: {
      company: 'New Corp',
      position: 'CTO'
    },
    tags: ['vip', 'enterprise', 'technical']
  }
});

console.log(`Updated: ${updatedContact.name}`);
typescript
// Update by integration ID
const updatedContact = await client.contacts.update({
  integrationId: 'ext-12345',
  data: {
    status: 'inactive',
    metadata: {
      lastInteraction: new Date().toISOString()
    }
  }
});

Partial Updates:

typescript
// Only update specific fields
await client.contacts.update({
  email: 'john.doe@example.com',
  data: {
    tags: ['premium'] // Only updates tags, leaves other fields unchanged
  }
});

contacts.list(options)

List contacts with pagination and filtering.

Parameters:

  • options? (ListContactsOptions):
    • page? (number): Page number (default: 1)
    • limit? (number): Items per page (default: 10)
    • filter? (object): Filter criteria
    • sort? (object): Sort options (e.g., { createdDate: -1 })

Returns: Promise<PaginatedResponse<Contact>>

Example:

typescript
// Basic listing
const result = await client.contacts.list({
  page: 1,
  limit: 20
});

console.log(`Total contacts: ${result.total}`);
console.log(`Page ${result.page} of ${Math.ceil(result.total / result.limit)}`);

result.data.forEach(contact => {
  console.log(`${contact.name} <${contact.email}>`);
});

With Filtering:

typescript
// Filter by status
const activeContacts = await client.contacts.list({
  page: 1,
  limit: 50,
  filter: {
    status: 'active',
    deleted: { $ne: true }
  },
  sort: { createdDate: -1 }
});

Advanced Filtering:

typescript
// Complex filters
const vipContacts = await client.contacts.list({
  filter: {
    tags: { $in: ['vip', 'enterprise'] },
    'properties.company': { $exists: true }
  },
  sort: { 'properties.company': 1 }
});

Pagination Loop:

typescript
// Fetch all contacts
const allContacts = [];
let page = 1;
let hasMore = true;

while (hasMore) {
  const result = await client.contacts.list({ page, limit: 100 });
  allContacts.push(...result.data);
  
  hasMore = page * result.limit < result.total;
  page++;
}

console.log(`Loaded ${allContacts.length} total contacts`);

Authentication Examples

Using Personal Access Token (PAT)

typescript
import { CognipeerClient } from '@cognipeer/sdk';

const client = new CognipeerClient({
  token: 'pat_your_personal_access_token',
  hookId: 'your-hook-id'
});

// All contact operations work with PAT
const contact = await client.contacts.create({
  email: 'user@example.com',
  name: 'User Name'
});

Using API Token (hookId-based)

typescript
import { CognipeerClient } from '@cognipeer/sdk';

const client = new CognipeerClient({
  token: 'your-api-token',
  hookId: 'your-channel-hook-id'
});

// Same methods work with API token
const contact = await client.contacts.get({
  email: 'user@example.com'
});

Type Definitions

Contact

typescript
interface Contact {
  _id: string;
  email?: string;
  integrationId?: string;
  name?: string;
  phone?: string;
  metadata?: Record<string, any>;
  properties?: Record<string, any>;
  workspaceId: string;
  peerId?: string;
  tags?: string[];
  status?: string;
  createdDate?: string;
  modifiedDate?: string;
  deleted?: boolean;
  [key: string]: any;
}

CreateContactOptions

typescript
interface CreateContactOptions {
  email?: string;
  integrationId?: string;
  name?: string;
  phone?: string;
  metadata?: Record<string, any>;
  properties?: Record<string, any>;
  tags?: string[];
  status?: string;
  [key: string]: any;
}

GetContactOptions

typescript
interface GetContactOptions {
  email?: string;
  integrationId?: string;
}

UpdateContactOptions

typescript
interface UpdateContactOptions {
  email?: string;
  integrationId?: string;
  data: {
    name?: string;
    email?: string;
    phone?: string;
    metadata?: Record<string, any>;
    properties?: Record<string, any>;
    tags?: string[];
    status?: string;
    [key: string]: any;
  };
}

ListContactsOptions

typescript
interface ListContactsOptions {
  page?: number;
  limit?: number;
  filter?: Record<string, any>;
  sort?: Record<string, 1 | -1>;
}

PaginatedResponse

typescript
interface PaginatedResponse<T> {
  success: boolean;
  data: T[];
  total: number;
  page: number;
  limit: number;
}

Use Cases

Customer Relationship Management

typescript
// Create a new customer contact
const customer = await client.contacts.create({
  email: 'customer@company.com',
  name: 'Jane Customer',
  phone: '+1555000000',
  properties: {
    company: 'Customer Corp',
    industry: 'Technology',
    lifetimeValue: 50000
  },
  tags: ['customer', 'paid'],
  status: 'active'
});

// Later, update their status
await client.contacts.update({
  email: 'customer@company.com',
  data: {
    status: 'vip',
    tags: ['customer', 'paid', 'vip'],
    properties: {
      ...customer.properties,
      lifetimeValue: 100000
    }
  }
});

External System Integration

typescript
// Sync contact from external CRM
async function syncContact(externalContact) {
  try {
    // Check if contact exists
    const existing = await client.contacts.get({
      integrationId: externalContact.id
    });
    
    // Update existing contact
    return await client.contacts.update({
      integrationId: externalContact.id,
      data: {
        name: externalContact.name,
        email: externalContact.email,
        metadata: {
          lastSync: new Date().toISOString(),
          source: 'external-crm'
        }
      }
    });
  } catch (error) {
    // Contact doesn't exist, create it
    return await client.contacts.create({
      integrationId: externalContact.id,
      name: externalContact.name,
      email: externalContact.email,
      metadata: {
        source: 'external-crm'
      }
    });
  }
}

Contact Search and Reporting

typescript
// Generate contact report
async function generateContactReport() {
  const activeContacts = await client.contacts.list({
    page: 1,
    limit: 1000,
    filter: { status: 'active' },
    sort: { createdDate: -1 }
  });
  
  const report = {
    total: activeContacts.total,
    byTag: {},
    byStatus: {},
    recentlyAdded: activeContacts.data.slice(0, 10)
  };
  
  activeContacts.data.forEach(contact => {
    // Count by tags
    contact.tags?.forEach(tag => {
      report.byTag[tag] = (report.byTag[tag] || 0) + 1;
    });
    
    // Count by status
    report.byStatus[contact.status] = 
      (report.byStatus[contact.status] || 0) + 1;
  });
  
  return report;
}

Error Handling

typescript
import { CognipeerClient } from '@cognipeer/sdk';

async function safeContactOperation() {
  try {
    const contact = await client.contacts.get({
      email: 'user@example.com'
    });
    
    return contact;
  } catch (error) {
    if (error.message.includes('not found')) {
      console.log('Contact does not exist, creating new one');
      
      return await client.contacts.create({
        email: 'user@example.com',
        name: 'New User'
      });
    }
    
    if (error.message.includes('Authorization')) {
      console.error('Invalid credentials');
    }
    
    throw error; // Re-throw unexpected errors
  }
}

Best Practices

  1. Use integrationId for external systems: When syncing with external systems, always use integrationId to maintain references.

  2. Implement retry logic: Network requests can fail, implement exponential backoff for production use.

  3. Validate data before creation: Ensure email format and required fields are valid before creating contacts.

  4. Use pagination efficiently: Don't fetch all contacts at once, use reasonable page sizes (10-100).

  5. Handle errors gracefully: Always wrap contact operations in try-catch blocks.

  6. Store credentials securely: Never hardcode API tokens, use environment variables.

  7. Use appropriate authentication: Choose PAT for server-side apps, API tokens for channel-based integrations.


Released under the MIT License.