Skip to main content

Manage Contacts

Create, update, and organize your customer contacts.

Contact Overview

A contact represents a customer you communicate with. Contacts can have:

  • Phone number (E.164 format)
  • Email address
  • Name (first, last, full)
  • Preferred channel
  • Custom metadata
  • Status (active, inactive, deleted)

Creating Contacts

Basic Contact

curl -X POST https://api.huechat.ai/v2/contact \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"phone": "+1234567890",
"first_name": "John",
"last_name": "Doe"
}'

Contact with Metadata

Store custom fields in the metadata object:

curl -X POST https://api.huechat.ai/v2/contact \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"phone": "+1234567890",
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"preferred_channel": "whatsapp",
"metadata": {
"customer_id": "cust_abc123",
"plan": "premium",
"signup_date": "2026-01-15",
"source": "website"
}
}'

Response

{
"id": "cnt_1a2b3c4d5e6f",
"phone": "+1234567890",
"email": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"full_name": "John Doe",
"preferred_channel": "whatsapp",
"metadata": {
"customer_id": "cust_abc123",
"plan": "premium",
"signup_date": "2026-01-15",
"source": "website"
},
"status": "active",
"created_at": "2026-01-25T10:30:00Z",
"updated_at": "2026-01-25T10:30:00Z",
"last_contacted": null
}

Retrieving Contacts

By ID

curl https://api.huechat.ai/v2/contact/cnt_1a2b3c4d5e6f \
-H "X-API-Key: sk_live_your_key"

By Phone Number

URL-encode the + as %2B:

curl https://api.huechat.ai/v2/contact/%2B1234567890 \
-H "X-API-Key: sk_live_your_key"

By Email

curl https://api.huechat.ai/v2/contact/john@example.com \
-H "X-API-Key: sk_live_your_key"

Updating Contacts

Only include fields you want to update:

curl -X PUT https://api.huechat.ai/v2/contact/cnt_1a2b3c4d5e6f \
-H "X-API-Key: sk_live_your_key" \
-H "Content-Type: application/json" \
-d '{
"email": "john.doe@newcompany.com",
"metadata": {
"plan": "enterprise",
"company": "New Company Inc"
}
}'

Updating Metadata

Metadata is merged, not replaced:

# Original metadata: { "plan": "premium", "source": "website" }

curl -X PUT https://api.huechat.ai/v2/contact/cnt_123 \
-H "X-API-Key: sk_live_your_key" \
-d '{"metadata": {"plan": "enterprise"}}'

# Result metadata: { "plan": "enterprise", "source": "website" }

To remove a metadata field, set it to null:

curl -X PUT https://api.huechat.ai/v2/contact/cnt_123 \
-H "X-API-Key: sk_live_your_key" \
-d '{"metadata": {"source": null}}'

Deleting Contacts

curl -X DELETE https://api.huechat.ai/v2/contact/cnt_1a2b3c4d5e6f \
-H "X-API-Key: sk_live_your_key"
warning

Deleting a contact also deletes all associated conversations and messages.

Get Contact Conversations

Retrieve all conversations for a contact:

curl "https://api.huechat.ai/v2/contact/cnt_123/conversations?status=open" \
-H "X-API-Key: sk_live_your_key"

Query Parameters

ParameterTypeDescription
statusstringFilter by status: open, closed, archived
channelstringFilter by channel: whatsapp, instagram, sms, email
limitintegerResults per page (max 100)
offsetintegerPagination offset

Contact Lookup Strategies

Upsert Pattern

Find or create a contact:

async function findOrCreateContact(phone, data) {
try {
// Try to find existing contact
return await client.contacts.get(phone);
} catch (error) {
if (error.code === 404) {
// Create new contact
return await client.contacts.create({
phone,
...data
});
}
throw error;
}
}

Search Before Create

Avoid duplicates by checking first:

def ensure_contact(phone, email, name):
# Try phone first
try:
return client.contacts.get(phone)
except NotFoundError:
pass

# Try email
try:
return client.contacts.get(email)
except NotFoundError:
pass

# Create new
return client.contacts.create({
'phone': phone,
'email': email,
'first_name': name
})

Using Metadata Effectively

Common Metadata Fields

{
"metadata": {
"customer_id": "cust_123",
"company": "Acme Inc",
"plan": "enterprise",
"mrr": 500,
"signup_date": "2026-01-15",
"source": "referral",
"referrer": "partner_abc",
"tags": ["vip", "early_adopter"],
"preferences": {
"language": "en",
"timezone": "America/New_York",
"marketing_opt_in": true
}
}
}

Syncing with Your CRM

// When a contact is updated in your CRM
async function syncContactToHueChat(crmContact) {
await client.contacts.update(crmContact.phone, {
first_name: crmContact.firstName,
last_name: crmContact.lastName,
email: crmContact.email,
metadata: {
crm_id: crmContact.id,
company: crmContact.company,
deal_stage: crmContact.dealStage,
last_synced: new Date().toISOString()
}
});
}

Phone Number Format

Always use E.164 format:

CorrectIncorrect
+12345678901234567890
+44791112345607911123456
+49123456789001234567890

Formatting Helper

function formatPhoneE164(phone, defaultCountry = '1') {
// Remove all non-digits
let digits = phone.replace(/\D/g, '');

// Add country code if missing
if (!phone.startsWith('+')) {
digits = defaultCountry + digits;
}

return '+' + digits;
}

Error Handling

Duplicate Contact

{
"error": "duplicate_contact",
"message": "A contact with this phone number already exists",
"code": 409,
"details": {
"existing_contact_id": "cnt_abc123"
}
}

Invalid Phone Format

{
"error": "invalid_input",
"message": "Phone number must be in E.164 format",
"code": 400,
"details": {
"field": "phone",
"received": "1234567890",
"expected": "+1234567890"
}
}