# Recevoir des fiches contact WhatsApp

`contact_cards` est le seul bras qui porte le même champ dans les deux sens. Un contact peut partager une fiche depuis son carnet d'adresses, et un appui sur une [demande d'informations de contact](/docs/guides/whatsapp/message-types/interactive/contact-info-requests) que vous avez envoyée arrive ici aussi, avec le numéro que le contact a choisi de communiquer.

## Ce que contient une fiche contact entrante

`contact_cards` est toujours un tableau, et `origin` indique comment la fiche est arrivée :

```json
{
  "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`          | Comment la fiche est arrivée                                                    |
| ----------------- | ------------------------------------------------------------------------------- |
| `contact_request` | Le contact a appuyé sur un bouton que vous avez envoyé pour demander son numéro |
| `other`           | Le contact a partagé une fiche dans la conversation, spontanément               |

**Vérifiez `origin` avant de traiter une fiche comme une réponse à votre demande.** C'est le seul signal qui distingue les deux, et une fiche partagée spontanément peut désigner un tiers plutôt que le contact lui-même. La liste de valeurs est ouverte : traitez toute valeur que vous ne reconnaissez pas comme un autre mode de partage ajouté depuis.

Une fiche envoyée par cet espace de travail est relue sans aucun `origin`, ce qui permet de distinguer une fiche sortante d'une fiche entrante sur le même champ.

## Ce que contient un appui, et ce que contient une fiche partagée

Les deux arrivent avec des niveaux de détail différents, et rien n'est obligatoire sur une fiche : WhatsApp envoie les parties que la fiche contient et omet le reste, donc une fiche ne portant qu'un `origin` arrive quand même au lieu d'être ignorée.

| Champ                                                    | Sur un appui de bouton                                 | Sur une fiche partagée dans la conversation |
| -------------------------------------------------------- | ------------------------------------------------------ | ------------------------------------------- |
| `phone_numbers[].phone_number`, `type`                   | Le numéro que le contact a choisi de communiquer       | Les numéros que la fiche contient           |
| `vcard`                                                  | Omis ; un appui ne porte que le numéro                 | La fiche au format vCard                    |
| `name`, `org`, `birthday`, `emails`, `urls`, `addresses` | Ce que WhatsApp envoie, c'est-à-dire généralement rien | Présents quand la fiche les contient        |

```json
{
  "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" }]
    }
  ]
}
```

Deux champs demandent de la prudence à l'analyse. `phone_number` est normalisé en E.164 lorsqu'il peut être interprété, et transmis tel quel, tel que l'appareil du contact l'a stocké, dans le cas contraire (une extension en fait partie) : analysez-le de manière défensive plutôt que de supposer le format E.164. `birthday` provient de l'appareil sans validation et est transmis sous forme de texte au format `YYYY-MM-DD` plutôt que typé comme une date : ne supposez pas qu'il est analysable. Un libellé `type` sur une fiche reçue est en minuscules, et WhatsApp ne définit aucun vocabulaire pour ce champ : comparez-le sans tenir compte de la casse plutôt que de faire un switch sur `CELL`.

## Le numéro de téléphone communiqué par un contact

Un contact qui a adopté un nom d'utilisateur WhatsApp vous contacte par [identifiant utilisateur à portée business](/docs/guides/whatsapp/business-scoped-user-ids) sans numéro de téléphone sur `from`. Une demande d'informations de contact est le moyen de demander le numéro, et ce bras est l'endroit où la réponse arrive, avec `origin: "contact_request"` et le numéro dans `phone_numbers`.

Le numéro communiqué n'est pas forcément le numéro depuis lequel le contact discute : Meta prévient que l'identifiant d'un utilisateur et son numéro de téléphone ne correspondent pas toujours. Stockez donc le numéro communiqué comme une donnée à part plutôt que d'écraser l'identité sur `from`.

## Le payload du webhook

`whatsapp.received` porte le tableau `contact_cards` sur l'enveloppe de l'événement :

```json
{
  "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
  }
}
```

## Points d'attention

- **Une demande refusée ne produit rien.** WhatsApp affiche au contact une feuille de partage, et la fermer n'envoie aucun message et ne déclenche aucun webhook. Un flux en attente d'un numéro a donc besoin de son propre délai d'expiration plutôt que d'un événement de refus à surveiller.
- **Deux demandes en attente sont indiscernables.** Une fiche répondant à une demande d'informations de contact ne porte aucun `in_reply_to_message_id` : une seconde demande envoyée avant que la première ne reçoive de réponse ne peut pas être associée à sa propre réponse.
- **Le tableau peut contenir plusieurs fiches.** Un contact qui partage plusieurs fiches dans un même message remplit plusieurs entrées, chacune avec son propre `origin`.
- **Une fiche est une donnée de contact que vous n'avez pas collectée.** Elle peut contenir le nom, les numéros et la date de naissance d'un tiers : appliquez les mêmes règles de conservation et de consentement que pour toute autre donnée personnelle avant de la stocker.

## Étapes suivantes

- [Fonctionnement de la réception](/docs/guides/whatsapp/receiving-whatsapp) : l'enveloppe entrante, la récupération des médias et le webhook `whatsapp.received`
- [Fiches contact WhatsApp](/docs/guides/whatsapp/message-types/contact-cards) : le côté envoi du même bras
- [Identifiants utilisateur à portée business](/docs/guides/whatsapp/business-scoped-user-ids) : pourquoi un contact arrive sans numéro de téléphone et comment la demande s'intègre dans la conversation
- [Demandes d'informations de contact WhatsApp](/docs/guides/whatsapp/message-types/interactive/contact-info-requests) : le bouton qui demande un numéro

## Related resources

- [Connecting WhatsApp to Bird: from buying a number to a live channel](/learn/whatsapp/connecting-whatsapp-to-bird) (video)
- [What is the 24-hour customer service window on WhatsApp?](/explained/whatsapp/what-is-the-24-hour-customer-service-window) (answer)
- [WhatsApp message builder](/tools/whatsapp-message-builder) (tool)
- [WhatsApp](/products/whatsapp) (product)

[Get an implementation brief](/learn/workspace?topic=whatsapp)
