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

# Enviar Media

> Envía imágenes, videos, audio, documentos y stickers por WhatsApp

Envía archivos multimedia a través de WhatsApp. Soporta imágenes, videos, audio, documentos y stickers.

## Métodos de Envío

Hay dos formas de enviar media:

<Tabs>
  <Tab title="Con URL (link)">
    Proporciona una URL pública y Meta descargará el archivo:

    ```json theme={null}
    {
      "to": "+5215512345678",
      "type": "image",
      "image": {
        "link": "https://example.com/imagen.jpg",
        "caption": "Descripción opcional"
      }
    }
    ```
  </Tab>

  <Tab title="Con media_id">
    Primero sube el archivo con `/media/v1`, luego usa el ID:

    ```json theme={null}
    {
      "to": "+5215512345678",
      "type": "image",
      "image": {
        "id": "123456789012345",
        "caption": "Descripción opcional"
      }
    }
    ```
  </Tab>
</Tabs>

### ¿Cuándo usar cada método?

| Método                 | Tamaño     | Mejor para                                        |
| ---------------------- | ---------- | ------------------------------------------------- |
| `link`                 | \< 5MB     | URLs públicas de CDN, imágenes pequeñas           |
| `id` (via `/media/v1`) | Cualquiera | Archivos grandes, URLs privadas, múltiples envíos |

<Info>
  **Compresión Automática de Imágenes**: Si envías una imagen por URL que excede 5MB, Whaapy automáticamente la detecta, la descarga, la comprime con calidad progresiva, y la sube a Meta. No necesitas hacer nada adicional - el proceso es transparente.
</Info>

<Tip>
  **Proxy Automático**: Si Meta no puede descargar tu URL (error 131052), Whaapy automáticamente descarga el archivo y lo re-sube. Para archivos muy grandes que no se pueden comprimir, usa `autoConvert: true` para enviarlos como documento, o súbelos primero via [/media/v1](/api-reference/media/upload-media).
</Tip>

***

## Imagen

Formatos soportados: **JPEG, PNG, WebP**\
Tamaño máximo: **5 MB**

### Con URL

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.whaapy.com/messages/v1 \
    -H "Authorization: Bearer wha_TU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "to": "+5215512345678",
      "type": "image",
      "image": {
        "link": "https://example.com/producto.jpg",
        "caption": "¡Mira nuestro nuevo producto!"
      }
    }'
  ```

  ```javascript Node.js theme={null}
  const response = await fetch('https://api.whaapy.com/messages/v1', {
    method: 'POST',
    headers: {
      'Authorization': 'Bearer wha_TU_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      to: '+5215512345678',
      type: 'image',
      image: {
        link: 'https://example.com/producto.jpg',
        caption: '¡Mira nuestro nuevo producto!'
      }
    })
  });
  ```

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

  response = requests.post(
      'https://api.whaapy.com/messages/v1',
      headers={
          'Authorization': 'Bearer wha_TU_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'to': '+5215512345678',
          'type': 'image',
          'image': {
              'link': 'https://example.com/producto.jpg',
              'caption': '¡Mira nuestro nuevo producto!'
          }
      }
  )
  ```
</RequestExample>

### Con media\_id

```json theme={null}
{
  "to": "+5215512345678",
  "type": "image",
  "image": {
    "id": "123456789012345",
    "caption": "Imagen subida previamente"
  }
}
```

### Campos

<ParamField body="image.link" type="string">
  URL pública de la imagen. Mutuamente excluyente con `id`.
</ParamField>

<ParamField body="image.id" type="string">
  ID de media obtenido de `/media/v1`. Mutuamente excluyente con `link`.
</ParamField>

<ParamField body="image.caption" type="string">
  Descripción opcional que aparece debajo de la imagen. Máximo 1024 caracteres.
</ParamField>

***

## Video

Formatos soportados: **MP4, 3GPP**\
Tamaño máximo: **16 MB**\
Códecs recomendados: H.264 video, AAC audio

<Warning>
  Para videos grandes (>5MB), siempre usa [/media/v1](/api-reference/media/upload-media) primero. El proxy automático tiene límites de tamaño.
