Skip to main content

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.

Get All Contacts

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
    }
  ]
}

Contact Fields

FieldDescription
idThe contact’s WhatsApp ID (phone number + @s.whatsapp.net).
nameContact name as saved in the phone’s address book. May be null if not saved.
short_nameShort name from the address book.
push_nameThe name the contact has set for themselves on WhatsApp.
is_businessWhether 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.

Get Contact Info

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();
}

Build a Contact Directory

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

MethodEndpointDescription
GET/api/instances/{id}/contactsList 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-pictureGet profile picture

Error Handling

Status CodeDescription
400Invalid phone number format. Use digits only, with country code (e.g., 5511999998888).
404Instance not found or contact not found.
429Rate limit exceeded. See Rate Limits.