Contacts
The Contacts API lets you verify phone numbers on WhatsApp, retrieve contact information, and fetch profile pictures. This is especially useful for validating numbers before sending messages and enriching your contact data.
All contact endpoints are scoped to a specific instance:
/api/instances/{instanceId}/contacts/...
Check if a Number Exists
Verify whether a phone number is registered on WhatsApp before sending a message. This prevents failed deliveries and wasted API calls.
curl "https://api.wappfy.io/api/instances/inst_abc123/contacts/check?phone=5511999998888" \
-H "X-Api-Key: YOUR_API_KEY"
Response (number exists):
{
"data": {
"exists": true,
"phone": "5511999998888",
"chat_id": "[email protected]"
}
}
Response (number does not exist):
{
"data": {
"exists": false,
"phone": "5511999998888",
"chat_id": null
}
}
Use this endpoint to validate numbers before sending messages. It saves on message quota and prevents message.failed webhook events.
Retrieve the full contact list for the connected WhatsApp account.
curl https://api.wappfy.io/api/instances/inst_abc123/contacts \
-H "X-Api-Key: YOUR_API_KEY"
Response:
{
"data": [
{
"id": "[email protected]",
"name": "Maria Silva",
"short_name": "Maria",
"push_name": "Mari",
"is_business": false
},
{
"id": "[email protected]",
"name": "Carlos Oliveira",
"short_name": "Carlos",
"push_name": "Carlos",
"is_business": true
}
]
}
| Field | Description |
|---|
id | The contact’s WhatsApp ID (phone number + @s.whatsapp.net). |
name | Contact name as saved in the phone’s address book. May be null if not saved. |
short_name | Short name from the address book. |
push_name | The name the contact has set for themselves on WhatsApp. |
is_business | Whether this is a WhatsApp Business account. |
The name field comes from your phone’s address book. If the contact is not saved, only push_name (set by the contact themselves) will be available.
Retrieve detailed information about a specific contact.
curl "https://api.wappfy.io/api/instances/inst_abc123/contacts/[email protected]" \
-H "X-Api-Key: YOUR_API_KEY"
Response:
{
"data": {
"id": "[email protected]",
"name": "Maria Silva",
"short_name": "Maria",
"push_name": "Mari",
"is_business": false
}
}
Get Profile Picture
Retrieve a contact’s WhatsApp profile picture URL.
curl "https://api.wappfy.io/api/instances/inst_abc123/contacts/[email protected]/profile-picture" \
-H "X-Api-Key: YOUR_API_KEY"
Response:
{
"data": {
"profile_picture_url": "https://pps.whatsapp.net/v/t61.24694-24/..."
}
}
Profile picture URLs are temporary and expire after some time. Do not store them permanently — fetch a fresh URL when needed.
If the contact has no profile picture or has restricted visibility in their privacy settings, the profile_picture_url will be null:
{
"data": {
"profile_picture_url": null
}
}
Common Patterns
Validate Before Sending
Always check if a number exists on WhatsApp before sending a message to avoid unnecessary failures:
async function sendMessageSafely(instanceId, phone, text) {
// Step 1: Check if the number is on WhatsApp
const checkResponse = await fetch(
`https://api.wappfy.io/api/instances/${instanceId}/contacts/check?phone=${phone}`,
{ headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const { data: checkResult } = await checkResponse.json();
if (!checkResult.exists) {
console.log(`${phone} is not on WhatsApp, skipping`);
return null;
}
// Step 2: Send the message using the confirmed chat_id
const sendResponse = await fetch(
`https://api.wappfy.io/api/instances/${instanceId}/messages/send`,
{
method: "POST",
headers: {
"X-Api-Key": "YOUR_API_KEY",
"Content-Type": "application/json",
},
body: JSON.stringify({
chat_id: checkResult.chat_id,
type: "text",
text,
}),
}
);
return sendResponse.json();
}
Fetch all contacts and enrich them with profile pictures:
async function buildContactDirectory(instanceId) {
// Get all contacts
const contactsRes = await fetch(
`https://api.wappfy.io/api/instances/${instanceId}/contacts`,
{ headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const { data: contacts } = await contactsRes.json();
// Enrich with profile pictures (batch with delay to avoid rate limits)
const enriched = [];
for (const contact of contacts) {
const picRes = await fetch(
`https://api.wappfy.io/api/instances/${instanceId}/contacts/${contact.id}/profile-picture`,
{ headers: { "X-Api-Key": "YOUR_API_KEY" } }
);
const { data: pic } = await picRes.json();
enriched.push({
...contact,
profile_picture_url: pic.profile_picture_url,
});
// Small delay to respect rate limits
await new Promise((r) => setTimeout(r, 200));
}
return enriched;
}
When fetching profile pictures for many contacts, add a delay between requests to stay within rate limits. The example above uses a 200ms delay.
Endpoint Reference
| Method | Endpoint | Description |
|---|
GET | /api/instances/{id}/contacts | List all contacts |
GET | /api/instances/{id}/contacts/check?phone={phone} | Check if a number exists on WhatsApp |
GET | /api/instances/{id}/contacts/{contactId} | Get contact info |
GET | /api/instances/{id}/contacts/{contactId}/profile-picture | Get profile picture |
Error Handling
| Status Code | Description |
|---|
400 | Invalid phone number format. Use digits only, with country code (e.g., 5511999998888). |
404 | Instance not found or contact not found. |
429 | Rate limit exceeded. See Rate Limits. |