Payload di esempio
Cinque documenti che si producono ogni giorno, ciascuno come il JSON che invii e un modello minimo che lo legge. Copia la coppia, generala una volta, poi personalizza il modello: la forma dei dati resta quella.
Ogni modello è in HTML perché sta nella pagina; gli stessi tag funzionano in un modello Word o
Excel (Scrivere un modello, Elenchi
e righe ripetute). Invia qualsiasi payload come data in
POST /api/v1/compose/documents/generate, con l'id del tuo modello in
settings.templateId (Generare un documento). Per un
modello che hai già caricato, la console precompila un esempio tutto suo nella pagina del modello,
sotto Prova con JSON.
Una fattura: righe e totali
Un elenco (lines) che diventa una riga per elemento, e totali che calcoli e formatti
tu: il modello colloca i valori, non fa i conti.
{
"number": "2026-001",
"date": "31/10/2026",
"customer": {"name": "Acme S.r.l.", "vatNumber": "IT01234567890",
"address": "Via Roma 1, 20121 Milano"},
"lines": [
{"description": "Consulenza", "quantity": "2", "price": "500,00", "amount": "1.000,00"},
{"description": "Trasferta", "quantity": "1", "price": "240,00", "amount": "240,00"}
],
"net": "1.240,00", "vat": "272,80", "total": "1.512,80"
}
<h1>Fattura {{ number }} del {{ date }}</h1>
<p>{{ customer.name }} · P.IVA {{ customer.vatNumber }}<br>{{ customer.address }}</p>
<table style="table-layout: fixed; width: 100%">
<thead><tr><th>Descrizione</th><th>Q.tà</th><th>Prezzo</th><th>Importo</th></tr></thead>
<tbody>
{% for l in lines %}
<tr><td>{{ l.description }}</td><td>{{ l.quantity }}</td><td>{{ l.price }}</td><td>{{ l.amount }}</td></tr>
{% endfor %}
</tbody>
</table>
<p>Imponibile {{ net }} · IVA {{ vat }} · <strong>Totale {{ total }}</strong></p>
Un preventivo: una parte che compare solo quando serve
Una sezione sconto stampata solo quando il payload ne contiene uno. Ometti il campo, o invialo vuoto, e la sezione non compare nel documento.
{
"number": "PREV-2026-014",
"customer": {"name": "Acme S.r.l."},
"validUntil": "30/11/2026",
"items": [
{"description": "Licenza annuale", "amount": "1.200,00"},
{"description": "Formazione (1 giorno)", "amount": "600,00"}
],
"discount": "10%",
"total": "1.620,00"
}
<h1>Preventivo {{ number }}</h1>
<p>Per {{ customer.name }}, valido fino al {{ validUntil }}.</p>
<ul>{% for i in items %}<li>{{ i.description }}: {{ i.amount }}</li>{% endfor %}</ul>
{% if discount %}<p>Sconto applicato: {{ discount }}</p>{% endif %}
<p><strong>Totale {{ total }}</strong></p>
Un documento di trasporto: un elenco dentro un elenco
Colli, ciascuno con la propria merce: un ciclo dentro un ciclo. Il nome interno (i)
legge l'elenco del collo corrente. Dentro un oggetto, non chiamare un elenco items,
keys o values: p.items è il metodo dell'oggetto stesso, non il tuo elenco.
{
"number": "DDT-2026-087",
"date": "31/10/2026",
"recipient": {"name": "Acme S.r.l.", "address": "Via Roma 1, 20121 Milano"},
"packages": [
{"label": "Collo 1", "goods": [{"code": "A-100", "description": "Staffa", "quantity": "20"},
{"code": "A-200", "description": "Vite M6", "quantity": "200"}]},
{"label": "Collo 2", "goods": [{"code": "B-310", "description": "Pannello", "quantity": "4"}]}
]
}
<h1>Documento di trasporto {{ number }} del {{ date }}</h1>
<p>Destinatario: {{ recipient.name }}, {{ recipient.address }}</p>
{% for p in packages %}
<h2>{{ p.label }}</h2>
<table style="table-layout: fixed; width: 100%">
{% for i in p.goods %}<tr><td>{{ i.code }}</td><td>{{ i.description }}</td><td>{{ i.quantity }}</td></tr>{% endfor %}
</table>
{% endfor %}
Un report mensile: cifre e una tabella
Qualche cifra di sintesi e una tabella di righe. Una tabella lunga viene generata più in fretta con un layout fisso: Una tabella lunga: fissane il layout.
{
"month": "Ottobre 2026",
"company": {"name": "Acme S.r.l."},
"figures": {"orders": "128", "revenue": "48.200,00", "returns": "3"},
"rows": [
{"day": "01/10/2026", "orders": "4", "revenue": "1.520,00"},
{"day": "02/10/2026", "orders": "6", "revenue": "2.310,00"}
]
}
<h1>{{ company.name }}: {{ month }}</h1>
<p>Ordini {{ figures.orders }} · Fatturato {{ figures.revenue }} · Resi {{ figures.returns }}</p>
<table style="table-layout: fixed; width: 100%">
<thead><tr><th>Giorno</th><th>Ordini</th><th>Fatturato</th></tr></thead>
<tbody>{% for r in rows %}<tr><td>{{ r.day }}</td><td>{{ r.orders }}</td><td>{{ r.revenue }}</td></tr>{% endfor %}</tbody>
</table>
Un contratto: parti e clausole numerate
Due parti e un elenco di clausole, pronto per essere inviato in firma: componilo e firmalo in una sola chiamata con Document Fly, posizionando le firme con i campi o i tag della guida alla firma.
{
"title": "Contratto di servizio",
"date": "31/10/2026",
"provider": {"name": "Acme S.r.l.", "representative": "Anna Rossi"},
"client": {"name": "Acme Servizi S.p.A.", "representative": "Marco Bianchi"},
"clauses": [
{"title": "Oggetto", "text": "Il fornitore presta il servizio descritto nell'allegato A."},
{"title": "Durata", "text": "Dodici mesi dalla firma, rinnovabili per iscritto."},
{"title": "Corrispettivo", "text": "1.200,00 euro annui, IVA esclusa, fatturati anticipatamente."}
]
}
<h1>{{ title }}</h1>
<p>Tra {{ provider.name }}, rappresentata da {{ provider.representative }}, e
{{ client.name }}, rappresentata da {{ client.representative }}, il {{ date }}.</p>
<ol>{% for c in clauses %}<li><strong>{{ c.title }}.</strong> {{ c.text }}</li>{% endfor %}</ol>
Il tuo payload
Va bene qualsiasi forma il tuo sistema abbia già: un modello legge gli oggetti annidati con il punto
(customer.address) e gli elenchi con un ciclo. I nomi vengono confrontati senza badare
a maiuscole e minuscole. Un campo che il modello legge e il payload non contiene viene reso vuoto e
segnalato, come TEMPLATE_FIELDS_MISSING: vedi Campi mancanti e in più.
Per controllare un payload senza generare nulla, usa
Convalida prima di inviare.