# Recibir tarjetas de contacto de WhatsApp

`contact_cards` es el único campo que funciona igual en ambas direcciones. Un contacto puede compartir una tarjeta de su agenda, y un toque en una [solicitud de información de contacto](/docs/guides/whatsapp/message-types/interactive/contact-info-requests) que enviaste también llega aquí, con el número que eligió revelar.

## Qué contiene una tarjeta de contacto entrante

`contact_cards` siempre es un array, y `origin` indica cómo llegó la tarjeta:

```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`          | Cómo llegó la tarjeta                                               |
| ----------------- | ------------------------------------------------------------------- |
| `contact_request` | El contacto pulsó un botón que enviaste para pedir su número        |
| `other`           | El contacto compartió una tarjeta en el chat sin que se la pidieras |

**Comprueba `origin` antes de tratar una tarjeta como respuesta a tu solicitud.** Es la única señal que distingue ambos casos, y una tarjeta compartida sin pedirla puede contener los datos de un tercero en lugar de los del contacto. La lista de valores es abierta, así que trata cualquier valor que no reconozcas como otra forma de compartir añadida después.

Una tarjeta enviada por este espacio de trabajo se lee de vuelta sin `origin`, y así se distingue una tarjeta saliente de una entrante en el mismo campo.

## Qué contiene un toque y qué contiene una tarjeta compartida

Ambos llegan con distinta cantidad de detalle, y ningún campo de la tarjeta es obligatorio: WhatsApp envía las partes que la tarjeta contiene y omite el resto, así que una tarjeta con solo un `origin` llega igualmente en lugar de descartarse.

| Campo                                                    | Al pulsar un botón                             | En una tarjeta compartida en el chat     |
| -------------------------------------------------------- | ---------------------------------------------- | ---------------------------------------- |
| `phone_numbers[].phone_number`, `type`                   | El número que el contacto eligió revelar       | Los números que contenga la tarjeta      |
| `vcard`                                                  | Omitido; un toque solo lleva el número         | La tarjeta en formato vCard              |
| `name`, `org`, `birthday`, `emails`, `urls`, `addresses` | Lo que WhatsApp envíe, que normalmente es nada | Presentes cuando la tarjeta los contiene |

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

Dos campos requieren cuidado al procesarlos. `phone_number` se normaliza a E.164 cuando se puede analizar y se pasa tal cual lo almacenó el dispositivo del contacto cuando no, incluidas las extensiones, así que analízalo de forma defensiva en lugar de asumir E.164. `birthday` sale del dispositivo sin validar y se pasa como texto con forma `YYYY-MM-DD` en lugar de tiparlo como fecha, así que no asumas que se puede analizar. Una etiqueta `type` en una tarjeta recibida llega en minúsculas, y WhatsApp no define un vocabulario para ella, así que compárala sin distinguir mayúsculas en lugar de hacer un switch sobre `CELL`.

## El número de teléfono que un contacto revela

Un contacto que ha adoptado un nombre de usuario de WhatsApp te contacta mediante un [identificador de usuario con alcance de negocio](/docs/guides/whatsapp/business-scoped-user-ids) sin número de teléfono en `from`. Una solicitud de información de contacto es la forma de pedir el número, y este campo es donde llega la respuesta, con `origin: "contact_request"` y el número en `phone_numbers`.

No se garantiza que el número revelado sea el número desde el que chatean: Meta advierte que el identificador de un usuario y su número de teléfono pueden no coincidir siempre, así que almacena el número revelado como un dato independiente en lugar de sobrescribir la identidad en `from`.

## El payload del webhook

`whatsapp.received` contiene el array `contact_cards` en el envelope del evento:

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

## Aspectos a tener en cuenta

- **Una solicitud rechazada no produce nada.** WhatsApp muestra al contacto una hoja de compartir, y cerrarla no envía ningún mensaje ni dispara ningún webhook, así que un flujo que espera un número necesita su propio tiempo de espera en lugar de un evento de rechazo.
- **Dos solicitudes pendientes son indistinguibles.** Una tarjeta que responde a una solicitud de información de contacto no lleva `in_reply_to_message_id`, así que una segunda solicitud enviada antes de que se responda la primera no se puede asociar con su propia respuesta.
- **El array puede contener varias tarjetas.** Un contacto que comparte varias tarjetas en un mismo mensaje llena varias entradas, cada una con su propio `origin`.
- **Una tarjeta son datos de contacto que tú no recopilaste.** Puede contener el nombre, los números y la fecha de nacimiento de un tercero, así que aplica las mismas reglas de retención y consentimiento que aplicarías a cualquier otro dato personal antes de almacenarla.

## Próximos pasos

- [Cómo funciona la recepción](/docs/guides/whatsapp/receiving-whatsapp): el envelope entrante, la descarga de medios y el webhook `whatsapp.received`
- [Tarjetas de contacto de WhatsApp](/docs/guides/whatsapp/message-types/contact-cards): el lado de envío del mismo campo
- [Identificadores de usuario con alcance de negocio](/docs/guides/whatsapp/business-scoped-user-ids): por qué un contacto llega sin número de teléfono y cómo encaja la solicitud en la conversación
- [Solicitudes de información de contacto de WhatsApp](/docs/guides/whatsapp/message-types/interactive/contact-info-requests): el botón que pide un número

## 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)
