Skip to main content
Contacts are automatically created when you send messages. Each contact represents a unique recipient (phone number or email) and stores metadata about their messaging preferences and history.

How Contacts Work

When you send a message to a new recipient, Zavu automatically:
  1. Creates a contact record
  2. Detects the country from the phone number
  3. Determines available messaging channels
  4. Captures the WhatsApp profile name (if available)
// Sending to a new recipient creates a contact
const message = await zavu.messages.send({
  to: "+14155551234",
  text: "Welcome!",
});

// Contact is now available
const contact = await zavu.contacts.getByPhone("+14155551234");
console.log(contact.id); // "con_abc123"

Contact Properties

PropertyDescription
idUnique contact identifier
phoneNumberE.164 formatted phone number
countryCodeTwo-letter country code (e.g., “US”)
profileNameWhatsApp display name (if available)
availableChannelsChannels this contact can receive (sms, whatsapp, etc.)
defaultChannelPreferred channel for auto-routing
verifiedWhether the contact has been verified
metadataCustom key-value data

Get Contact by ID

import Zavudev from '@zavudev/sdk';

const zavu = new Zavudev();

const contact = await zavu.contacts.get("con_abc123");

console.log(`Phone: ${contact.phoneNumber}`);
console.log(`Country: ${contact.countryCode}`);
console.log(`Channels: ${contact.availableChannels.join(", ")}`);
console.log(`Profile: ${contact.profileName || "Unknown"}`);

Response

{
  "id": "con_abc123",
  "phoneNumber": "+14155551234",
  "countryCode": "US",
  "profileName": "John Doe",
  "availableChannels": ["sms", "whatsapp"],
  "defaultChannel": "whatsapp",
  "verified": true,
  "metadata": {
    "tier": "premium",
    "source": "website"
  },
  "createdAt": "2024-01-15T10:30:00.000Z",
  "updatedAt": "2024-01-15T12:00:00.000Z"
}

Get Contact by Phone Number

Look up a contact using their phone number:
const contact = await zavu.contacts.getByPhone("+14155551234");

if (contact) {
  console.log(`Found contact: ${contact.id}`);
  console.log(`Available channels: ${contact.availableChannels}`);
} else {
  console.log("Contact not found");
}
Use this endpoint to check if a recipient already exists before sending messages, or to retrieve their metadata for personalization.

List Contacts

Retrieve all contacts with pagination:
// List all contacts
const { items, nextCursor } = await zavu.contacts.list({
  limit: 50,
});

for (const contact of items) {
  console.log(`${contact.id}: ${contact.phoneNumber}`);
}

// Paginate through all contacts
let cursor: string | undefined;
const allContacts = [];

do {
  const result = await zavu.contacts.list({ cursor, limit: 100 });
  allContacts.push(...result.items);
  cursor = result.nextCursor ?? undefined;
} while (cursor);

console.log(`Total contacts: ${allContacts.length}`);

Filter by Phone Number

Search for contacts matching a phone number prefix:
// Find all contacts with US country code
const { items } = await zavu.contacts.list({
  phoneNumber: "+1",
  limit: 50,
});

Update Contact

Update a contact’s default channel or metadata:
const contact = await zavu.contacts.update("con_abc123", {
  defaultChannel: "whatsapp",
  metadata: {
    name: "John Doe",
    tier: "premium",
    source: "mobile_app",
  },
});

console.log(`Updated default channel: ${contact.defaultChannel}`);

Updateable Fields

FieldDescription
defaultChannelPreferred channel for smart routing (sms, whatsapp, telegram, email)
metadataCustom key-value pairs (merged with existing metadata)
Setting defaultChannel affects smart routing. When you send a message with channel: "auto", Zavu will prefer the contact’s default channel.

Contact Metadata

Store custom data on contacts for personalization and segmentation:
// Add customer data
await zavu.contacts.update("con_abc123", {
  metadata: {
    customerId: "cust_12345",
    plan: "enterprise",
    signupDate: "2024-01-15",
    preferredLanguage: "es",
  },
});

// Use in messages
const contact = await zavu.contacts.get("con_abc123");
const message = await zavu.messages.send({
  to: contact.phoneNumber,
  text: `Hola ${contact.metadata?.customerId}! Your ${contact.metadata?.plan} plan is active.`,
});
Metadata values must be strings. Store complex data as JSON strings if needed.

Available Channels

The availableChannels array indicates which channels can reach this contact:
ChannelWhen Available
smsValid mobile or landline number
whatsappContact has WhatsApp (detected on first message or reply)
telegramContact has connected via Telegram bot
emailContact has email address on file
const contact = await zavu.contacts.get("con_abc123");

if (contact.availableChannels.includes("whatsapp")) {
  // Send via WhatsApp for richer experience
  await zavu.messages.send({
    to: contact.phoneNumber,
    channel: "whatsapp",
    text: "Hello via WhatsApp!",
  });
} else {
  // Fall back to SMS
  await zavu.messages.send({
    to: contact.phoneNumber,
    channel: "sms",
    text: "Hello via SMS!",
  });
}

Phone Number Introspection

Validate a phone number and check available channels without creating a contact:
const result = await zavu.introspect.phone({
  phoneNumber: "+14155551234",
});

console.log(`Valid: ${result.validNumber}`);
console.log(`Country: ${result.countryCode}`);
console.log(`Format: ${result.nationalFormat}`);
console.log(`Type: ${result.lineType}`);
console.log(`Carrier: ${result.carrier?.name}`);
console.log(`Channels: ${result.availableChannels}`);

Response

{
  "phoneNumber": "+14155551234",
  "countryCode": "US",
  "validNumber": true,
  "nationalFormat": "(415) 555-1234",
  "lineType": "mobile",
  "carrier": {
    "name": "Verizon Wireless",
    "type": "mobile"
  },
  "availableChannels": ["sms", "whatsapp"]
}
Use introspection to validate phone numbers before adding them to broadcasts or CRM systems.

Complete Example

import Zavudev from '@zavudev/sdk';

const zavu = new Zavudev();

async function processNewCustomer(phone: string, customerData: {
  name: string;
  email: string;
  plan: string;
}) {
  // 1. Validate the phone number
  const introspection = await zavu.introspect.phone({ phoneNumber: phone });

  if (!introspection.validNumber) {
    throw new Error("Invalid phone number");
  }

  console.log(`Valid ${introspection.lineType} number from ${introspection.countryCode}`);

  // 2. Send welcome message (creates contact automatically)
  const message = await zavu.messages.send({
    to: phone,
    channel: "auto", // Smart routing based on available channels
    text: `Welcome ${customerData.name}! Your ${customerData.plan} account is ready.`,
  });

  console.log(`Welcome message sent: ${message.id}`);

  // 3. Update contact with customer data
  const contact = await zavu.contacts.getByPhone(phone);

  await zavu.contacts.update(contact.id, {
    defaultChannel: introspection.availableChannels.includes("whatsapp")
      ? "whatsapp"
      : "sms",
    metadata: {
      name: customerData.name,
      email: customerData.email,
      plan: customerData.plan,
      signupDate: new Date().toISOString(),
    },
  });

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

  return contact;
}

// Usage
processNewCustomer("+14155551234", {
  name: "John Doe",
  email: "john@example.com",
  plan: "premium",
});

Next Steps