WhatsApp-contactkaarten ontvangen
contact_cards is het enige onderdeel dat hetzelfde veld in beide richtingen draagt. Een contact kan een kaart uit het adresboek delen, en een tik op een contactgegevensverzoek dat je hebt gestuurd komt hier ook aan, met het nummer dat ze hebben gekozen om vrij te geven.
Wat een inkomende contactkaart bevat
contact_cards is altijd een array, en origin geeft aan hoe de kaart is binnengekomen:
Codevoorbeeld
{
"id": "wam_01kyg9v3timy1w7n0r4cbh9ukf",
"direction": "inbound",
"from": { "phone_number": "+14155550100" },
"to": { "phone_number": "+13124495569" },
"status": "received",
"contact_cards": [
{
"origin": "contact_request",
"phone_numbers": [{ "phone_number": "+14155550100", "type": "cell" }]
}
],
"created_at": "2026-08-25T09:27:45Z"
}| origin | Hoe de kaart is binnengekomen |
|---|---|
| contact_request | Het contact tikte op een knop die je stuurde om hun nummer te vragen |
| other | Het contact deelde uit zichzelf een kaart in de chat |
Controleer origin voordat je een kaart als antwoord op je verzoek behandelt. Het is het enige signaal dat de twee onderscheidt, en een kaart die uit zichzelf is gedeeld kan volledig een derde partij benoemen in plaats van het contact. De waardenlijst is open, dus behandel een waarde die je niet herkent als een andere manier van delen die sindsdien is toegevoegd.
Een kaart die deze werkruimte heeft gestuurd, wordt teruggelezen zonder origin, en zo onderscheid je een uitgaande kaart van een inkomende op hetzelfde veld.
Wat een tik bevat, en wat een gedeelde kaart bevat
De twee komen binnen met verschillende hoeveelheden detail, en niets op een kaart is verplicht: WhatsApp stuurt de onderdelen die de kaart bevat en laat de rest weg, dus een kaart met alleen een origin komt gewoon binnen in plaats van te worden weggegooid.
| Veld | Bij een knoptik | Bij een kaart gedeeld in de chat |
|---|---|---|
| phone_numbers[].phone_number, type | Het nummer dat het contact koos om vrij te geven | De nummers die de kaart bevat |
| vcard | Weggelaten; een tik bevat alleen het nummer | De kaart in vCard-formaat |
| name, org, birthday, emails, urls, addresses | Wat WhatsApp stuurt, wat meestal niets is | Aanwezig wanneer de kaart ze bevat |
Codevoorbeeld
{
"contact_cards": [
{
"origin": "other",
"vcard": "BEGIN:VCARD\nVERSION:3.0\nN:Johnson;Barbara;;;\nTEL;type=CELL:+16505551234\nEND:VCARD\n",
"name": {
"formatted_name": "Barbara J. Johnson",
"first_name": "Barbara",
"last_name": "Johnson"
},
"org": { "company": "Northside Plumbing" },
"phone_numbers": [{ "phone_number": "+16505551234", "type": "cell" }]
}
]
}Twee velden vragen aandacht bij het parsen. phone_number is genormaliseerd naar E.164 waar het geparsed kan worden, en wordt exact doorgegeven zoals het apparaat van het contact het opsloeg waar dat niet kan, inclusief een extensie, dus parse defensief in plaats van E.164 aan te nemen. birthday komt ongevalideerd van dat apparaat en wordt als tekst in YYYY-MM-DD-vorm doorgegeven in plaats van als datum getypeerd, dus neem niet aan dat het parsbaar is. Een type-label op een ontvangen kaart is in kleine letters, en WhatsApp definieert er geen vocabulaire voor, dus match het hoofdletterongevoelig in plaats van te switchen op CELL.
Het telefoonnummer dat een contact vrijgeeft
Een contact dat een WhatsApp-gebruikersnaam heeft aangenomen bereikt je via een bedrijfsgebonden gebruikers-ID zonder telefoonnummer op from. Een contactgegevensverzoek is hoe je om het nummer vraagt, en dit onderdeel is waar het antwoord binnenkomt, met origin: "contact_request" en het nummer in phone_numbers.
Het nummer dat ze vrijgeven is niet gegarandeerd het nummer waarmee ze chatten: Meta waarschuwt dat de identifier en het telefoonnummer van een gebruiker niet altijd overeen hoeven te komen, dus sla het vrijgegeven nummer op als een eigen gegeven in plaats van de identiteit op from te overschrijven.
De webhook-payload
whatsapp.received draagt de contact_cards-array op de event-envelope:
Codevoorbeeld
{
"type": "whatsapp.received",
"timestamp": "2026-08-25T09:27:45.019Z",
"data": {
"whatsapp_id": "wam_01kyg9v3timy1w7n0r4cbh9ukf",
"workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
"direction": "inbound",
"from": { "phone_number": "+14155550100", "bsuid": "US.13491208655302741918" },
"to": { "phone_number": "+13124495569" },
"contact_cards": [
{
"origin": "contact_request",
"phone_numbers": [{ "phone_number": "+14155550100", "type": "cell" }]
}
],
"tags": null,
"metadata": null
}
}Aandachtspunten
- Een afgewezen verzoek levert niets op. WhatsApp toont het contact een deelvenster, en het sluiten ervan stuurt geen bericht en activeert geen webhook, dus een flow die op een nummer wacht heeft een eigen timeout nodig in plaats van een afwijzingsevent.
- Twee openstaande verzoeken zijn niet te onderscheiden. Een kaart als antwoord op een contactgegevensverzoek bevat geen in_reply_to_message_id, dus een tweede verzoek dat is gestuurd voordat het eerste is beantwoord kan niet aan zijn eigen antwoord worden gekoppeld.
- De array kan meerdere kaarten bevatten. Een contact dat meerdere kaarten in één bericht deelt vult meerdere items, elk met een eigen origin.
- Een kaart is contactdata die je niet hebt verzameld. Het kan de naam, nummers en geboortedatum van een derde partij bevatten, dus pas dezelfde bewaar- en toestemmingsregels toe als bij alle andere persoonsgegevens voordat je het opslaat.
Volgende stappen
- Hoe ontvangen werkt: de inkomende envelope, media ophalen en de whatsapp.received-webhook
- WhatsApp-contactkaarten: de verzendzijde van hetzelfde onderdeel
- Bedrijfsgebonden gebruikers-ID's: waarom een contact zonder telefoonnummer binnenkomt, en hoe het verzoek past in het gesprek
- WhatsApp-contactgegevensverzoeken: de knop die om een nummer vraagt
Gerelateerde bronnen
Ga verder met de documentatie, gidsen en voorbeelden voor dit onderwerp. De bronnen zijn in het Engels.
Bekijk de gidsConnecting WhatsApp to Bird: from buying a number to a live channelBegrijp het conceptWhat is the 24-hour customer service window on WhatsApp?Gebruik de toolWhatsApp message builderOntdek de mogelijkheidWhatsApp
Probeer de oefening en ontvang een implementatieoverzicht