Blog

Champs de métadonnées PDF : title, language, author, subject, creator, producer

Passage en revue, champ par champ, des six métadonnées PDF standard exposées par gPdf — title, language, author, subject, creator, producer. À quoi sert chacun, qui le lit, les erreurs courantes et comment vérifier le résultat livré.

Le pendant de Les propriétés du PDF doivent afficher votre marque, pas l’outil de quelqu’un d’autre — ce billet-là plaidait pour s’intéresser aux métadonnées PDF. Celui-ci en est le manuel d’utilisation : à quoi sert chaque champ dans la spécification PDF, qui le lit, les erreurs courantes, et comment vérifier que votre sortie a bien livré ce que vous vouliez.

gPdf expose les six champs standard que la spécification PDF définit pour les métadonnées au niveau du document. Ils se trouvent sous settings.metadata dans le JSON DocumentRequest. Chaque champ est facultatif — si vous n’en définissez pas un, gPdf retombe soit sur le default_metadata du jeton (fonctionnalité de politique Enterprise), soit sur une valeur par défaut système.

{
  "settings": {
    "metadata": {
      "title":    "...",
      "language": "...",
      "author":   "...",
      "subject":  "...",
      "creator":  "...",
      "producer": "..."
    }
  }
}

Le reste de ce billet est une section par champ. Chaque section suit la même structure : à quoi sert le champ, où il apparaît, erreurs courantes, règle empirique. L’ordre est celui dans lequel les remplir d’abord → ensuite → … → en dernier.

title — ce qu’est le document

La spécification PDF le décrit comme le « titre du document ».

Où il apparaît :

  • La barre de titre des visionneuses PDF (Adobe Reader, Preview, Foxit, la visionneuse PDF de Chromium l’affichent toutes).
  • L’onglet du navigateur quand le PDF s’ouvre en ligne (Content-Disposition: inline).
  • Les index de recherche — Spotlight, Outlook, SharePoint, l’indexeur plein texte de Google Drive lisent tous title et lui accordent un poids important.

Erreurs courantes :

  • Mettre le nom de fichier comme titre. invoice-20260318.pdf est un nom de fichier. Le titre devrait être quelque chose qu’un humain lit, comme Invoice INV-2026-3401. Nom de fichier et titre relèvent de préoccupations différentes ; le nom de fichier est pour les systèmes de fichiers, le titre est pour les visionneuses et la recherche.
  • Laisser le titre vide. Les visionneuses retombent sur le nom de fichier. Le résultat est lu comme auto-généré et produit par une machine.
  • Ajouter la marque dans le titre. Acme Logistics — Invoice INV-2026-3401 encombre la barre de titre. La marque appartient à author, pas à title.

Règle empirique : le titre devrait correspondre au H1 de la page rendue. Si la première ligne de votre modèle de facture est « Facture INV-2026-3401 », c’est le titre.

language — pour l’accessibilité, la recherche et la conformité

language est une étiquette de langue BCP-47 : en, de, zh-Hans, pt-BR, ar-SA. Définissez-la pour chaque document. Parmi les six champs, c’est celui qui a les conséquences en aval les plus concrètes pour le coût d’implémentation le plus faible — c’est pourquoi il occupe la position 2 plutôt qu’une place plus discrète.

Où il apparaît :

  • Lecteurs d’écran — JAWS, NVDA, VoiceOver l’utilisent pour choisir le bon jeu de phonèmes. Un lecteur d’écran anglais lisant un PDF language: "de" prononcera correctement les mots allemands ; sans l’étiquette, la prosodie est faussée.
  • Moteurs de recherche et indexeurs — affecte les règles de racinisation et la liste de mots vides propres à la langue. Une facture language: "zh-Hans" est indexée selon la segmentation chinoise ; en l’absence d’étiquette, le système retombe souvent sur l’anglais et l’index devient inutilisable.
  • Conformité PDF/A — PDF/A-2a et PDF/A-3a (profils d’accessibilité) exigent l’étiquette de langue. Sans elle, la validation veraPDF échoue.

Erreurs courantes :

  • La laisser non définie. Reposez-vous sur « la locale du destinataire », pas « la valeur par défaut de la plateforme ». La plupart des piles défaillantes n’écrivent simplement pas ce champ ; le résultat est des lecteurs d’écran qui prononcent mal et des index de recherche qui « racinisent » de travers.
  • Utiliser une chaîne non conforme à BCP-47 comme "english" ou "EN-US". La spécification PDF attend des étiquettes RFC 5646 : en, en-US, de, pt-BR.
  • Coder en dur la valeur par défaut de la plateforme (par ex. toujours "en") sans tenir compte de la langue réelle du document. Une facture en portugais étiquetée "en" est pire qu’un document non étiqueté — elle induit activement l’indexeur en erreur.

