# Recibir mensajes de WhatsApp

Los mensajes entrantes llegan al mismo recurso que los salientes, sin un endpoint de bandeja de entrada separado que consultar. Léelos con la [lista de mensajes](/docs/guides/whatsapp/message-log) en el dashboard, o a través de la API con `GET /v1/whatsapp/messages/{id}` tras filtrar la lista a entrantes.

Cada mensaje entrante extiende la [ventana de servicio al cliente](/docs/knowledge-base/whatsapp/customer-service-window) a 24 horas después de la marca de tiempo de ese mensaje, que es lo que hace entregable una respuesta libre de tu parte. Un mensaje que llega tarde a Bird trae la ventana que su contacto realmente otorgó, y una fecha límite posterior que ya esté registrada nunca se acorta.

## Qué contiene un mensaje entrante

Cada mensaje entrante comparte un sobre: un `id`, `direction: "inbound"`, el contacto en `from`, tu propio número en `to`, un `status` de `received` y un `created_at`. Exactamente un campo de contenido lo acompaña, indicando lo que el contacto envió:

```json
{
  "id": "wam_01kya19eknftrs2s6p82asmvnh",
  "direction": "inbound",
  "from": { "phone_number": "+14155550100" },
  "to": { "phone_number": "+13124495569" },
  "status": "received",
  "text": { "body": "Is my order out for delivery yet?" },
  "created_at": "2026-08-25T09:04:11Z"
}
```

`from` identifica al contacto según la identidad que WhatsApp reporta: un `phone_number` E.164, un `bsuid`, o ambos, más el `username` y `display_name` que publican. Un contacto que ha adoptado un nombre de usuario de WhatsApp puede contactarte sin número de teléfono; consulta [IDs de usuario con alcance de negocio](/docs/guides/whatsapp/business-scoped-user-ids) para saber qué almacenar y cómo solicitar un número.

Uno de estos campos de contenido, un **arm**, contiene lo que enviaron, y exactamente un arm está presente en cada mensaje. Cada uno tiene su propia página, con la forma de lectura, el payload de `whatsapp.received` y qué tener en cuenta:

| Campo                                                                               | Qué contiene uno entrante                                                       |
| ----------------------------------------------------------------------------------- | ------------------------------------------------------------------------------- |
| [`text`](/docs/guides/whatsapp/receiving-whatsapp/plain-text)                       | `body`, el mensaje que el contacto escribió                                     |
| [`image`](/docs/guides/whatsapp/receiving-whatsapp/images)                          | Un `id`, `url`, `mime_type` y cualquier `caption`                               |
| [`video`](/docs/guides/whatsapp/receiving-whatsapp/video)                           | Los mismos campos multimedia, más cualquier `caption`                           |
| [`audio`](/docs/guides/whatsapp/receiving-whatsapp/audio)                           | Los mismos campos multimedia, más `voice` en una nota de voz; no existe caption |
| [`sticker`](/docs/guides/whatsapp/receiving-whatsapp/stickers)                      | Los mismos campos multimedia, más `animated`                                    |
| [`document`](/docs/guides/whatsapp/receiving-whatsapp/documents)                    | Los mismos campos multimedia, más cualquier `filename` y `caption`              |
| [`location`](/docs/guides/whatsapp/receiving-whatsapp/location)                     | `latitude` y `longitude`, y a veces `name`, `address` o un `url`                |
| [`contact_cards`](/docs/guides/whatsapp/receiving-whatsapp/contact-cards)           | Una o más tarjetas de contacto que el contacto compartió                        |
| [`interactive_reply`](/docs/guides/whatsapp/receiving-whatsapp/interactive-replies) | El `slug` y `text` del botón o fila que el contacto tocó                        |
| [`unsupported`](/docs/guides/whatsapp/receiving-whatsapp/unsupported)               | El tipo de contenido WhatsApp que API no modela, como un pedido                 |

Dos toques llegan en un arm que quizá no esperes. Una [solicitud de ubicación](/docs/guides/whatsapp/message-types/interactive/location-requests) responde como un `location` entrante normal, y una [solicitud de información de contacto](/docs/guides/whatsapp/message-types/interactive/contact-info-requests) responde como `contact_cards`, así que una integración que solo vigile `interactive_reply` para detectar un toque se pierde ambas.

## Descargar multimedia entrante

Un `image`, `video`, `audio`, `sticker` o `document` entrante llega como una referencia a un archivo que Bird almacenó, no como el archivo en sí:

```json
{
  "image": {
    "id": "waf_01kyb2m4xq7whs0d8n3prv6tez",
    "url": "https://platform.bird.com/v1/whatsapp/messages/wam_01kya19eknftrs2s6p82asmvnh/media/waf_01kyb2m4xq7whs0d8n3prv6tez",
    "mime_type": "image/jpeg",
    "caption": "Is this the right part?"
  }
}
```

Descarga los bytes con el método de multimedia del canal, pasando el id del mensaje y el `id` del multimedia:

**TypeScript**

