È il caso d'uso più comune di un modello di utilità: mandare la fattura. Un modello di Meta può avere un'intestazione con un documento, un'immagine o un video, e quel file si sceglie a ogni invio — il modello approvato definisce il TIPO, tu metti il file.
Come si manda. Come qualsiasi modello (POST /v1/messages con type: "template"), ma l'array components contiene per primo un componente header con il file:
{ "type": "header", "parameters": [ { "type": "document", "document": { "link": "https://…/A-1042.pdf", "filename": "Factura A-1042.pdf" } } ] }
Da dove viene il file: da un tuo link. Meta accetta link (un URL https pubblico che scarica lei) o id (un identificativo di media). Connect non archivia file e non ha un endpoint di caricamento, quindi gli unici id che esistono sono quelli dei file che hai RICEVUTO — per mandare una tua fattura, ospitala e manda il link. È lo stesso criterio di «Inviare media», e per lo stesso motivo: non conserviamo contenuti.
⚠ Il tipo del parametro lo decide il MODELLO, non il file. Se Meta ha approvato l'intestazione come DOCUMENT, il parametro va come document anche se il file è un JPG. Se mandi image su un modello DOCUMENT, Meta lo rifiuta.
⚠ filename è solo per i documenti (è il nome che vede chi lo riceve). Su immagini e video, Meta lo rifiuta.
🔴 Cosa NON si può fare: CREARE un modello con intestazione di file da Connect. Si creano solo intestazioni di testo. Se mandi un header.format di immagine/documento/video a POST /v1/templates, ti rispondiamo 400 TEMPLATE_PRECHECK_FAILED con il codice TPL_HEADER_FORMAT_UNSUPPORTED — non lo creiamo a metà né ti diciamo di sì. La strada è: crealo nel Business Manager di Meta (lì le intestazioni di file sono accettate) e poi POST /v1/templates/sync — Connect lo legge correttamente, lo elenca, ti avvisa quando cambia stato e lo invia come descritto sopra.
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.Come sapere se un modello ha un file: GET /v1/templates restituisce header: { format: "DOCUMENT" } (o IMAGE/VIDEO). Nel pannello sono segnati con 📎.
Se dimentichi il file te lo diciamo PRIMA di Meta: 422 TEMPLATE_HEADER_MEDIA_REQUIRED, con details.example = il componente esatto che manca. Meta, invece, risponde con un 132000 poco chiaro.
E se arriva comunque (un modello che non abbiamo ancora sincronizzato), il messaggio fallisce al primo tentativo con lastErrorCode = TEMPLATE_PARAM_MISMATCH — non si ritenta cinque volte un payload che non può funzionare.
Cosa serve al link: essere https, puntare direttamente al file (senza login né pagine intermedie) e avere il Content-Type corretto. ⚠ Un link di "condivisione" di Google Drive o Dropbox restituisce una pagina HTML: Meta la scarica e rifiuta l'invio. Limiti di Meta: documento 100 MB, immagine 5 MB, video 16 MB.
Meta tiene in cache il tuo link per 10 minuti: se cambi il file dietro lo stesso URL, aggiungi un ?v=… diverso.