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.
When you send a message to a new recipient, Zavu automatically:
- Creates a contact record
- Detects the country from the phone number
- Determines available messaging channels
- 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"
| Property | Description |
|---|
id | Unique contact identifier |
phoneNumber | E.164 formatted phone number |
countryCode | Two-letter country code (e.g., “US”) |
profileName | WhatsApp display name (if available) |
availableChannels | Channels this contact can receive (sms, whatsapp, etc.) |
defaultChannel | Preferred channel for auto-routing |
verified | Whether the contact has been verified |
metadata | Custom key-value data |
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"
}
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.
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 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
| Field | Description |
|---|
defaultChannel | Preferred channel for smart routing (sms, whatsapp, telegram, email) |
metadata | Custom 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.
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:
| Channel | When Available |
|---|
sms | Valid mobile or landline number |
whatsapp | Contact has WhatsApp (detected on first message or reply) |
telegram | Contact has connected via Telegram bot |
email | Contact 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