Actualizado el 25/10/2026
Para enviar un archivo con la API de WhatsApp, haces un POST al endpoint de mensajes con type igual a image, document, audio o video e indicas el archivo de dos maneras: con el id de un medio que subiste antes al endpoint /media o con un link público. Meta recomienda subir el archivo y usar el id, y acepta imágenes JPEG y PNG de hasta 5 MB, audio y video de hasta 16 MB y documentos de hasta 100 MB. Fuera de la ventana de 24 horas, el archivo solo puede ir como encabezado de una plantilla aprobada.
Esta guía muestra los formatos aceptados, cuándo subir o enlazar, cuánto dura un media ID, cómo recibir y descargar los archivos que envía el cliente y ejemplos listos en cURL, Node.js y Python.
Carga o enlace: las dos formas de enviar multimedia
Todo mensaje multimedia de la Cloud API lleva un objeto con el nombre del tipo (image, document, audio, video o sticker). Dentro va uno de estos campos, nunca los dos:
| Campo | Qué es | Cuándo usarlo |
|---|---|---|
id | ID que devuelve POST /<PHONE_NUMBER_ID>/media después de la carga | Recomendado por Meta. Archivos reutilizados en muchos envíos, campañas, archivos privados |
link | URL HTTPS pública donde está alojado el archivo | Envíos puntuales, archivos que ya están en un CDN. Meta marca esta opción como «no recomendada» por rendimiento |
Con link, los servidores de Meta tienen que descargar el archivo de tu servidor en el momento del envío. Si la URL pide inicio de sesión, redirige a una página HTML o devuelve un Content-Type distinto del archivo real, el envío falla. Con id, el archivo ya está en Meta y el envío no depende de que tu servidor esté disponible.
Un patrón habitual: el archivo que va a mucha gente (el catálogo en PDF, el video tutorial) se sube una vez a /media y el id se reutiliza mientras esté vigente. Los archivos generados al momento (una factura, un comprobante) van por un link firmado de corta duración o por una carga justo antes del envío.
Formatos y límites de tamaño oficiales
La tabla resume la página de multimedia de la Cloud API:
| Tipo | Formatos (MIME) | Tamaño máximo |
|---|---|---|
| Imagen | image/jpeg, image/png (8 bits, RGB o RGBA) | 5 MB |
| Documento | application/pdf, text/plain, Word (.doc, .docx), Excel (.xls, .xlsx), PowerPoint (.ppt, .pptx) | 100 MB |
| Audio | audio/aac, audio/amr, audio/mpeg (MP3), audio/mp4 (M4A), audio/ogg (solo códec OPUS, mono) | 16 MB |
| Video | video/mp4, video/3gpp (video H.264 y audio AAC) | 16 MB |
| Sticker | image/webp | 100 KB estático, 500 KB animado |
Detalles que suelen provocar fallas:
- Pie de foto.
captionadmite hasta 1.024 caracteres en imagen, video y documento. El audio no lleva pie. - Documento. El campo
filenamedefine el nombre que se muestra, y su extensión elige el ícono en la app. Solo los tipos de la tabla tienen visualización garantizada; otros se pueden enviar, pero Meta no garantiza cómo se verán. - Video en Android. Meta advierte que el perfil H.264 «High» con B-frames no es compatible con WhatsApp en Android. Usa el perfil «Main» sin B-frames o «Baseline» y coloca el átomo
moovantes demdat(en ffmpeg,-movflags faststart). - MIME incorrecto. Si la extensión o el tipo declarado no coincide con el contenido real, el envío falla con el error
131053. En Linux o macOS,file -I archivo.pngmuestra el tipo real.
Conversión de un video al formato más compatible:
ffmpeg -i entrada.mov -c:v libx264 -profile:v main -bf 0 \
-c:a aac -ac 2 -movflags faststart salida.mp4
Audio común y mensaje de voz
La Cloud API distingue dos tipos de audio, según la documentación de mensajes de audio:
- Audio común. Se muestra con ícono de descarga y de música. Acepta cualquier formato de la tabla.
- Mensaje de voz. Envía
"voice": truedentro del objetoaudio. El archivo debe ser.oggcon códec OPUS, mono. Se muestra con la foto del perfil de la empresa y el ícono de micrófono, se descarga automáticamente y puede transcribirse en la app del cliente. El botón de reproducir solo aparece en archivos de hasta 512 KB; por encima de eso, el cliente ve el ícono de descarga.
Para convertir un MP3 en nota de voz compatible:
ffmpeg -i audio.mp3 -c:a libopus -ac 1 -b:a 32k voz.ogg
Paso 1: subir el archivo y obtener el media ID
La carga es un multipart/form-data con tres campos obligatorios: file, type (el MIME) y messaging_product=whatsapp.
curl -X POST "https://graph.facebook.com/v26.0/PHONE_NUMBER_ID/media" \
-H "Authorization: Bearer $WHATSAPP_TOKEN" \
-F "file=@catalogo.pdf;type=application/pdf" \
-F "type=application/pdf" \
-F "messaging_product=whatsapp"
Respuesta:
{ "id": "1037543291543636" }
El token necesita el permiso whatsapp_business_messaging. En producción, usa un token permanente de usuario del sistema en lugar del token temporal del panel.
Cuánto dura un media ID
| Origen del ID | Vigencia |
|---|---|
| Carga hecha por ti | 30 días (el archivo queda cifrado hasta que se elimine o venza) |
| Multimedia recibida por webhook | 7 días para descargarla |
URL de descarga obtenida con GET /<MEDIA_ID> | 5 minutos |
Guarda la fecha de carga junto con el id y vuelve a subir el archivo antes de los 30 días si lo vas a usar más tiempo. Para borrarlo antes, usa DELETE /<MEDIA_ID>.
Paso 2: enviar el mensaje multimedia
Con el id, el envío es igual al de un mensaje de texto por la API, cambiando el tipo:
curl -X POST "https://graph.facebook.com/v26.0/PHONE_NUMBER_ID/messages" \
-H "Authorization: Bearer $WHATSAPP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"messaging_product": "whatsapp",
"recipient_type": "individual",
"to": "5215512345678",
"type": "document",
"document": {
"id": "1037543291543636",
"filename": "catalogo-octubre.pdf",
"caption": "Te enviamos el catálogo de octubre"
}
}'
La respuesta trae el wamid del mensaje. Solo confirma que Meta aceptó la solicitud; la entrega, la lectura y las fallas llegan después por webhook, como explica el artículo sobre estados de mensaje por webhook.
Ejemplo en Node.js (carga + envío)
Usa fetch, FormData y Blob nativos de Node.js 18 o superior:
import { readFile } from 'node:fs/promises';
const GRAPH = 'https://graph.facebook.com/v26.0';
const PHONE_ID = process.env.PHONE_NUMBER_ID;
const TOKEN = process.env.WHATSAPP_TOKEN;
async function subirMedio(ruta, mime) {
const form = new FormData();
form.append('messaging_product', 'whatsapp');
form.append('type', mime);
form.append('file', new Blob([await readFile(ruta)], { type: mime }), ruta.split('/').pop());
const r = await fetch(`${GRAPH}/${PHONE_ID}/media`, {
method: 'POST',
headers: { Authorization: `Bearer ${TOKEN}` },
body: form,
});
const cuerpo = await r.json();
if (!r.ok) throw new Error(JSON.stringify(cuerpo.error));
return cuerpo.id;
}
async function enviarImagen(para, mediaId, pie) {
const r = await fetch(`${GRAPH}/${PHONE_ID}/messages`, {
method: 'POST',
headers: { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
messaging_product: 'whatsapp',
to: para,
type: 'image',
image: { id: mediaId, caption: pie },
}),
});
return r.json();
}
const id = await subirMedio('./producto.jpg', 'image/jpeg');
console.log(await enviarImagen('5215512345678', id, 'Llegó el nuevo modelo'));
Ejemplo en Python (enlace público y nota de voz)
import os
import requests
GRAPH = "https://graph.facebook.com/v26.0"
PHONE_ID = os.environ["PHONE_NUMBER_ID"]
HEADERS = {"Authorization": f"Bearer {os.environ['WHATSAPP_TOKEN']}"}
def enviar(payload: dict) -> dict:
payload = {"messaging_product": "whatsapp", **payload}
r = requests.post(f"{GRAPH}/{PHONE_ID}/messages", json=payload, headers=HEADERS, timeout=30)
r.raise_for_status()
return r.json()
# Video alojado en tu CDN
enviar({
"to": "5215512345678",
"type": "video",
"video": {"link": "https://cdn.ejemplo.com/tutorial.mp4", "caption": "Cómo instalar"},
})
# Nota de voz a partir de una carga
with open("voz.ogg", "rb") as f:
up = requests.post(
f"{GRAPH}/{PHONE_ID}/media",
headers=HEADERS,
data={"messaging_product": "whatsapp", "type": "audio/ogg"},
files={"file": ("voz.ogg", f, "audio/ogg")},
timeout=60,
)
up.raise_for_status()
enviar({"to": "5215512345678", "type": "audio", "audio": {"id": up.json()["id"], "voice": True}})
Multimedia fuera de la ventana de 24 horas: encabezado de plantilla
Los mensajes de imagen, video, audio y documento son mensajes libres. Solo se pueden enviar con la ventana de atención de 24 horas abierta por el cliente. Para mandar un archivo a alguien que no te escribió en las últimas 24 horas, crea una plantilla con encabezado multimedia (imagen, video o documento) y completa el archivo en el envío:
{
"messaging_product": "whatsapp",
"to": "5215512345678",
"type": "template",
"template": {
"name": "copia_factura",
"language": { "code": "es_MX" },
"components": [
{
"type": "header",
"parameters": [
{ "type": "document", "document": { "id": "1037543291543636", "filename": "factura.pdf" } }
]
},
{ "type": "body", "parameters": [{ "type": "text", "text": "María" }] }
]
}
}
En Brasil, así es como las empresas envían el boleto (comprobante de pago bancario) en PDF a clientes que no escribieron hace poco. Las categorías y la aprobación de plantillas se explican en cómo Meta clasifica tu plantilla.
Recibir y descargar archivos que envía el cliente
Cuando el cliente manda una foto, un PDF o un audio, el webhook trae el objeto del tipo con id, mime_type y sha256 (y caption o filename, cuando existan):
{
"from": "5215512345678",
"id": "wamid.HBgM...",
"type": "image",
"image": { "id": "1489362375523190", "mime_type": "image/jpeg", "sha256": "8f2c..." }
}
Descargarlo requiere dos llamadas:
# 1. Obtener la URL temporal (vale 5 minutos)
curl "https://graph.facebook.com/v26.0/1489362375523190" \
-H "Authorization: Bearer $WHATSAPP_TOKEN"
# 2. Descargar el binario de la URL devuelta, con el mismo token
curl -L "URL_DEVUELTA" -H "Authorization: Bearer $WHATSAPP_TOKEN" -o foto.jpg
Sin el header Authorization, la descarga falla. Si da 404, pide una URL nueva y vuelve a intentar. Descarga enseguida y guarda el archivo en tu almacenamiento: el ID recibido vence a los 7 días. El límite de multimedia entrante es de 100 MB; por encima, el webhook llega con el error 131052, y lo ideal es pedirle al cliente un archivo más pequeño.
Errores más comunes al enviar multimedia
| Síntoma | Causa probable | Qué hacer |
|---|---|---|
Error 131053 | MIME declarado distinto del contenido o formato no compatible | Revisa el tipo real del archivo y usa un formato de la tabla |
Error 131052 (multimedia entrante) | Archivo del cliente de más de 100 MB | Pide un archivo más pequeño |
Falla el envío con link | URL privada, redirección a HTML, certificado inválido | Prueba la URL con curl -I desde fuera de tu red o sube el archivo |
Falla el envío con id | ID vencido (más de 30 días) o subido en otro número | Vuelve a subirlo con el mismo phone_number_id |
| El video no abre en Android | H.264 High con B-frames | Recodifica en Main o Baseline |
| El audio llega sin botón de reproducir | Archivo de más de 512 KB o fuera de OGG OPUS | Baja el bitrate y envíalo como voice |
Para la lista completa de códigos, consulta errores de la API de WhatsApp.
Cómo hacerlo con Vectalk
En Vectalk, los payloads multimedia son los mismos de la Cloud API. Cambian la URL base y el token:
- Carga:
POST https://apis.vectalk.com.br/api/media(multipart, confile,typeymessaging_product), con un token de instancia. - Envío:
POST https://apis.vectalk.com.br/api/messagescon el mismo JSON de imagen, documento, audio o video. - Multimedia recibida:
GET /api/media/{mediaId}devuelve la URL temporal, yGET /api/media/{mediaId}/downloaddevuelve el binario directamente. - Eliminar:
DELETE /api/media/{mediaId}.
curl -X POST https://apis.vectalk.com.br/api/media \
-H "Authorization: Bearer $VECTALK_TOKEN" \
-F "file=@producto.jpg" \
-F "type=image/jpeg" \
-F "messaging_product=whatsapp"
Las rutas están en Carga de multimedia e Imagen (documentación en portugués). El costo de los mensajes se incluye en la factura de Vectalk, sin tarjeta registrada en Meta. Para empezar, crea tu cuenta en apps.vectalk.com.br/register.
Preguntas frecuentes
¿Puedo enviar una imagen WebP?
No como mensaje de imagen. La Cloud API acepta JPEG y PNG para imágenes. WebP se usa solo en stickers. Conviértela antes de subirla.
¿Cuál es el tamaño máximo de un PDF en la API de WhatsApp?
100 MB, el mismo límite de todos los documentos compatibles (PDF, TXT, Word, Excel y PowerPoint).
¿Enviar multimedia cuesta más que enviar texto?
No. Meta cobra por mensaje entregado según su categoría, no por el tipo de contenido. Una imagen enviada dentro de la ventana de atención es un mensaje de servicio, igual que un texto libre: desde el 1 de octubre de 2026, cada número tiene 1.000 mensajes de servicio gratis al mes, y el cobro empieza en el 1.001. El cálculo está en cuánto cuesta una campaña de WhatsApp.
¿Puedo reutilizar el mismo media ID en miles de envíos?
Sí, mientras esté vigente (30 días después de la carga). Es la forma recomendada para campañas con el mismo archivo, porque evita que Meta descargue el archivo de tu servidor en cada envío.
¿Cómo envío varios archivos en un mismo mensaje?
No existe un tipo de mensaje de álbum. Cada archivo es un mensaje aparte, con su propio wamid y estado.
Fuentes oficiales consultadas el 25/10/2026: Media (Cloud API), Image messages, Document messages, Audio messages, Video messages, Documentación de Vectalk: carga de multimedia.