</Warning>

### Con URL

<RequestExample>
  ```json Request theme={null}
  {
    "to": "+5215512345678",
    "type": "video",
    "video": {
      "link": "https://example.com/tutorial.mp4",
      "caption": "Tutorial de instalación"
    }
  }
  ```
</RequestExample>

### Con media\_id (Recomendado)

<RequestExample>
  ```json Request theme={null}
  {
    "to": "+5215512345678",
    "type": "video",
    "video": {
      "id": "123456789012345",
      "caption": "Video subido previamente"
    }
  }
  ```
</RequestExample>

### Campos

<ParamField body="video.link" type="string">
  URL pública del video. Mutuamente excluyente con `id`.
</ParamField>

<ParamField body="video.id" type="string">
  ID de media obtenido de `/media/v1`. Mutuamente excluyente con `link`.
</ParamField>

<ParamField body="video.caption" type="string">
  Descripción opcional. Máximo 1024 caracteres.
</ParamField>

***

## Audio

Formatos soportados: **AAC, MP3, OGG (Opus), AMR**\
Tamaño máximo: **16 MB**

<Note>
  Los audios se muestran como notas de voz en WhatsApp si son formato OGG con códec Opus.
</Note>

### Ejemplo

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.whaapy.com/messages/v1 \
    -H "Authorization: Bearer wha_TU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "to": "+5215512345678",
      "type": "audio",
      "audio": {
        "link": "https://example.com/mensaje.mp3"
      }
    }'
  ```

  ```json Request Body theme={null}
  {
    "to": "+5215512345678",
    "type": "audio",
    "audio": {
      "link": "https://example.com/mensaje.mp3"
    }
  }
  ```
</RequestExample>

### Con media\_id

```json theme={null}
{
  "to": "+5215512345678",
  "type": "audio",
  "audio": {
    "id": "123456789012345"
  }
}
```

### Campos

<ParamField body="audio.link" type="string">
  URL pública del audio.
</ParamField>

<ParamField body="audio.id" type="string">
  ID de media obtenido de `/media/v1`.
</ParamField>

<Tip>
  Los audios no soportan `caption`. Si necesitas agregar contexto, envía un mensaje de texto antes o después.
</Tip>

***

## Documento

Formatos soportados: **PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT**\
Tamaño máximo: **100 MB**

### Ejemplo

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.whaapy.com/messages/v1 \
    -H "Authorization: Bearer wha_TU_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "to": "+5215512345678",
      "type": "document",
      "document": {
        "link": "https://example.com/factura.pdf",
        "filename": "factura-enero-2026.pdf",
        "caption": "Tu factura del mes de enero"
      }
    }'
  ```

  ```json Request Body theme={null}
  {
    "to": "+5215512345678",
    "type": "document",
    "document": {
      "link": "https://example.com/factura.pdf",
      "filename": "factura-enero-2026.pdf",
      "caption": "Tu factura del mes de enero"
    }
  }
  ```
</RequestExample>

### Con media\_id

```json theme={null}
{
  "to": "+5215512345678",
  "type": "document",
  "document": {
    "id": "123456789012345",
    "filename": "contrato.pdf",
    "caption": "Contrato firmado"
  }
}
```

### Campos

<ParamField body="document.link" type="string">
  URL pública del documento.
</ParamField>

<ParamField body="document.id" type="string">
  ID de media obtenido de `/media/v1`.
</ParamField>

<ParamField body="document.filename" type="string" required>
  Nombre del archivo que verá el usuario al descargar. **Recomendado** para mejor UX.
</ParamField>

<ParamField body="document.caption" type="string">
  Descripción opcional del documento.
</ParamField>

***

## Sticker

Formato soportado: **WebP**\
Tamaño máximo: **500 KB**\
Dimensiones: **512x512 píxeles** (recomendado)

<Note>
  Los stickers animados deben usar WebP animado y no exceder 500KB.
</Note>

### Ejemplo

