Chapter 1 · The scenario
Example: Handing a patient the right desk in Patna
A Patna heart clinic's front-desk bot is asked how to reach the cardiology OPD. Instead of typing a number, it sends a contacts message: "Cardiology OPD (Patna)" with the department's landline, its WhatsApp-enabled appointment number carrying a wa_id, the OPD email and the clinic's address. The patient taps Save contact and has the right number for next time. Later she shares her father's card so the clinic can send him his report; the bot stores the number as a pending contact and sends nothing to it until her father messages the clinic himself.
Chapter 2 · What is a contacts message?
A contacts message is the WhatsApp message type (type: "contacts") for sharing contact cards. Instead of typing a phone number into a text, the business sends a structured card — a name, one or more phone numbers, emails, postal addresses, an organisation and job title, websites, a birthday — and the recipient sees a bubble they can open to save the contact, call it or start a chat. Customers can share cards the same way, for example to refer a friend or nominate a family member.
On the Cloud API the payload is a contacts array of card objects. The only required field on a card is name.formatted_name, the name shown in the bubble; first_name, last_name, middle_name, prefix and suffix sit beside it. phones, emails, addresses and urls are arrays, so one card can carry a support line and a sales line; org holds company, department and title; birthday uses YYYY-MM-DD; addresses take a two-letter country_code. A single message can carry up to 257 cards, although Meta recommends far fewer.
One field changes the experience: wa_id inside a phone entry. With it, the card shows Message and Save contact buttons, and Message opens a chat with that number; without it, WhatsApp shows an Invite to WhatsApp button instead. Inbound cards arrive in the messages webhook as type: "contacts" with the same structure — not to be confused with the webhook contacts object, the contacts array at the top of every inbound webhook that describes who sent the message. Like other free-form types, a contacts message can be sent only inside an open customer service window.
Key takeaways
- A contacts message sends one or more contact cards that the recipient can save, call or message in one tap.
- Each card needs only
name.formatted_name; phones, emails, addresses, organisation, URLs and birthday are optional. - Add
wa_idto a phone entry to show Message and Save contact buttons; without it WhatsApp shows Invite to WhatsApp. - Shared cards arrive as
type: contactsinsidemessages[], unlike the top-levelcontactsarray that describes the sender. - One message can carry up to 257 cards, but Meta recommends sending fewer.
Chapter 3 · In code
A contacts message in code
curl -X POST "https://graph.facebook.com/v26.0/{PHONE_NUMBER_ID}/messages" \-H "Authorization: Bearer {ACCESS_TOKEN}" \-H "Content-Type: application/json" \-d '{"messaging_product": "whatsapp","to": "919812345678","type": "contacts","contacts": [{"name": { "formatted_name": "Cardiology OPD (Patna)", "first_name": "Cardiology", "last_name": "OPD" },"org": { "company": "Demo Heart Clinic", "department": "Cardiology" },"phones": [{ "phone": "+91 612 255 0100", "type": "WORK" },{ "phone": "+91 98765 43210", "type": "WORK", "wa_id": "919876543210" }],"emails": [{ "email": "opd@example.in", "type": "WORK" }]}]}'
The second phone has a wa_id, so the card shows Message and Save contact buttons.
Chapter 4 · How it unfolds
How does a contacts message work?
Build the card
Create a
contactsarray with one object per person or desk, and setname.formatted_nameexactly as it should appear in the customer's address book.Add reachable details
Fill
phonesin international format with atypesuch asWORK, and addwa_idto any number that is on WhatsApp so the card offers a Message button. Addemails,urlsand an address only if they help.Send inside the window
POST to
/{PHONE_NUMBER_ID}/messageswithtype: "contacts". It is a session message, so the customer must have messaged you in the last 24 hours.Receive shared cards
When a customer shares a contact,
messages[0].typeiscontactsand the card sits inmessages[0].contacts. Normalise the numbers to E.164 before storing or matching them.Ask before you use them
A shared card is a third person's data. Store it, but message that person only once they have opted in themselves.
Chapter 5 · The facts
A contacts message: key facts and limits
| Message type | contacts |
|---|---|
| Required per card | name.formatted_name |
| Optional fields | phones, emails, addresses, org, urls, birthday |
| Birthday format | YYYY-MM-DD |
| Cards per message | Up to 257 (fewer recommended) |
| Phone with wa_id | Message and Save contact buttons |
| Phone without wa_id | Invite to WhatsApp button |
| When you can send | Inside an open customer service window |
Chapter 6 · Where it goes wrong
Common mistakes with a contacts message
Leaving out wa_id
Without it the card offers Invite to WhatsApp instead of Message, even for your own WhatsApp support line. Add the number's
wa_id— digits only, country code first.Reading the wrong contacts array
value.contactsin every inbound webhook is the sender's profile;messages[].contactsexists only when the message is a shared card. Parsers that mix them save the sender as the shared contact.Messaging people from shared cards
A card a customer forwards is not that person's consent. Keep it, but contact them only after they opt in directly.
Storing numbers as typed
Phone fields arrive with spaces, dashes and local prefixes. Normalise to E.164 before matching against your CRM, or the same person ends up as three contacts.
Chapter 7 · Why it matters
Why does a contacts message matter?
Numbers typed into a chat get mistyped, lost in the scroll and never saved, so the next time a customer needs help they search the web and find a fake "customer care" listing. A contacts message hands them the real line in a form their phone understands — saved in one tap, under the right name — and lets a business introduce a specific person, such as a relationship manager or a branch desk, without anyone copying details by hand.
Chapter 8 · What good teams do
Best practices for a contacts message
- Name the card the way customers search for you: "Acme Support (Pune)" beats a legal entity name.
- Send a card at the end of a resolved conversation so the right number is saved for next time.
- Use
org.titlefor a named relationship manager so the saved contact says who they are. - Keep each card to the numbers a customer actually needs; a card listing six lines is hard to use.
Chapter 9 · Contacts Message FAQs