Choisir une API de génération de PDF paraît simple jusqu’au moment de commencer. Il existe environ 40 fournisseurs, leurs pages marketing se ressemblent, et vous ne découvrirez les vrais compromis qu’après quelques milliers de documents en production.
Voici une checklist à utiliser pendant une évaluation fournisseur. Elle est neutre, et tirée des incidents que les équipes rencontrent réellement en achat comme en post-mortem. Huit questions : si vous n’obtenez pas une réponse claire à chacune, vous n’avez pas encore assez d’information pour choisir.
1. Quel est votre format d’entrée : HTML, JSON ou DSL de modèle ?
C’est la question la plus importante. La réponse détermine ce que votre équipe va écrire, et ce qu’elle devra déboguer à 2 h du matin.
- HTML/CSS (Puppeteer, DocRaptor, Prince) : familier, infiniment flexible, coûteux à l’exécution, difficile à rendre déterministe.
- JSON / données structurées (gPdf) : peu coûteux à rendre, identique octet pour octet, mais demande un petit mapping entre votre modèle de données et le modèle documentaire.
- DSL de modèle (PDFKit, ReportLab, Apache PDFBox) : contrôle total, responsabilité totale. Vous écrirez vous-même la pagination, la mise en page et le fallback de polices.
Il n’y a pas de mauvaise réponse en soi. Il y a une mauvaise réponse pour votre équipe. Demandez à vos ingénieurs dans quel modèle ils préfèrent corriger un bug de pagination de trois heures.
2. Quelle est la latence de démarrage à froid, et est-elle prévisible ?
Certains moteurs démarrent en microsecondes, notamment en WASM ou en binaire natif. D’autres démarrent en secondes, surtout ceux basés sur Chromium. La différence reste invisible jusqu’au premier pic de trafic.
À demander au fournisseur :
- “Quelle est votre latence p99 pour la première requête vers un worker froid ?”
- “Combien de temps après ma dernière requête un worker redevient-il froid ?”
- “Publiez-vous une page de statut avec des données de démarrage à froid ?”
S’il ne peut pas répondre à la première question avec un chiffre, partez du principe que la réponse est mauvaise.
3. Comment le coût par rendu est-il modélisé ?
Trois modèles reviennent souvent, dans l’ordre où ils finissent par vous rattraper :
- Tarification par page (Anvil à 0,10 USD/PDF, DocRaptor à 89 USD/100 000 pages) : prévisible, facile à budgéter, coûteuse à grande échelle.
- Paliers d’abonnement avec dépassement (gPdf à 5-12 USD/mois + 0,00005 USD par page supplémentaire) : peu cher à tout volume, mais plus difficile à projeter pour un usage que vous n’avez jamais testé.
- Tarification compute (Puppeteer auto-hébergé sur Lambda) : vous payez directement le compute, y compris les démarrages à froid et la mémoire Chromium.
Calculez votre VRAIE facture à trois niveaux de trafic : actuel, 5× et 50×. La forme de la courbe de coût compte davantage que le chiffre mis en avant.
4. La sortie est-elle déterministe ?
Le déterminisme, même entrée -> mêmes octets, semble théorique jusqu’au jour où vous en avez besoin.
Vous en avez besoin lorsque :
- vous comparez des PDF en CI pour détecter un changement involontaire de modèle ;
- vous conservez des documents au titre d’une facture électronique ou d’une règle fiscale, et le PDF stocké doit correspondre au PDF régénéré ;
- vous calculez un hash du PDF pour l’intégrité d’archivage ;
- vous versionnez la sortie rendue pour une revue juridique.
Les moteurs basés sur navigateur (Puppeteer, tout ce qui repose sur Chromium) ne sont PAS déterministes entre versions de patch. Les moteurs binaires natifs (Prince, gPdf) le sont généralement. Posez explicitement la question : “Mes octets de sortie changeront-ils si vous déployez une mise à jour du moteur ?”
5. Comment le moteur gère-t-il les polices, notamment CJK et RTL ?
C’est la question qui a coûté plus de carrières que n’importe quelle autre dans le monde PDF.
Le mode de panne est toujours le même : vous lancez dans votre marché domestique, les polices vont bien. Six mois plus tard, vous ouvrez un marché qui utilise une écriture dont le moteur n’a pas les glyphes. Le PDF commence à émettre des boîtes □□□□. Le client escalade. Votre équipe passe deux sprints à ajouter des polices dans un Dockerfile.
Questions à poser :
- “Quelles écritures sont intégrées sans configuration supplémentaire ? Latin, CJK, cyrillique, devanagari, arabe, hébreu ?”
- “Que se passe-t-il lorsqu’un glyphe inconnu est rencontré : fallback ou tofu ?”
- “Puis-je ajouter des polices à la requête, ou dois-je les déployer en amont ?”
- “Prenez-vous en charge le shaping du texte RTL ?”
Une bonne réponse ressemble à : “Nous intégrons NotoSans CJK et un ensemble de fallback Noto ; les glyphes inconnus retombent sur Noto Symbols.” Une mauvaise réponse ressemble à : “Oui, nous supportons les polices.”
6. Quels profils de conformité sont pris en charge ?
Si votre activité peut un jour :
- émettre des factures dans l’UE (Factur-X / ZUGFeRD / EN 16931, obligatoire en DE/FR/IT/PL d’ici 2026) ;
- archiver des documents selon des règles de rétention SOX, HIPAA ou GDPR (PDF/A) ;
- soumettre des dossiers médicaux (PDF/A-3 avec XML attaché) ;
- intégrer des signatures numériques (PAdES) ;
…demandez quels profils de conformité le moteur prend en charge nativement. La mauvaise réponse : “vous pouvez lancer un autre outil pour convertir ensuite”. C’est un pipeline multi-étapes que vous possédez désormais.
Les bonnes réponses ressemblent souvent à un seul flag. Par exemple, gPdf accepte settings.profile: "pdfa-3b" plus un bloc settings.e_invoice avec standard: "factur_x" et un XML CII intégré. Le natif demande beaucoup moins d’exploitation que le greffon ajouté après coup.
7. Le rendu est-il sans état ? Où vont mes documents après le rendu ?
Deux questions, liées.
Rendu sans état signifie que la requête arrive, que le PDF est émis, puis que rien n’est stocké. Vous gérez vous-même la persistance : S3, votre base, ou autre. C’est ce que vous voulez pour les charges soumises à de fortes contraintes de conformité, car le moteur ne devient jamais dépositaire de vos données.
Rendu avec état signifie que le fournisseur stocke le PDF, souvent sur son CDN, puis vous donne une URL signée. C’est pratique pour des flux occasionnels, par exemple “envoyer un lien au client”, mais problématique pour des flux régulés : un tiers possède désormais une copie de chaque document que vous avez rendu.
À demander :
- “Le rendu est-il sans état par défaut ?”
- “Où le document est-il stocké géographiquement si vous le stockez ?”
- “Combien de temps est-il conservé ?”
- “Puis-je obtenir une garantie écrite de rendu sans état pour la revue conformité ?”
Si la réponse reste floue, votre équipe privacy/legal en fera un sujet dans neuf mois.
8. Que se passe-t-il lorsque le moteur échoue, et comment le saurai-je ?
Tous les moteurs échouent parfois. Les questions sont :
- Comment l’échec remonte-t-il ? Un 500 avec stack trace ? Un 4xx avec erreur structurée ? Un PDF vide ?
- Quelle est la politique de retry ? Est-elle idempotente ? Les rendus échoués sont-ils facturés ?
- Quelle instrumentation le fournisseur fournit-il ? Une page de statut ? Des webhooks d’incident ? Des tableaux p50/p99 par région ?
- Existe-t-il une sonde synthétique ? Le fournisseur surveille-t-il lui-même le point d’entrée public, ou attend-il que vous ouvriez un ticket ?
Test rapide : allez sur la page de statut du fournisseur maintenant. Si elle n’existe pas, n’est pas temps réel, ou affiche “all systems operational” sans détail, c’est le niveau de transparence fiabilité que vous aurez après l’achat.
Pour référence, gPdf publie /status avec des données de sondes synthétiques et Cloudflare Analytics sur les 7 derniers jours.
Comment gPdf répond aux huit questions
Comme c’est notre blog et que vous pouvez soupçonner les questions d’être orientées, voici notre scorecard honnête :
| # | Question | Réponse gPdf |
|---|---|---|
| 1 | Format d’entrée | JSON DocumentRequest (données structurées) |
| 2 | Démarrage à froid | 5-20 ms (isolate V8, sans navigateur) |
| 3 | Modèle de coût | 0/5/8/12 USD par mois ; 0,00005 USD par page supplémentaire |
| 4 | Déterminisme | Identique octet pour octet, garanti sur la même version du moteur |
| 5 | Polices | NotoSans CJK + fallback latin intégrés |
| 6 | Conformité | PDF/A-1b/2b/3b/4 + pièce jointe Factur-X / ZUGFeRD intégrée |
| 7 | Sans état | Oui, contractuellement : aucun stockage documentaire |
| 8 | Échecs et visibilité | Page de statut publique avec tendance 7 jours ; 4xx/5xx structurés ; idempotent |
Là où nous perdons : Q1, si votre entrée est réellement du HTML que vous ne pouvez pas refactorer, par exemple des rapports générés par les utilisateurs ou des modèles hérités. Dans ce cas, DocRaptor ou Prince sont les bons choix.
TL;DR
Ne demandez pas “quelle est la meilleure API PDF”. Posez les huit questions, notez les réponses, puis choisissez le fournisseur aligné avec votre charge réelle. L’équipe qui a perdu un achat au profit d’un concurrent un peu moins cher, puis s’est fait surprendre par la question n° 5 neuf mois plus tard, vous dira la même chose.
Si votre charge correspond à la façon dont gPdf est conçu, le Playground prend 30 secondes à évaluer. Sinon, nous vous orienterons volontiers vers le bon outil : souvent DocRaptor pour les problèmes structurés comme du HTML, Prince pour l’auto-hébergement, ou Puppeteer si votre entrée est vraiment constituée de pages web arbitraires.