<RequestExample>
  ```json Request theme={null}
  {
    "to": "+5215512345678",
    "type": "sticker",
    "sticker": {
      "link": "https://example.com/sticker.webp"
    }
  }
  ```
</RequestExample>

### Con media\_id

```json theme={null}
{
  "to": "+5215512345678",
  "type": "sticker",
  "sticker": {
    "id": "123456789012345"
  }
}
```

### Campos

<ParamField body="sticker.link" type="string">
  URL pública del sticker en formato WebP.
</ParamField>

<ParamField body="sticker.id" type="string">
  ID de media obtenido de `/media/v1`.
</ParamField>

<Warning>
  Los stickers no soportan `caption`. Son elementos visuales independientes.
</Warning>

***

## Respuesta Exitosa

<ResponseExample>
  ```json 200 OK theme={null}
  {
    "messaging_product": "whatsapp",
    "contacts": [
      { "input": "+5215512345678", "wa_id": "5215512345678" }
    ],
    "messages": [
      { "id": "550e8400-e29b-41d4-a716-446655440000", "wamid": "wamid.HBgLNTIxNTUx..." }
    ],
    "data": {
      "id": "550e8400-e29b-41d4-a716-446655440000",
      "conversationId": "660e8400-e29b-41d4-a716-446655440001",
      "messageType": "image",
      "direction": "outbound",
      "status": "sent",
      "createdAt": "2026-01-22T10:30:00Z"
    }
  }
  ```
</ResponseExample>

***

## Límites de Tamaño

| Tipo       | Formatos                | Tamaño Máximo |
| ---------- | ----------------------- | ------------- |
| `image`    | JPEG, PNG, WebP         | 5 MB          |
| `video`    | MP4, 3GPP               | 16 MB         |
| `audio`    | AAC, MP3, OGG, AMR      | 16 MB         |
| `document` | PDF, DOC, XLS, PPT, TXT | 100 MB        |
| `sticker`  | WebP                    | 500 KB        |

***

## Errores Comunes

### Media No Descargable (131052)

```json theme={null}
{
  "error": "media_download_failed",
  "message": "No se pudo descargar el archivo multimedia",
  "code": "131052"
}
```

**Solución**: Usa una URL pública o sube el archivo via [/media/v1](/api-reference/media/upload-media).

### Tipo de Media No Soportado (131051)

```json theme={null}
{
  "error": "unsupported_media_type",
  "message": "El formato del archivo no es compatible",
  "code": "131051"
}
```

**Solución**: Convierte el archivo a un formato soportado.

### Archivo Demasiado Grande (131053)

```json theme={null}
{
  "error": "file_too_large",
  "message": "El archivo excede el tamaño máximo permitido",
  "code": "131053"
}
```

**Solución**: Comprime el archivo o divídelo en partes más pequeñas.

***

## Flujo Recomendado para Archivos Grandes

```mermaid theme={null}
sequenceDiagram
    participant App as Tu App
    participant Whaapy as Whaapy API
    participant Meta as Meta CDN

    App->>Whaapy: POST /media/v1 (archivo)
    Whaapy->>Meta: Upload a CDN
    Meta-->>Whaapy: media_id
    Whaapy-->>App: { media_id: "123..." }
    
    App->>Whaapy: POST /messages/v1 (con media_id)
    Whaapy->>Meta: Enviar mensaje con media_id
    Meta-->>Whaapy: Mensaje enviado
    Whaapy-->>App: { status: "sent" }
```

<Tip>
  El `media_id` expira después de \~30 días. Puedes reutilizarlo para enviar el mismo archivo a múltiples destinatarios sin re-subirlo.
</Tip>

***

## Conversión Automática (autoConvert)

Cuando un archivo excede el límite de tamaño para su tipo, puedes usar `autoConvert: true` para que Whaapy intente comprimir automáticamente y, si la compresión no es suficiente, envíe el archivo como documento.

<ParamField body="autoConvert" type="boolean" default="false">
  Habilita compresión automática y conversión a documento como fallback
</ParamField>

### Comportamiento

