Documentación / Completo
Enviar una plantilla con un archivo en el encabezado
POST /v1/messages
¿Programás con IA? Conectala a tu cuenta por MCP: revisa tu configuración, crea webhooks y plantillas con tu confirmación y te escribe el código. Ver cómo →
Es el caso de uso más común de una plantilla de utilidad: mandar la factura. Una plantilla de Meta puede llevar un encabezado con un documento, una imagen o un video, y ese archivo se elige en cada envío — la plantilla aprobada define el TIPO, vos ponés el archivo.
Cómo se manda. Igual que cualquier plantilla (POST /v1/messages con type: "template"), pero el array components lleva primero un componente header con el archivo:
{ "type": "header", "parameters": [ { "type": "document", "document": { "link": "https://…/A-1042.pdf", "filename": "Factura A-1042.pdf" } } ] }
De dónde sale el archivo: de un enlace tuyo. Meta acepta link (una URL https pública que descarga ella) o id (un identificador de media). Connect no almacena archivos y no tiene endpoint de subida, así que los únicos id que existen son los de archivos que RECIBISTE — para mandar una factura tuya, hospedala y mandá el enlace. Es el mismo criterio que en «Enviar media», y por la misma razón: no guardamos contenido.
⚠ El tipo del parámetro lo manda la PLANTILLA, no el archivo. Si Meta aprobó el encabezado como DOCUMENT, el parámetro va como document aunque el archivo sea un JPG. Mandar image sobre una plantilla DOCUMENT lo rechaza Meta.
⚠ filename es sólo para documentos (es el nombre que ve quien lo recibe). En imagen y video, Meta lo rechaza.
✅ Crearla con encabezado de archivo también se puede desde Connect (desde la versión 0.22.0): subís la muestra con POST /v1/templates/media y mandás su handle en POST /v1/templates — está en «Crear plantillas con imagen, documento y botones».
curl -X POST https://api.waiaconnect.com/v1/messages \
-H "Authorization: Bearer wc_live_YOUR_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"connectionId":"conn_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX","to":"5493511234567","type":"template","template":{"name":"envio_factura","language":"es","components":[{"type":"header","parameters":[{"type":"document","document":{"link":"https://your-server.example/invoices/A-1042.pdf","filename":"Factura A-1042.pdf"}}]},{"type":"body","parameters":[{"type":"text","text":"María"}]}]}}'
# The header component goes FIRST and its type is the one the APPROVED TEMPLATE
# declares (document | image | video) — NOT the file's mime type.
# image: {"type":"image","image":{"link":"https://…/photo.jpg"}} (no filename)
# by media id instead of a link: {"document":{"id":"1234567890"}}
# ⚠ You cannot CREATE a media-header template from Connect (only TEXT headers).
# Create it in Meta Business Manager, then POST /v1/templates/sync.Cómo saber si una plantilla lleva archivo: GET /v1/templates devuelve header: { format: "DOCUMENT" } (o IMAGE/VIDEO). En el panel están marcadas con 📎.
Si te olvidás del archivo te lo decimos ANTES de Meta: 422 TEMPLATE_HEADER_MEDIA_REQUIRED, con details.example = el componente exacto que falta. Meta, en cambio, contesta un 132000 opaco.
Y si llega igual (una plantilla que todavía no sincronizamos), el mensaje falla en el primer intento con lastErrorCode = TEMPLATE_PARAM_MISMATCH — no se reintenta cinco veces un payload que no puede funcionar.
Qué necesita el enlace: ser https, apuntar directo al archivo (sin login ni página intermedia) y traer el Content-Type correcto. ⚠ Un enlace de "compartir" de Google Drive o Dropbox devuelve una página HTML: Meta la descarga y rechaza el envío. Límites de Meta: documento 100 MB, imagen 5 MB, video 16 MB.
Meta cachea tu enlace 10 minutos: si cambiás el archivo detrás de la misma URL, agregale un ?v=… distinto.