Guide · API REST
Générer un PDF à partir de JSON et d'un modèle Word
Vos données sont en JSON, la mise en page est un modèle Word avec des champs de fusion standard. Un appel remplit les champs, développe les tableaux répétés, place les images et renvoie le PDF ou le DOCX fini.
Pourquoi ne pas construire le PDF dans le code
- Une bibliothèque PDF fait de la mise en page une tâche de programmation ; les responsables du document ne peuvent plus le modifier.
- Le publipostage exige Word sur un poste et produit un fichier par exécution, pas un par enregistrement depuis une API.
- Chaque format de modèle avec sa propre syntaxe impose une formation et des modèles captifs.
La requête
Les données voyagent dans une enveloppe fields : champs scalaires en paires nom/valeur, régions répétées sous lists, chaque ligne avec ses propres champs. Les noms correspondent aux codes MERGEFIELD et au marqueur TableStart du modèle.
TOKEN=$(curl -sS https://auth.xgenerate.io/realms/xgenerate/protocol/openid-connect/token \
-d grant_type=client_credentials \
-d client_id="$XGENERATE_CLIENT_ID" \
-d client_secret="$XGENERATE_CLIENT_SECRET" | jq -r .access_token)
cat > fields.json <<'JSON'
{
"fields": [
{ "name": "recipient.name", "value": "Camille Durand" },
{ "name": "invoice.number", "value": "2026-0042" },
{ "name": "invoice.date", "value": "25.10.2026" }
],
"lists": [
{ "name": "invoice.lines", "value": [
{ "fields": [ { "name": "description", "value": "Consulting, October" },
{ "name": "amount", "value": "CHF 4'800.00" } ] },
{ "fields": [ { "name": "description", "value": "Travel expenses" },
{ "name": "amount", "value": "CHF 312.40" } ] }
] }
]
}
JSON
# The Word template carries MERGEFIELD placeholders and a TableStart:invoice.lines region.
curl -sS https://api.xgenerate.io/v2/documents/generate \
-H "Authorization: Bearer $TOKEN" \
-F "file=@invoice.docx" \
-F "fields=@fields.json;type=application/json" \
-F "format=PDF" \
-o invoice.pdfDepuis .NET
using System.Net.Http.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new("Bearer", token);
var request = new
{
filename = "invoice.docx",
content = Convert.ToBase64String(await File.ReadAllBytesAsync("invoice.docx")),
format = "PDF",
fields = new
{
fields = new[]
{
new { name = "recipient.name", value = "Camille Durand" },
new { name = "invoice.number", value = "2026-0042" }
},
lists = new[]
{
new
{
name = "invoice.lines",
value = new[]
{
new
{
fields = new[]
{
new { name = "description", value = "Consulting, October" },
new { name = "amount", value = "CHF 4'800.00" }
}
}
}
}
}
}
};
var response = await http.PostAsJsonAsync(
"https://api.xgenerate.io/v2/documents/generate", request);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<GenerateResult>();
await File.WriteAllBytesAsync(result!.Filename, Convert.FromBase64String(result.Content));
record GenerateResult(string Filename, string Content, string Format);La réponse
L'appel multipart renvoie le PDF en octets bruts ; le transport JSON renvoie filename, content, format et warnings. Un avertissement nomme un emplacement d'image, de QR ou d'en-tête resté sans valeur, jamais une requête échouée ; les champs de fusion sans données sont supprimés sans avertissement.
Le résultat

Ce que XGenerate ne fait pas
Les données arrivent dans l'enveloppe fields (paires nom/valeur, listes, images), pas en JSON arbitraire. Les blocs conditionnels dépendant d'une valeur ne sont pas pris en charge ; les champs IF de Word autour d'un texte le sont.
Essayez-le sur votre propre modèle
Envoyez-nous un fichier Word que vous utilisez aujourd'hui. Nous le rendons avec vos données et vous renvoyons le PDF avec le modèle adapté, pour que votre évaluation ne dépende pas de nous.
Demander une démo