Règle empirique : l’étiquette doit correspondre à la langue réelle du contenu. Pour un client au Brésil qui reçoit une facture en portugais, mettez "language": "pt-BR", pas "en". Pour les documents multilingues, choisissez la langue dominante et utilisez l’attribut Lang sur les éléments de contenu individuels pour le reste — c’est une fonctionnalité d’accessibilité des PDF balisés, au-delà du champ language au niveau du document.

author — à qui appartient le document

Dans la spécification PDF, author est « le nom de la personne ou de l’organisation qui a créé le document ». Pour les PDF métier livrés à des destinataires, la réponse est presque toujours l’organisation — mais la bonne forme varie réellement selon le contexte.

Où il apparaît :

  • La fenêtre Propriétés de chaque visionneuse PDF, en évidence, libellée « Author ».
  • Les indexeurs DMS / archive, où il sert souvent de filtre.
  • Le flux de métadonnées XMP PDF/A, où il est porté dans les archives à long terme.

Erreurs courantes :

  • "author": "[email protected]" — fait fuiter accidentellement l’e-mail de l’opérateur dans chaque PDF, finit dans tous les index de recherche, devient un problème de données personnelles à long terme.
  • "author": "PDF Generator Service" — nom d’outil interne ; ne signifie rien pour le destinataire.
  • ❌ Vide — Preview et la plupart des visionneuses affichent littéralement « (no author) » dans la fenêtre Propriétés, ce qui se lit comme « personne ne possède ce document ».

Formes qui fonctionnent :

  • "author": "Acme Logistics, Inc." — organisation simple.
  • "author": "Acme Logistics — Billing" — organisation + service, pour les documents qui sont routés vers un bureau précis.
  • "author": "Bridge Capital Partners — Fund III" — utile en finance/juridique où l’attribution porte sur une entité spécifique.
  • "author": "Maria López, RICS Surveyor" — pour la publication mono-auteur (rapports, expertises, avis juridiques) où l’individu EST l’attribution éditoriale.

Règle empirique : author est l’entité à laquelle le destinataire doit associer le document. Dans un SaaS multi-tenant où la plateforme génère des PDF au nom de ses clients, author devrait être le nom de l’organisation du client, pas celui de la plateforme. (Le nom de la plateforme appartient à creator — voir ci-dessous.) Pour les contextes conseil / publication / juridique où les individus sont la marque, des individus conviennent très bien.

subject — quel type de document c’est

subject est la courte description du document. Les visionneuses ne le mettent pas en évidence — la plupart des utilisateurs ne le verront jamais à moins d’ouvrir la fenêtre Propriétés. Mais les systèmes de gestion documentaire, les systèmes d’archivage et le routage e-mail/fichier par règles s’en servent.

Où il apparaît :

  • Fenêtre Propriétés, en position secondaire.
  • Règles de routage DMS, logique de regroupement en archive.
  • Flux de métadonnées XMP (PDF/A).

Erreurs courantes :

  • "subject": "Invoice for Acme on 2026-03-18 for $4,532.10" — c’est une description d’instance de document, pas d’un type. Cela appartient à title.
  • ❌ Vide — vous renoncez à un point d’accroche gratuit pour le routage en aval.
  • ❌ Mélanger les classes de façon incohérente ("Invoice" vs "Invoice/2026-03" vs "Monthly invoice") — les filtres DMS ne peuvent pas regrouper une cible mouvante.

Formes qui fonctionnent :

  • "subject": "Invoice"
  • "subject": "Monthly account statement"
  • "subject": "Étiquette d'expédition — thermique 4×6"
  • "subject": "Dossier conseil d'administration T3 2026"

Règle empirique : la bonne granularité est la classe de document, pas l’instance de document. Un DMS qui reçoit des milliers de PDF peut router sur subject si vous lui donnez un vocabulaire cohérent. Choisissez un ensemble fini de classes pour votre plateforme et ne déviez jamais — chaque facture que votre plateforme génère doit avoir exactement "subject": "Invoice".

creator vs producer — la paire la plus confondue

C’est là que la plupart des équipes arrêtent de lire la spécification PDF et improvisent. La spécification est précise ; les deux champs ne signifient pas la même chose.

  • creator — l’application qui a produit le contenu source (le système amont qui a décidé ce que le document devait dire).
  • producer — l’application qui a produit les octets du PDF (le moteur de rendu qui a transformé ce contenu en fichier PDF).