```typescript
const media = await bird.whatsapp.messages.media(
  "wam_01kya19eknftrs2s6p82asmvnh",
  "waf_01kyb2m4xq7whs0d8n3prv6tez",
);
console.log(media.contentType, media.contentLength);
```

Examples: [TypeScript](/es-es/documentacion/guides/whatsapp/receiving-whatsapp.ts.md) · [Python](/es-es/documentacion/guides/whatsapp/receiving-whatsapp.py.md) · [Go](/es-es/documentacion/guides/whatsapp/receiving-whatsapp.go.md) · [PHP](/es-es/documentacion/guides/whatsapp/receiving-whatsapp.php.md) · [CLI](/es-es/documentacion/guides/whatsapp/receiving-whatsapp.cli.md) · [MCP](/es-es/documentacion/guides/whatsapp/receiving-whatsapp.mcp.md) · [cURL](/es-es/documentacion/guides/whatsapp/receiving-whatsapp.curl.md)

Recibes los bytes con el `mime_type` de almacenamiento declarado para ellos. Un id que Bird no reconoce devuelve `404`, y un mensaje saliente no tiene multimedia almacenado que servir.

**Un mensaje se puede leer durante 30 días después de su llegada, y su multimedia nunca lo sobrevive.** Este endpoint lee el mensaje antes de servir el archivo, así que una vez pasada esa ventana ambos responden `404`. Almacena cualquier archivo que necesites por más tiempo mientras el mensaje aún sea legible. El único caso que termina antes es que los bytes almacenados desaparezcan antes de que se cumpla la ventana: la descarga responde `410` [`E15021`](/docs/api/errors/E15021), y el mensaje aún se puede leer con el `mime_type` y `caption` del multimedia.

Internamente, este endpoint responde `302` con una URL prefirmada válida por 15 minutos. Los SDKs y la CLI se encargan de esa redirección por ti. Si lo llamas directamente, la URL prefirmada lleva su propia credencial, así que la solicitud redirigida no debe enviar también tu encabezado `Authorization`. Enviar ambos falla. `curl -L` elimina el encabezado en una redirección a otro host por sí solo; un cliente que reenvía encabezados tal cual necesita descargar el `Location` como una solicitud separada y sin autenticación.

## Respuestas citadas

`in_reply_to_message_id` indica el mensaje al que responde uno entrante, cuando WhatsApp lo marca como respuesta:

```json
{
  "id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
  "direction": "inbound",
  "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
  "text": { "body": "Yes, that one" }
}
```

WhatsApp no marca todas las respuestas, y una sin marcar no lleva ningún ID. El campo también se omite cuando el mensaje citado no puede asociarse con uno que Bird tenga: un mensaje enviado antes de que este espacio de trabajo comenzara a registrarlos, o uno que supere los 15 días que Bird conserva los IDs de mensaje propios de WhatsApp. Una falta de coincidencia omite el campo en lugar de reportar uno, lo cual se lee igual que una respuesta que no contesta a nada.

Trata el campo como una pista, no como una clave. `metadata` en tu propio envío no ayuda aquí, porque permanece en tu mensaje y nunca viaja a la respuesta del contacto, así que una integración que necesite saber a qué pregunta pertenece una respuesta debe rastrear por sí misma la última pregunta que envió a ese contacto. Consulta [Citar un mensaje](/docs/guides/whatsapp/sending-whatsapp#quoting-a-message) para el lado de envío.

## El webhook

Suscríbete a `whatsapp.received` para actuar sobre un mensaje entrante en cuanto llega, en lugar de consultar la lista. El payload incluye el contenido sobre el sobre del evento, así que un endpoint no necesita una lectura adicional:

```json
{
  "type": "whatsapp.received",
  "timestamp": "2026-08-25T09:04:11.118Z",
  "data": {
    "whatsapp_id": "wam_01kyb2m4xq7whs0d8n3prv6tez",
    "workspace_id": "ws_01ky7m235keycbnwyajabe1a6b",
    "direction": "inbound",
    "from": { "phone_number": "+14155550100", "display_name": "Alex Rivera" },
    "to": { "phone_number": "+13124495569" },
    "in_reply_to_message_id": "wam_01kya19eknftrs2s6p82asmvnh",
    "interactive_reply": {
      "type": "button",
      "button": { "slug": "cancel-booking", "text": "Cancel" }
    },
    "tags": null,
    "metadata": null
  }
}
```

Consulta [eventos de WhatsApp](/docs/guides/whatsapp/events#webhooks) para ver el sobre completo y el resto de la lista de eventos.

## Próximos pasos

- [Mensajes de servicio](/docs/guides/whatsapp/message-types): el lado de envío de los mismos arms de contenido
- [Enviar mensajes de WhatsApp](/docs/guides/whatsapp/sending-whatsapp): responder dentro de la ventana de servicio y citar un mensaje
- [Eventos de WhatsApp](/docs/guides/whatsapp/events): la lista completa de eventos, a través de la API o webhooks
- [Registro de WhatsApp](/docs/guides/whatsapp/message-log): explorar la conversación en el dashboard

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