Tarjetas de contacto de WhatsApp
Un mensaje de tarjeta de contacto comparte uno o más contactos: un nombre que el destinatario ve en la tarjeta y una vista de perfil que abre desde ella con números de teléfono, correos electrónicos, sitios web, direcciones, un empleador y una fecha de nacimiento. Úsalo para darle a un cliente el número de un colega, el de un mensajero o el tuyo, en lugar de pegar dígitos en un texto que luego tiene que volver a escribir.
Enviar una tarjeta de contacto
contact_cards es un array. Cada tarjeta necesita un name, y ese nombre necesita formatted_name más al menos otra parte:
const msg = await bird.whatsapp.send({
to: "+16505551234",
from: "+13124495648",
contact_cards: [
{
name: {
formatted_name: "Barbara J. Johnson",
first_name: "Barbara",
last_name: "Johnson",
},
phone_numbers: [{ phone_number: "+16505559999", type: "Mobile" }],
},
],
});
console.log(msg.id, msg.status);msg = client.whatsapp.send(
to="+16505551234",
from_="+13124495648",
contact_cards=[
{
"name": {
"formatted_name": "Barbara J. Johnson",
"first_name": "Barbara",
"last_name": "Johnson",
},
"phone_numbers": [{"phone_number": "+16505559999", "type": "Mobile"}],
}
],
)
print(msg.id, msg.status)package main
import (
"context"
"fmt"
"log"
"os"
bird "github.com/messagebird/bird-sdk-go"
"github.com/messagebird/bird-sdk-go/option"
)
func main() {
client, err := bird.NewClient(option.WithAPIKey(os.Getenv("BIRD_API_KEY")))
if err != nil {
log.Fatal(err)
}
msg, err := client.Whatsapp.Send(context.Background(), bird.WhatsappSendParams{
To: "+16505551234",
From: "+13124495648",
ContactCards: []bird.WhatsAppContactCardSend{{
Name: bird.WhatsAppContactNameSend{
FormattedName: "Barbara J. Johnson",
FirstName: bird.String("Barbara"),
LastName: bird.String("Johnson"),
},
PhoneNumbers: &[]bird.WhatsAppContactPhoneSend{{
PhoneNumber: "+16505559999",
Type: bird.String("Mobile"),
}},
}},
})
if err != nil {
log.Fatal(err)
}
fmt.Println(msg.Id, *msg.Status)
}$name = (new WhatsAppContactCardSendName())
->setFormattedName('Barbara J. Johnson')
->setFirstName('Barbara')
->setLastName('Johnson');
$phone = (new WhatsAppContactPhoneSend())
->setPhoneNumber('+16505559999')
->setType('Mobile');
$card = (new WhatsAppContactCardSend())
->setName($name)
->setPhoneNumbers([$phone]);
$message = $bird->whatsapp->send(
to: '+16505551234',
from: '+13124495648',
contactCards: [$card],
);
echo $message->getId(), ' ', $message->getStatus();bird whatsapp send \
--to +16505551234 \
--from +13124495648 \
--contact-cards '[{"name":{"formatted_name":"Barbara J. Johnson","first_name":"Barbara","last_name":"Johnson"},"phone_numbers":[{"phone_number":"+16505559999","type":"Mobile"}]}]'curl -X POST "https://us1.platform.bird.com/v1/whatsapp/messages" \
-H "Authorization: Bearer $BIRD_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+16505551234",
"from": "+13124495648",
"contact_cards": [
{
"name": {
"formatted_name": "Barbara J. Johnson",
"first_name": "Barbara",
"last_name": "Johnson"
},
"phone_numbers": [
{ "phone_number": "+16505559999", "type": "Mobile" }
]
}
]
}'from es obligatorio en cada mensaje de servicio: un número que tu espacio de trabajo posee, no uno gestionado por Bird.
La forma completa añade un empleador, una fecha de nacimiento y los demás arrays de datos de contacto:
Ejemplo de código
{
"to": "+16505551234",
"from": "+13124495648",
"contact_cards": [
{
"name": {
"formatted_name": "Dr. Barbara J. Johnson Esq.",
"prefix": "Dr.",
"first_name": "Barbara",
"middle_name": "Joana",
"last_name": "Johnson",
"suffix": "Esq."
},
"org": { "company": "Lucky Shrub", "department": "Legal", "title": "Lead Counsel" },
"birthday": "1999-01-23",
"phone_numbers": [
{ "phone_number": "+16505559999", "type": "Landline" },
{ "phone_number": "+19175559999", "type": "Mobile" }
],
"emails": [{ "email": "bjohnson@example.com", "type": "Work" }],
"urls": [{ "url": "https://example.com", "type": "Company" }],
"addresses": [
{
"street": "1 Lucky Shrub Way",
"city": "Menlo Park",
"state": "CA",
"zip": "94025",
"country": "United States",
"country_code": "US",
"type": "Office"
}
]
}
]
}Cada etiqueta type, ya sea en un teléfono, un correo electrónico, un sitio web o una dirección, es texto libre que tú escribes, se envía exactamente como lo escribiste y se muestra junto al valor en la vista de perfil del destinatario. WhatsApp no define un vocabulario para estas, así que Mobile, Landline, Pop-Up y Work (old) son todos igualmente válidos.
Qué le da a una tarjeta un botón
Un número de teléfono escrito en E.164, con su código de país y + inicial, le da a esa tarjeta un botón que abre un chat de WhatsApp con el número. Un número que Bird no puede leer como E.164 sigue apareciendo en la tarjeta, exactamente como lo escribiste; simplemente no genera ningún botón.
Esto incluye un número escrito sin su + inicial. Bird no añadirá uno por ti: un número en formato nacional de un país puede interpretarse como un número válido en otro una vez que se le adjunta un +, lo que apuntaría el botón a un desconocido. Negarse a adivinar cuesta un botón; adivinar mal le cuesta al destinatario un chat con la persona equivocada.
Una tarjeta sin ningún número de teléfono se muestra sin botón de chat y solo puede guardarse en una agenda de contactos.
Límites
| Campo | Límite | Impuesto por |
|---|---|---|
| contact_cards | 1 a 5 tarjetas por mensaje | Bird, al aceptar (422) |
| name | obligatorio; formatted_name más otra parte del nombre | Bird, al aceptar (422) |
| formatted_name, first_name, middle_name, last_name | hasta 256 caracteres | Bird, al aceptar (422) |
| prefix, suffix | hasta 64 caracteres | Bird, al aceptar (422) |
| birthday | opcional, YYYY-MM-DD, y una fecha que el calendario contenga | Bird, al aceptar (422) |
| phone_numbers, emails, urls, addresses | hasta 10 entradas cada uno | Bird, al aceptar (422) |
| phone_number | hasta 32 caracteres | Bird, al aceptar (422) |
| hasta 254 caracteres | Bird, al aceptar (422) | |
| url | hasta 2048 caracteres, no se valida como URL | Bird, al aceptar (422) |
| type en cualquier teléfono, correo electrónico, sitio web o dirección | hasta 64 caracteres de texto libre | Bird, al aceptar (422) |
| company, department, title | hasta 128 caracteres | Bird, al aceptar (422) |
| street, city, state, zip, country, country_code | hasta 128 caracteres | Bird, al aceptar (422) |
El límite de cinco tarjetas es de Bird, y está deliberadamente muy por debajo de lo que WhatsApp acepta. La propia descripción publicada de API de WhatsApp declara cinco, su documentación recomienda menos por razones de usabilidad y retroalimentación negativa, y un mensaje que se abre como "Contact 1 and 256 other contacts" es un vector de spam antes de ser una funcionalidad. Aumentar el límite después sería un cambio aditivo, así que pregunta si cinco es poco para lo que estás construyendo.
Cada límite de longitud anterior también es de Bird. WhatsApp no impone ninguno que valga la pena y su cliente no compensa: un type de 500 caracteres se muestra como diez líneas de una sola letra repetida, y un url de 4000 caracteres se descarta silenciosamente, dejando la vista de perfil en blanco. Un 422 que nombre el campo infractor es mejor que una tarjeta que el destinatario no puede leer.
Dos reglas que el esquema no puede expresar
Un nombre necesita una segunda parte. formatted_name solo se rechaza con un 422 E15061 WhatsAppContactNameIncomplete, nombrando contact_cards.<n>.name. Cualquiera de prefix, first_name, middle_name, last_name o suffix lo satisface, pero un valor en blanco o solo con espacios no cuenta, y un org no lo rescata. Este es un requisito propio de WhatsApp, no documentado en ninguna parte de su referencia; Bird lo detecta al aceptar para que obtengas un error accionable en lugar de un fallo asíncrono.
Una fecha de nacimiento tiene que ser una fecha real. birthday es YYYY-MM-DD; cualquier otra forma, y cualquier fecha que el calendario no contenga, como 2026-02-30, se rechaza con un 422 E15062 WhatsAppContactBirthdayInvalid. WhatsApp acepta 2026-02-30 y se lo muestra al destinatario, lo que parece un error en tus datos.
Leer una tarjeta de vuelta
Una tarjeta que enviaste se lee de vuelta en el mismo campo contact_cards que usa una tarjeta entrante, a través de la lista de mensajes o GET /v1/whatsapp/messages/{id}:
Ejemplo de código
{
"id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
"direction": "outbound",
"status": "delivered",
"contact_cards": [
{
"name": { "formatted_name": "Barbara J. Johnson", "first_name": "Barbara" },
"phone_numbers": [{ "phone_number": "+16505559999", "type": "Mobile" }]
}
]
}origin y vcard están ausentes en una tarjeta que enviaste: WhatsApp establece ambos en una tarjeta que un contacto compartió. Una etiqueta type que enviaste se lee de vuelta exactamente como la escribiste, mientras que una etiqueta en una tarjeta recibida se convierte a minúsculas. Consulta Recibir tarjetas de contacto de WhatsApp para el lado entrante.
Casos límite
- La ventana de servicio al cliente tiene que estar abierta. El envío de una tarjeta de contacto es un mensaje de servicio, entregable solo dentro de una ventana abierta; consulta la ventana de servicio al cliente del hub.
- No hay wa_id que enviar. WhatsApp identifica el contacto de una tarjeta por un ID de cuenta; Bird lo deriva de cada phone_number E.164 en lugar de aceptar uno, así que el botón en una tarjeta nunca puede apuntar a un lugar distinto de los dígitos impresos en ella.
- vcard es de solo lectura. WhatsApp lo genera para una tarjeta que un contacto compartió. No hay forma de enviar una tarjeta como texto vCard sin procesar.
- Una tarjeta no es un registro de contacto. Enviar una comparte datos en un mensaje; no crea nada en tu espacio de trabajo, y que el destinatario la guarde es su propia acción, invisible para ti.
Próximos pasos
- Mensajes de servicio de WhatsApp: la ventana de servicio al cliente y el modelo que comparten todos los mensajes de servicio
- Solicitudes de información de contacto: pide a un contacto su número en lugar de enviar uno
- Recibir mensajes de WhatsApp: mensajes entrantes, medios y el webhook whatsapp.received
- Enviar mensajes de WhatsApp: la estructura de la solicitud, el modelo 202 y reintentos seguros
Recursos relacionados
Continúa con la documentación, guías y ejemplos sobre este tema. Los recursos están en inglés.
Ver la guíaConnecting WhatsApp to Bird: from buying a number to a live channelComprender el conceptoWhat is the 24-hour customer service window on WhatsApp?Usar la herramientaWhatsApp message builderExplorar la funcionalidadWhatsApp
Prueba el ejercicio y obtén un resumen de implementación