Guide · API REST
Publipostage : un PDF par destinataire
Le publipostage de Word produit un long document. Un appel d'API produit un document : bouclez sur vos destinataires, envoyez le même modèle avec les valeurs de chaque enregistrement et donnez un nom de fichier unique à chaque PDF. Courriers, attestations, fiches de paie, factures.
Là où le publipostage de Word s'arrête
- Le publipostage écrit un seul fichier pour tous les enregistrements ; le découper en PDF individuels demande des macros ou du travail manuel.
- Il exige Word sur un poste et une personne pour le lancer, donc il ne peut pas vivre dans un flux de travail ni dans un traitement nocturne.
- Pièces jointes, noms de fichiers et archivage par destinataire sont hors de portée du publipostage.
La requête
Une requête par enregistrement : la boucle construit une enveloppe fields à partir de chaque destinataire et l'envoie avec le modèle. Le service est sans état, les requêtes peuvent s'exécuter en parallèle ; le nom de fichier vous appartient.
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)
# recipients.json holds one object per letter:
# [ { "name": "Camille Durand", "street": "12 rue de la République", "city": "69002 Lyon" }, ... ]
index=0
jq -c '.[]' recipients.json | while IFS= read -r r; do
index=$((index + 1))
jq -n --argjson r "$r" '{ fields: [
{ name: "recipient.name", value: $r.name },
{ name: "recipient.street", value: $r.street },
{ name: "recipient.city", value: $r.city } ] }' > fields.json
out="letter-$index.pdf"
curl -sS https://api.xgenerate.io/v2/documents/generate \
-H "Authorization: Bearer $TOKEN" \
-F "file=@letter.docx" \
-F "fields=@fields.json;type=application/json" \
-F "format=PDF" \
-o "$out"
doneDepuis .NET
using System.Net.Http.Json;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new("Bearer", token);
var template = Convert.ToBase64String(await File.ReadAllBytesAsync("letter.docx"));
var recipients = new[]
{
new { Name = "Camille Durand", Street = "12 rue de la République", City = "69002 Lyon" },
new { Name = "Jonas Keller", Street = "Bahnhofstrasse 10", City = "8001 Zürich" }
};
// One request per recipient; the service is stateless, so run them in parallel if you like.
for (var index = 0; index < recipients.Length; index++)
{
var r = recipients[index];
var request = new
{
filename = "letter.docx",
content = template,
format = "PDF",
fields = new
{
fields = new[]
{
new { name = "recipient.name", value = r.Name },
new { name = "recipient.street", value = r.Street },
new { name = "recipient.city", value = r.City }
}
}
};
var response = await http.PostAsJsonAsync(
"https://api.xgenerate.io/v2/documents/generate", request);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<GenerateResult>();
var file = $"letter-{index + 1}.pdf";
await File.WriteAllBytesAsync(file, Convert.FromBase64String(result!.Content));
}
record GenerateResult(string Filename, string Content, string Format);La réponse
Chaque appel renvoie un PDF en octets bruts sur le transport multipart, ou filename, content, format et warnings sur le transport JSON. Les avertissements nomment les emplacements d'image, de QR et d'en-tête sans valeur ; les champs de fusion et les régions sans données sont supprimés sans avertissement.
Le résultat

Ce que XGenerate ne fait pas
Il n'y a pas de point de terminaison par lot : une requête par document, pilotée par votre boucle ou votre file. La section paiement QR suisse n'existe qu'en PDF.
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