Pour une plateforme SaaS de facturation générant des factures via une API JSON-to-PDF comme gPdf :

  • creator = la plateforme SaaS de facturation avec sa version. C’est elle qui a décidé que ce devait être une facture pour Acme à 4 532,10 USD.
  • producer = le moteur de rendu. Par défaut, c’est « gPdf ». Mais comme la couche de rendu est une infrastructure que le SaaS a choisie, le SaaS peut légitimement mettre dans producer le nom de sa propre plateforme — sa plateforme a, en un sens réel, produit les octets du PDF en déléguant à gPdf comme infrastructure.
{
  "creator":  "Acme Billing Platform v7.2",
  "producer": "Acme Billing Platform"
}

Où ils apparaissent :

  • Fenêtre Propriétés, tous deux libellés.
  • Sortie de pdfinfo, l’un à côté de l’autre.
  • Flux XMP PDF/A (les deux champs doivent être non vides en PDF/A).

Erreurs courantes :

  • creator défini sur une chaîne user-agent Chromium / Mozilla. Arrive quand une pile PDF basée sur un navigateur headless passe le User-Agent dans creator automatiquement. C’est la version du navigateur, pas le système source de vérité. Écrasez-la.
  • producer laissé tel quel avec le nom du moteur de rendu par défaut. La plupart des équipes ne l’écrasent jamais, et chaque PDF dit donc « Skia/PDF m120 » ou « wkhtmltopdf » — voir le billet sur la marque blanche pour savoir pourquoi cela compte en B2B.
  • Mettre la même valeur dans les deux. Acceptable mais gaspilleur — les deux champs existent précisément pour qu’une visionneuse puisse distinguer « app source » et « moteur de rendu ». Utilisez-les.

Règle empirique : creator est le nom de votre application avec version (par ex. "Acme Billing Platform v7.2") ; producer est la marque ou le nom de plateforme de votre application sans version (par ex. "Acme Billing Platform"). Les deux doivent être des valeurs que le destinataire reconnaîtrait.

Champs vides, valeurs par défaut par token, surprises en aval

Trois détails d’implémentation à connaître avant de livrer :

  1. Les chaînes vides ou composées uniquement d’espaces sont traitées comme non fournies. Envoyer "title": "" revient à omettre title — cela n’écrit pas une chaîne vide dans le PDF, cela parcourt la chaîne de fallback (valeur par défaut du token → valeur par défaut du système). C’est la cause du rapport de bug « je l’ai défini, ça n’a pas pris » le plus fréquent.
  2. Les politiques de jeton peuvent supprimer ou définir par défaut les champs de métadonnées. Un SaaS multi-tenant utilisant gPdf peut définir un default_metadata sur chaque jeton API afin que chaque PDF généré par ce jeton porte le author et le producer du client sans avoir à faire confiance à chaque développeur pour les définir à chaque requête. La valeur par défaut au niveau du jeton est la bonne couche d’application pour « chaque PDF Acme doit dire Acme ».
  3. Les chaînes en aval peuvent réécrire vos métadonnées. Les outils qui post-traitent les PDF après le retour de gPdf — Ghostscript sans indicateurs explicites de préservation des métadonnées, certains outils DRM d’entreprise, certains « optimiseurs PDF » — peuvent écraser Producer avec leur propre nom et annuler l’attribution de marque que vous venez de définir. Vérifiez sur votre vraie chaîne de production, pas seulement sur la réponse brute de gPdf.

Vérifier vos métadonnées

Après avoir implémenté les changements ci-dessus, trois moyens rapides de contrôler que le PDF a bien livré ce que vous vouliez :

Ligne de commande (macOS / Linux, requiert poppler-utils) :

$ pdfinfo your-output.pdf | head -10
Title:           Invoice INV-2026-3401
Subject:         Monthly invoice 2026-03
Author:          Acme Logistics, Inc.
Creator:         Acme Billing Platform v7.2
Producer:        Acme Billing Platform
Language:        en

Acrobat / Adobe Reader : Fichier → Propriétés → onglet Description. Les six champs apparaissent, avec Title affiché dans la barre de titre de la visionneuse en haut.

Aperçu macOS : ⌘+I (Lire les informations). Le panneau d’inspecteur « PDF » affiche les mêmes champs.

Si un champ apparaît vide, blanc ou avec un nom d’outil que vous n’avez pas défini, repassez sur le corps de la requête — la cause la plus fréquente est l’envoi de "" (chaîne vide), que l’API traite comme « non fourni » et qui parcourt la chaîne de fallback jusqu’à une valeur par défaut. La deuxième cause la plus fréquente est une chaîne en aval (Ghostscript, DRM, optimiseur) qui écrase le champ après le retour de gPdf ; testez sur la production, pas seulement sur la réponse de rendu brute.

Métadonnées dans l’archivage PDF/A