| Tipo       | Límite | Con autoConvert                                                                              |
| ---------- | ------ | -------------------------------------------------------------------------------------------- |
| `image`    | 5 MB   | Comprime con calidad progresiva (85% → 70% → 50%). Si sigue excediendo, envía como documento |
| `video`    | 16 MB  | **No comprime** (muy costoso). Si excede, envía como documento directamente                  |
| `audio`    | 16 MB  | Comprime a MP3 64kbps mono. Si sigue excediendo, envía como documento                        |
| `document` | 100 MB | Sin cambios (ya tiene el límite más alto)                                                    |

### Ejemplo: Imagen Grande con autoConvert

```json theme={null}
{
  "to": "+5215512345678",
  "type": "image",
  "image": {
    "link": "https://example.com/foto-alta-resolucion.jpg",
    "caption": "Foto en alta resolución"
  },
  "autoConvert": true
}
```

**Sin `autoConvert`**: Si la imagen excede 5MB, recibirás error 413.

**Con `autoConvert: true`**:

1. Whaapy intenta comprimir la imagen
2. Si la compresión es exitosa → se envía como imagen
3. Si la compresión no es suficiente → se envía como documento

### Respuesta cuando se convierte a documento

```json theme={null}
{
  "messaging_product": "whatsapp",
  "messages": [{ "id": "..." }],
  "data": {
    "messageType": "document",
    "metadata": {
      "originalType": "image",
      "wasConverted": true,
      "reason": "Exceeded size limit after compression"
    }
  }
}
```

<Warning>
  Cuando un archivo se envía como documento, el destinatario no verá una vista previa en la conversación. Deberá descargarlo para verlo.
</Warning>

<Tip>
  Para mejor experiencia de usuario, comprime tus imágenes antes de enviarlas. Si usas Cloudinary o servicios similares, agrega transformaciones como `q_auto,w_1920` para reducir el tamaño automáticamente.
</Tip>

***

## Error de Tamaño (media\_too\_large)

Cuando un archivo excede el límite y `autoConvert` está deshabilitado:

```json theme={null}
{
  "error": "media_too_large",
  "message": "image exceeds 5MB limit (7.9MB)",
  "suggestion": "Use autoConvert:true to auto-compress, or send as document type",
  "limits": {
    "image": "5MB",
    "video": "16MB",
    "audio": "16MB",
    "document": "100MB"
  }
}
```

<Info>
  El error incluye los límites actuales de Meta WhatsApp Cloud API para tu referencia.
</Info>

***

## Control de IA (Opcional)

Puedes controlar el comportamiento del agente IA al enviar mensajes de media usando el campo `ai`:

<ParamField body="ai.pause" type="boolean">
  Pausar la IA después de enviar este mensaje
</ParamField>

<ParamField body="ai.pauseDuration" type="number">
  Duración de la pausa en minutos (default: 5, máximo: 1440)
</ParamField>

<ParamField body="ai.disable" type="boolean">
  Desactivar la IA permanentemente en esta conversación
</ParamField>

### Ejemplo: Enviar Imagen y Pausar IA

```json theme={null}
{
  "to": "+5215512345678",
  "type": "image",
  "image": {
    "link": "https://example.com/producto.jpg",
    "caption": "Aquí está la foto que pediste"
  },
  "ai": { "pause": true, "pauseDuration": 30 }
}
```

<Info>
  Esto es útil cuando integras con sistemas externos (n8n, Zapier, CRMs) y necesitas evitar que la IA responda automáticamente. Ver [Agente IA](/api-reference/agent/overview) para más opciones.
</Info>

***

## Próximos Pasos

<CardGroup cols={2}>
  <Card title="Subir Media" icon="upload" href="/api-reference/media/upload-media">
    Endpoint para subir archivos grandes
  </Card>

  <Card title="Enviar Templates" icon="table-layout" href="/api-reference/messages/send-templates">
    Mensajes fuera de ventana 24h
  </Card>

  <Card title="Agente IA" icon="robot" href="/api-reference/agent/overview">
    Controla cuándo la IA responde
  </Card>
</CardGroup>
