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 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:
Exemplo de código
{
"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 |
Exemplo de código
{
"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 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:
Exemplo de código
{
"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: o envelope de entrada, busca de mídia e o webhook whatsapp.received
- Cartões de contato do WhatsApp: o lado de envio do mesmo recurso
- IDs de usuário com escopo de negócio: 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: o botão que pede um número
Recursos relacionados
Continue com a documentação, guias e exemplos sobre este tópico. Os recursos estão em inglês.
Assista ao guiaConnecting WhatsApp to Bird: from buying a number to a live channelEntenda o conceitoWhat is the 24-hour customer service window on WhatsApp?Use a ferramentaWhatsApp message builderExplore a funcionalidadeWhatsApp
Experimente na prática e obtenha um resumo de implementação