# Recebendo cartões de contato do WhatsApp

`contact_cards` é o único recurso que carrega o mesmo campo nas duas direções. Um contato pode compartilhar um cartão da agenda dele, e um toque em uma [solicitação de informações de contato](/docs/guides/whatsapp/message-types/interactive/contact-info-requests) que você enviou também chega aqui, trazendo o número que ele escolheu divulgar.

## O que um cartão de contato recebido carrega

`contact_cards` é sempre um array, e `origin` indica como o cartão chegou:

```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`          | Como o cartão chegou                                              |
| ----------------- | ----------------------------------------------------------------- |
| `contact_request` | O contato tocou em um botão que você enviou pedindo o número dele |
| `other`           | O contato compartilhou um cartão no chat, espontaneamente         |

**Verifique `origin` antes de tratar um cartão como resposta à sua solicitação.** É o único sinal que diferencia os dois, e um cartão compartilhado espontaneamente pode conter o nome de um terceiro em vez do contato. A lista de valores é aberta, então trate qualquer valor que você não reconheça como uma forma de compartilhamento adicionada posteriormente.

Um cartão que este espaço de trabalho enviou aparece na leitura sem nenhum `origin`, e é assim que um cartão enviado se diferencia de um recebido no mesmo campo.

## O que um toque carrega e o que um cartão compartilhado carrega

Os dois chegam com quantidades diferentes de detalhe, e nada em um cartão é obrigatório: WhatsApp envia as partes que o cartão contém e omite o restante, então um cartão que contém apenas um `origin` ainda chega em vez de ser descartado.

| Campo                                                    | Em um toque de botão                         | Em um cartão compartilhado no chat  |
| -------------------------------------------------------- | -------------------------------------------- | ----------------------------------- |
| `phone_numbers[].phone_number`, `type`                   | O número que o contato escolheu divulgar     | Os números que o cartão contém      |
| `vcard`                                                  | Omitido; um toque carrega apenas o número    | O cartão em formato vCard           |
| `name`, `org`, `birthday`, `emails`, `urls`, `addresses` | O que WhatsApp envia, que normalmente é nada | Presentes quando o cartão os contém |

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

Dois campos exigem cuidado ao fazer o parsing. `phone_number` é normalizado para E.164 quando pode ser interpretado, e repassado exatamente como o dispositivo do contato o armazenou quando não pode, incluindo ramais, então faça o parsing de forma defensiva em vez de assumir E.164. `birthday` vem do dispositivo sem validação e é repassado como texto no formato `YYYY-MM-DD` em vez de ser tipado como data, então não assuma que ele pode ser interpretado. Um rótulo `type` em um cartão recebido vem em letras minúsculas, e WhatsApp não define um vocabulário para ele, então faça a comparação sem distinguir maiúsculas e minúsculas em vez de usar switch em `CELL`.

## O número de telefone que um contato divulga

Um contato que adotou um nome de usuário do WhatsApp chega até você por [ID de usuário com escopo de negócio](/docs/guides/whatsapp/business-scoped-user-ids) sem número de telefone em `from`. Uma solicitação de informações de contato é como você pede o número, e este recurso é onde a resposta chega, com `origin: "contact_request"` e o número em `phone_numbers`.

O número divulgado não é garantido como sendo o número de onde o contato conversa: a Meta alerta que o identificador e o número de telefone de um usuário podem não coincidir, então armazene o número divulgado como um dado próprio em vez de sobrescrever a identidade em `from`.

## O payload do webhook

`whatsapp.received` carrega o array `contact_cards` no envelope do 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
  }
}
```

## Pontos de atenção

- **Uma solicitação recusada não produz nada.** WhatsApp mostra ao contato uma tela de compartilhamento, e descartá-la não envia mensagem nem dispara webhook, então um fluxo que espera um número precisa do seu próprio timeout em vez de um evento de recusa para monitorar.
- **Duas solicitações pendentes são indistinguíveis.** Um cartão que responde a uma solicitação de informações de contato não carrega `in_reply_to_message_id`, então uma segunda solicitação enviada antes de a primeira ser respondida não pode ser associada à sua própria resposta.
- **O array pode conter vários cartões.** Um contato que compartilha múltiplos cartões em uma mensagem preenche várias entradas, cada uma com seu próprio `origin`.
- **Um cartão é dado de contato que você não coletou.** Ele pode conter nome, números e data de nascimento de terceiros, então aplique as mesmas regras de retenção e consentimento que você aplicaria a qualquer outro dado pessoal antes de armazená-lo.

## Próximos passos

- [Como funciona o recebimento](/docs/guides/whatsapp/receiving-whatsapp): o envelope de entrada, busca de mídia e o webhook `whatsapp.received`
- [Cartões de contato do WhatsApp](/docs/guides/whatsapp/message-types/contact-cards): o lado de envio do mesmo recurso
- [IDs de usuário com escopo de negócio](/docs/guides/whatsapp/business-scoped-user-ids): por que um contato chega sem número de telefone e como a solicitação se encaixa na conversa
- [Solicitações de informações de contato do WhatsApp](/docs/guides/whatsapp/message-types/interactive/contact-info-requests): o botão que pede um 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)