Si vous effectuez le rendu pour un archivage à long terme avec settings.profile: "pdfa-2b" (ou -2a, -3a, -3b), les métadonnées cessent d’être facultatives et deviennent porteuses :

  • Le champ producer ne peut pas être vide dans un fichier conforme PDF/A — au minimum la valeur par défaut du système est livrée.
  • language est requis pour les profils d’accessibilité (PDF/A-2a, PDF/A-3a). Sans lui, la validation veraPDF échoue purement et simplement.
  • Le flux de métadonnées XMP que PDF/A exige est généré automatiquement à partir des six champs ci-dessus ; vous n’avez pas à le construire vous-même.
  • title, author, subject, creator, producer et language se retrouvent tous dans le flux XMP, de sorte que l’indexeur de métadonnées d’une archive en aval (Preservica, Archivematica) peut bâtir son catalogue à partir d’eux sans re-parser le corps du document.

Pour un document d’archive, les métadonnées attribuées à la bonne marque ne sont pas qu’une touche de finition — elles font partie de la durabilité de l’artéfact. Le bureau des douanes allemand, l’administration fiscale brésilienne, ou toute archive à long terme qui ouvrira votre PDF dans dix ans verra ce qui se trouvait dans ces champs le jour où vous l’avez rendu. Les définir délibérément au moment du rendu est la seule chance que vous avez.

Ce que gPdf n’expose pas (encore)

Pour rester honnête sur la surface actuelle : la spécification PDF définit aussi Keywords (termes de recherche en forme libre) et un flux de métadonnées XMP qui prend en charge des paires clé-valeur personnalisées arbitraires. gPdf n’expose ni l’un ni l’autre dans l’API actuelle.

Si vous devez planquer des données métier arbitraires à l’intérieur du PDF (UUID de commande, code d’entrepôt, version de modèle), les contournements aujourd’hui sont :

  • Mettre dans subject une courte chaîne structurée que les systèmes en aval analysent.
  • Conserver les données métier dans votre propre base de données, indexées sur le nom de fichier ou un hash du contenu.
  • Attendre — les champs personnalisés XMP sont sur la feuille de route, et quand ils arriveront ils seront la bonne réponse pour le contexte de traitement caché et lisible par machine.

Confondre « métadonnées de marque » (les six champs standard, disponibles maintenant) avec « métadonnées métier personnalisées » (champs personnalisés XMP, futurs) est le moyen le plus facile de sur-promettre ce qui est possible aujourd’hui. Il vaut la peine de les garder distincts dans votre propre planification.

Un exemple complet

Une plateforme SaaS de facturation (Acme Billing Platform) générant une facture pour un client allemand (Müller Versand GmbH), prête à être archivée au format PDF/A :

{
  "settings": {
    "profile": "pdfa-3b",
    "metadata": {
      "title":    "Rechnung RE-2026-0412",
      "language": "de",
      "author":   "Müller Versand GmbH",
      "subject":  "Monatsrechnung — März 2026",
      "creator":  "Acme Billing Platform v7.2",
      "producer": "Acme Billing Platform"
    }
  }
}

pdfinfo sur le PDF résultant :

$ pdfinfo invoice-2026-0412.pdf | head -10
Title:           Rechnung RE-2026-0412
Subject:         Monatsrechnung — März 2026
Author:          Müller Versand GmbH
Creator:         Acme Billing Platform v7.2
Producer:        Acme Billing Platform
Language:        de

Titre en allemand, author en tant que Müller Versand (l’entité GmbH du client, destinataire du document), creator en tant qu’Acme Billing Platform (le système éditorial qui a décidé du contenu de la page), producer en tant que marque d’Acme Billing Platform, langue étiquetée correctement pour le lecteur d’écran allemand et pour l’indexeur plein texte allemand qui plus tard reprendra cela dans le DMS de Müller. Le profil PDF/A-3b implique que cet ensemble de métadonnées est aussi sérialisé dans le flux XMP pour l’archivage à long terme.

Rien dans les propriétés du fichier ne nomme gPdf, Chromium, ou un outil que le client n’a pas choisi. Ce qui est exactement l’objectif.

La plus petite amélioration possible

Si vous appelez déjà /api/v1/pdf/render en POST et que votre appel actuel ne contient pas de settings.metadata, la plus petite amélioration tient en trois lignes ajoutées au JSON que vous envoyez déjà :

 {
   "pages": [...],
   "settings": {
+    "metadata": {
+      "author":   "Your customer's organisation",
+      "producer": "Your platform"
+    }
   }
 }

Deux champs, une nouvelle clé. Vérifiable avec pdfinfo en quelques secondes. Une fois cela en place, complétez title, language, subject et creator quand vous aurez le temps.

Où cela se traduit