> ## Documentation Index
> Fetch the complete documentation index at: https://docs.whaapy.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Historial de Mensajes

> Obtén el historial completo de mensajes de una conversación

## Parámetros

<ParamField path="id" type="string" required>
  UUID de la conversación
</ParamField>

<ParamField query="limit" type="number" default="50">
  Número de mensajes (máximo 100)
</ParamField>

<ParamField query="before" type="string">
  Cursor para paginación (ID del mensaje más antiguo)
</ParamField>

<RequestExample>
  ```bash cURL theme={null}
  curl -X GET "https://api.whaapy.com/conversations/v1/uuid/messages?limit=20" \
    -H "Authorization: Bearer wha_xxxxx"
  ```

  ```javascript Node.js theme={null}
  const conversationId = 'uuid';
  const response = await fetch(
    `https://api.whaapy.com/conversations/v1/${conversationId}/messages?limit=20`,
    {
      headers: { 'Authorization': 'Bearer wha_xxxxx' }
    }
  );
  const data = await response.json();
  ```

  ```python Python theme={null}
  import requests

  conversation_id = 'uuid'
  response = requests.get(
      f'https://api.whaapy.com/conversations/v1/{conversation_id}/messages',
      params={'limit': 20},
      headers={'Authorization': 'Bearer wha_xxxxx'}
  )
  data = response.json()
  ```

  ```php PHP theme={null}
  $conversationId = 'uuid';
  $curl = curl_init();

  curl_setopt_array($curl, [
    CURLOPT_URL => "https://api.whaapy.com/conversations/v1/{$conversationId}/messages?limit=20",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
      "Authorization: Bearer wha_xxxxx"
    ],
  ]);

  $response = curl_exec($curl);
  $data = json_decode($response, true);
  ```
</RequestExample>

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "data": [
      {
        "id": "msg-uuid-1",
        "conversationId": "conv-uuid",
        "content": "Hola, ¿tienen disponibilidad para mañana?",
        "messageType": "text",
        "direction": "inbound",
        "status": "read",
        "sentByAi": false,
        "timestamp": "2026-01-29T10:30:00Z",
        "createdAt": "2026-01-29T10:30:00Z"
      },
      {
        "id": "msg-uuid-2",
        "conversationId": "conv-uuid",
        "content": "¡Hola! Sí, tenemos disponibilidad. ¿A qué hora te gustaría?",
        "messageType": "text",
        "direction": "outbound",
        "status": "delivered",
        "sentByAi": true,
        "timestamp": "2026-01-29T10:30:15Z",
        "createdAt": "2026-01-29T10:30:15Z"
      },
      {
        "id": "msg-uuid-3",
        "conversationId": "conv-uuid",
        "content": null,
        "messageType": "image",
        "direction": "inbound",
        "status": "read",
        "sentByAi": false,
        "mediaUrl": "https://api.whaapy.com/messages/msg-uuid-3/media?token=xxx",
        "mediaMimeType": "image/jpeg",
        "timestamp": "2026-01-29T10:31:00Z",
        "createdAt": "2026-01-29T10:31:00Z"
      }
    ],
    "meta": {
      "hasMore": true,
      "oldestMessageId": "msg-uuid-1"
    }
  }
  ```
</ResponseExample>

## Campos del mensaje

| Campo            | Tipo    | Descripción                                 |
| ---------------- | ------- | ------------------------------------------- |
| `id`             | string  | UUID del mensaje                            |
| `conversationId` | string  | UUID de la conversación                     |
| `content`        | string  | Contenido del mensaje (null para media)     |
| `messageType`    | string  | Tipo de mensaje (ver tabla abajo)           |
| `direction`      | string  | `inbound` (recibido) o `outbound` (enviado) |
| `status`         | string  | `sent`, `delivered`, `read`, `failed`       |
| `sentByAi`       | boolean | Si fue enviado por la IA                    |
| `mediaUrl`       | string  | URL del archivo (si es media)               |
| `mediaMimeType`  | string  | MIME type del archivo                       |
| `timestamp`      | string  | Fecha y hora del mensaje                    |
| `createdAt`      | string  | Fecha de creación en BD                     |

## Tipos de mensaje

| Tipo          | Descripción                           |
| ------------- | ------------------------------------- |
| `text`        | Mensaje de texto simple               |
| `image`       | Imagen (jpeg, png, webp)              |
| `video`       | Video (mp4)                           |
| `audio`       | Audio o nota de voz (ogg, mp3)        |
| `document`    | Documento (pdf, doc, etc.)            |
| `sticker`     | Sticker de WhatsApp                   |
| `template`    | Mensaje de template                   |
| `interactive` | Mensaje interactivo (botones, listas) |
| `location`    | Ubicación                             |
| `contacts`    | Tarjeta de contacto                   |
| `reaction`    | Reacción a mensaje                    |

## Paginación

Los mensajes se ordenan del más reciente al más antiguo. Para obtener mensajes más antiguos, usa el parámetro `before` con el `id` del mensaje más antiguo de la página actual.

```javascript theme={null}
// Primera página
const page1 = await fetch(
  `https://api.whaapy.com/conversations/v1/${id}/messages?limit=20`,
  { headers: { 'Authorization': 'Bearer wha_xxxxx' } }
).then(r => r.json());

// Segunda página (mensajes más antiguos)
if (page1.meta.hasMore) {
  const oldestId = page1.meta.oldestMessageId;
  const page2 = await fetch(
    `https://api.whaapy.com/conversations/v1/${id}/messages?limit=20&before=${oldestId}`,
    { headers: { 'Authorization': 'Bearer wha_xxxxx' } }
  ).then(r => r.json());
}
```

<Warning>
  Los mensajes se ordenan del más reciente al más antiguo. Usa `before` para paginar hacia atrás en el historial.
</Warning>

## Acceder a media

Las URLs de media (`mediaUrl`) son temporales y requieren el token incluido. Para acceder a la media:

```javascript theme={null}
// La URL ya incluye el token
const mediaUrl = message.mediaUrl;
const mediaResponse = await fetch(mediaUrl);
const blob = await mediaResponse.blob();
```

<Tip>
  Las URLs de media expiran después de 5 minutos. Si necesitas acceso persistente, descarga el archivo y almacénalo en tu propio servidor.
</Tip>
