SDK Node.js : générer des PDF depuis JavaScript et TypeScript
Dernière mise à jour le 20 août 2026
Nous fournissons un SDK Node.js pour se connecter à PDFMonkey. Ce package est le moyen le plus rapide d’utiliser notre API depuis JavaScript ou TypeScript.
Le SDK n’a aucune dépendance runtime, fournit des builds ESM et CommonJS, et est entièrement typé. Il ne repose que sur l’API fetch globale et Web Crypto : il fonctionne donc sur Node.js 20+, Bun, Deno et les runtimes edge comme Cloudflare Workers ou Vercel Edge Functions.
Installation #
$ npm install pdfmonkey
Ou avec le gestionnaire de paquets de votre choix :
$ pnpm add pdfmonkey
$ yarn add pdfmonkey
$ bun add pdfmonkey
Utilisation #
Configuration de l’authentification #
Utilisation de la variable d’environnement par défaut #
Le SDK recherche la variable d’environnement PDFMONKEY_API_KEY. Cette variable doit contenir votre clé API obtenue sur https://dashboard.pdfmonkey.io/account.
PDFMONKEY_API_KEY=j39ckj4…
Une fois la variable définie, vous pouvez créer un client sans argument :
import { PDFMonkey } from "pdfmonkey";
const client = new PDFMonkey();
Configuration manuelle des identifiants #
Vous pouvez aussi passer la clé API explicitement, sous forme de chaîne ou dans un objet d’options :
const client = new PDFMonkey("j39ckj4…");
// ou, avec des options supplémentaires
const client = new PDFMonkey({
apiKey: "j39ckj4…",
timeout: 30_000,
});
Identifiants par tenant #
Les identifiants sont liés à une instance de client. Si vous avez besoin d’identifiants par requête (par ex. en multi-tenant), créez un client par tenant :
const tenantClient = new PDFMonkey(tenant.pdfmonkeyApiKey);
const card = await tenantClient.documents.generateSync({
document_template_id: "b13ebd75-…",
payload: { name: "John Doe" },
});
Documents #
Génération synchrone #
Si vous souhaitez attendre la fin de la génération d’un document avant de poursuivre votre flux de travail, utilisez generateSync. Cette méthode envoie une demande de génération et attend le succès ou l’échec avant de renvoyer une DocumentCard.
const card = await client.documents.generateSync({
document_template_id: "b13ebd75-d290-409b-9cac-8f597ae3e785",
payload: { name: "John Doe" },
});
card.status; // => 'success'
card.download_url; // => 'https://…'
La requête expire après 2 minutes par défaut. Vous pouvez modifier ce délai avec l’option timeout :
const card = await client.documents.generateSync(
{ document_template_id: "…", payload: { name: "John Doe" } },
{ timeout: 300_000 },
);
L’URL de téléchargement est temporaire
L’URL de téléchargement d’un document n’est valide que pendant 1 heure. Passé ce délai, récupérez à nouveau la carte du document pour en obtenir une nouvelle :
const fresh = await client.documentCards.get(card.id);
fresh.download_url; // => nouvelle URL, valide 1 heure
Génération asynchrone #
PDFMonkey a été conçu avec un flux de travail asynchrone en tête. Il fournit des webhooks pour vous informer du succès ou de l’échec de la génération d’un document.
Pour tirer parti de ce comportement et continuer à travailler pendant la génération de votre document, créez le document avec status: 'pending' :
const document = await client.documents.create({
document_template_id: "b13ebd75-d290-409b-9cac-8f597ae3e785",
payload: { name: "John Doe" },
status: "pending",
});
document.status; // => 'pending'
document.download_url; // => null
Si vous avez configuré une URL de webhook, elle sera appelée avec votre document une fois la génération terminée. Consultez la page Webhooks pour le format du payload et la vérification de signature.
Si vous préférez interroger l’API plutôt que d’utiliser des webhooks, waitForGeneration interroge l’API jusqu’à ce que le document atteigne un statut final :
const completed = await client.documents.waitForGeneration(document.id, {
interval: 2000, // intervalle initial en ms (défaut : 2000)
maxInterval: 10_000, // plafond du backoff exponentiel (défaut : 10 000)
timeout: 120_000, // abandon après ce délai en ms (défaut : 120 000)
signal: AbortSignal.timeout(60_000), // AbortSignal optionnel
});
completed.status; // => 'success'
completed.download_url; // => 'https://…'
Cette méthode lève une PDFMonkeyError si le document termine en failure ou error, ou si le délai est dépassé.
Documents brouillons #
Vous pouvez créer un document brouillon qui ne sera pas mis en file d’attente pour la génération. C’est le comportement par défaut quand status est omis.
preview_url avant de déclencher la génération. C’est ce que nous faisons dans le tableau de bord PDFMonkey pour vous montrer un aperçu de votre document avant de le générer, en utilisant une iframe.const draft = await client.documents.create({
document_template_id: "b13ebd75-d290-409b-9cac-8f597ae3e785",
payload: { name: "John Doe" },
});
draft.status; // => 'draft'
draft.preview_url; // => 'https://…'
// Quand vous êtes prêt, déclenchez la génération :
const pending = await client.documents.update(draft.id, { status: "pending" });
pending.status; // => 'pending'
// Puis attendez la fin :
const completed = await client.documents.waitForGeneration(draft.id);
completed.status; // => 'success'
Joindre des métadonnées #
En plus du payload du document, vous pouvez ajouter des métadonnées lors de la génération. Passez la propriété meta à generateSync, create ou update. Elle accepte un objet ou une chaîne JSON déjà sérialisée :
const card = await client.documents.generateSync({
document_template_id: templateId,
payload: payload,
meta: {
_filename: "john-doe-contract.pdf", // définit le nom du fichier téléchargé
_password: "secret123", // chiffre le PDF (AES-256)
client_id: "123xxx123", // vos propres métadonnées
},
});
card.meta;
// => '{"_filename":"john-doe-contract.pdf","_password":"secret123","client_id":"123xxx123"}'
Consultez Nom de fichier personnalisé et Protection par mot de passe pour le détail des clés _filename et _password.
L’API renvoie meta sous forme de chaîne JSON. Utilisez parseMeta pour retrouver l’objet structuré que vous avez envoyé :
import { parseMeta } from "pdfmonkey";
const meta = parseMeta(card.meta); // DocumentMeta | null
meta?._filename; // => 'john-doe-contract.pdf'
meta?.client_id; // => '123xxx123'
Génération d’images #
La génération d’images suit le même flux API que la génération de PDF. L’attribut output_type du template indique s’il produit une sortie 'pdf' ou 'image'. Les options spécifiques aux images sont passées via la propriété meta :
const card = await client.documents.generateSync({
document_template_id: templateId,
payload: payload,
meta: {
_type: "png", // webp (défaut), png ou jpg
_width: 800, // pixels
_height: 600, // pixels
_quality: 80, // webp uniquement, défaut 100
},
});
card.download_url; // => URL vers l’image générée
Télécharger le fichier #
Plutôt que de récupérer download_url vous-même, laissez le SDK s’en charger. Passez un document, une carte de document ou un identifiant :
// Sous forme de Uint8Array
const bytes = await client.documents.download(card);
await fs.promises.writeFile("contract.pdf", bytes);
// Sous forme de ReadableStream — à rediriger directement vers le disque ou une réponse HTTP
const stream = await client.documents.downloadStream(card.id);
Ces deux méthodes lèvent une PDFMonkeyError si le document n’a pas encore de download_url : attendez d’abord la fin de la génération.
Mettre à jour un document #
const updated = await client.documents.update(document.id, {
payload: { name: "Jane Doe" },
status: "pending",
});
Lister les documents #
Le listage renvoie des cartes de documents allégées, il se trouve donc sur client.documentCards :
const page = await client.documentCards.list({ page: 1, status: "success" });
for (const card of page.data) {
console.log(card.id, card.status);
}
page.currentPage; // => 1
page.totalPages; // => 5
// Naviguer entre les pages
if (page.hasNextPage()) {
const next = await page.getNextPage();
}
Vous pouvez filtrer par document_template_id, status, workspace_id et updated_since.
Récupérer un document #
Préférez `documentCards.get` à `documents.get`
client.documentCards.get sauf si vous avez une raison spécifique de récupérer le document complet.Pour récupérer uniquement la représentation légère (recommandé) :
const card = await client.documentCards.get(
"76bebeb9-9eb1-481a-bc3c-faf43dc3ac81",
);
Pour récupérer le document complet, payload inclus :
const document = await client.documents.get(
"76bebeb9-9eb1-481a-bc3c-faf43dc3ac81",
);
Supprimer un document #
await client.documents.delete("76bebeb9-9eb1-481a-bc3c-faf43dc3ac81");
Gestion des erreurs #
Les erreurs API et les erreurs réseau lèvent des exceptions typées :
import {
APIConnectionError,
APIError,
AuthenticationError,
NotFoundError,
RateLimitError,
UnprocessableEntityError,
} from "pdfmonkey";
try {
await client.documents.create({
document_template_id: templateId,
payload: data,
});
} catch (error) {
if (error instanceof AuthenticationError) {
// Clé API invalide (401)
} else if (error instanceof NotFoundError) {
// Ressource introuvable (404)
} else if (error instanceof UnprocessableEntityError) {
error.body; // => { errors: { document_template_id: ["can't be blank"] } }
} else if (error instanceof RateLimitError) {
error.retryAfter; // => secondes à attendre, issues de l’en-tête Retry-After
} else if (error instanceof APIError) {
error.status; // => tout autre statut HTTP d’erreur
} else if (error instanceof APIConnectionError) {
error.cause; // => erreur réseau d’origine
}
}
Toutes les classes d’exception héritent de PDFMonkeyError, ce qui permet de les intercepter de manière générale :
import { PDFMonkeyError } from "pdfmonkey";
try {
await client.documents.generateSync({
document_template_id: templateId,
payload: data,
});
} catch (error) {
if (error instanceof PDFMonkeyError) {
console.error(`Une erreur est survenue : ${error.message}`);
}
}
Le client réessaie automatiquement les requêtes qui échouent avec un statut 408, 429 ou 5xx (2 tentatives par défaut, avec backoff exponentiel respectant l’en-tête Retry-After). Consultez la section Configuration pour ajuster ce comportement.
Templates #
Récupérer un template #
Les templates complets peuvent être volumineux
list quand vous n’avez besoin que des métadonnées.const template = await client.documentTemplates.get(
"b13ebd75-d290-409b-9cac-8f597ae3e785",
);
template.identifier; // => 'my-invoice'
template.body; // => '<h1>Invoice</h1>…' (version publiée)
template.body_draft; // => '<h1>Invoice v2</h1>…' (version brouillon)
Créer un template #
Lors de la création d’un template, écrivez dans les champs brouillons (body_draft, scss_style_draft, sample_data_draft, settings_draft) :
const template = await client.documentTemplates.create({
identifier: "my-invoice",
body_draft: "<h1>Invoice</h1>",
});
template.body_draft; // => '<h1>Invoice</h1>'
Ne renseignez pas pdf_engine_draft_id : l’API sélectionne automatiquement le moteur le plus récent. Consultez la section Moteurs si vous devez figer une version précise.
Mettre à jour un template #
Comme create, update écrit dans les champs brouillons :
const updated = await client.documentTemplates.update(template.id, {
body_draft: "<h1>Updated Invoice</h1>",
});
updated.body_draft; // => '<h1>Updated Invoice</h1>'
Lister les templates #
const page = await client.documentTemplates.list({
workspace_id: "f4ab650c-…",
});
Supprimer un template #
await client.documentTemplates.delete("b13ebd75-…");
Template Folders #
// Lister les dossiers
const folders = await client.templateFolders.list();
// Créer un dossier
const folder = await client.templateFolders.create({ identifier: "invoices" });
// Récupérer un dossier
const folder = await client.templateFolders.get("folder-id");
// Mettre à jour un dossier
await client.templateFolders.update("folder-id", { identifier: "receipts" });
// Supprimer un dossier
await client.templateFolders.delete("folder-id");
Pour créer un template dans un dossier spécifique, passez le template_folder_id :
const folder = await client.templateFolders.create({ identifier: "invoices" });
const template = await client.documentTemplates.create({
identifier: "monthly-invoice",
body_draft: "<h1>Invoice</h1>",
template_folder_id: folder.id,
});
Snippets #
Les snippets sont des composants HTML réutilisables qui peuvent être inclus dans les templates.
// Lister les snippets
const snippets = await client.snippets.list();
// Créer un snippet
const snippet = await client.snippets.create({
identifier: "header",
code: '<div class="header">…</div>',
workspace_id: "f4ab650c-…",
});
// Récupérer un snippet
const snippet = await client.snippets.get("snippet-id");
// Mettre à jour un snippet
await client.snippets.update("snippet-id", {
code: '<div class="header">Updated</div>',
});
// Supprimer un snippet
await client.snippets.delete("snippet-id");
Workspaces #
Les workspaces sont des ressources en lecture seule. Ils peuvent être listés et récupérés, mais pas créés, mis à jour ou supprimés via l’API.
// Lister les workspaces
const page = await client.workspaces.list();
for (const workspace of page.data) {
console.log(workspace.identifier);
}
// Récupérer un workspace
const workspace = await client.workspaces.get("workspace-id");
workspace.identifier; // => 'my-app'
Moteurs #
Lister les moteurs de rendu PDF disponibles :
const engines = await client.pdfEngines.list();
for (const engine of engines) {
console.log(
`${engine.name} v${engine.version} (déprécié : ${engine.deprecated_on ?? "non"})`,
);
}
La plupart des intégrations n’en ont pas besoin : l’API choisit le moteur le plus récent pour les nouveaux templates. Utilisez-le uniquement pour figer un template sur une version précise :
const engines = await client.pdfEngines.list();
const chromium = engines.find((engine) => engine.name === "chromium");
await client.documentTemplates.update(template.id, {
pdf_engine_draft_id: chromium.id,
});
Utilisateur courant #
Récupérer les informations de l’utilisateur authentifié :
const user = await client.currentUser.get();
user.email; // => 'user@example.com'
user.current_plan; // => 'pro'
user.available_documents; // => 1000
Pagination #
Toutes les méthodes de liste renvoient un objet Page<T> avec une navigation intégrée :
const page = await client.documentCards.list({ page: 1 });
page.data; // => éléments de cette page
page.currentPage; // => 1
page.totalPages; // => 5
// Naviguer vers la page suivante/précédente
if (page.hasNextPage()) {
const next = await page.getNextPage();
}
if (page.hasPreviousPage()) {
const prev = await page.getPreviousPage();
}
// Aller à une page précise
const last = await page.getPage(page.totalPages);
page.data ne contient que les éléments de la page courante. Pour traiter toutes les pages, naviguez manuellement :let page = await client.documentTemplates.list();
while (true) {
for (const template of page.data) {
process(template);
}
if (!page.hasNextPage()) break;
page = await page.getNextPage();
}
Configuration #
Toutes les options sont facultatives. Passez-les au constructeur :
const client = new PDFMonkey({
apiKey: "j39ckj4…", // ou définissez PDFMONKEY_API_KEY dans l’environnement
baseURL: "https://api.pdfmonkey.io/api/v1", // défaut
timeout: 30_000, // délai d’expiration des requêtes en ms (défaut : 30 s)
maxRetries: 2, // nouvelles tentatives sur 408/429/5xx (défaut : 2)
fetch: customFetch, // fournissez votre propre implémentation de fetch
logger: console, // journalisation de débogage
defaultHeaders: { "X-Source": "my-app" }, // envoyés avec chaque requête
retryDelay: (attempt) => attempt * 250, // stratégie de backoff personnalisée
hooks: {
// intercepteurs de requête/réponse/erreur
onRequest: (ctx) => {
ctx.headers["X-Trace-Id"] = newTraceId();
},
onResponse: (ctx) => metrics.observe(ctx.durationMs, ctx.response.status),
},
});
Options par requête #
Chaque méthode de ressource accepte un objet d’options en dernier argument pour surcharger signal, timeout et maxRetries le temps d’un appel :
await client.documents.create(
{ document_template_id: "b13ebd75-…", payload: { invoice: 1 } },
{
signal: AbortSignal.timeout(10_000),
timeout: 60_000,
maxRetries: 0,
},
);
Questions fréquentes
- Comment installer le SDK Node.js PDFMonkey ?
- Exécutez npm install pdfmonkey (ou l’équivalent avec pnpm, yarn ou bun). Définissez votre clé API via la variable d’environnement PDFMONKEY_API_KEY ou passez-la au constructeur PDFMonkey. Le package n’a aucune dépendance runtime et fournit des builds ESM et CommonJS.
- Quelle est la différence entre generateSync et create dans le SDK Node.js PDFMonkey ?
- generateSync envoie une seule requête et attend la fin de la génération du document, puis renvoie une DocumentCard avec une URL de téléchargement. create renvoie immédiatement : avec le statut pending, la génération est mise en file d’attente et vous gérez le résultat via des webhooks ou waitForGeneration ; avec le statut draft (par défaut), rien n’est généré tant que vous ne mettez pas à jour le statut.
- Peut-on utiliser le SDK Node.js PDFMonkey dans des runtimes edge comme Cloudflare Workers ou Vercel Edge ?
- Oui. Le SDK ne repose que sur l’API fetch globale et Web Crypto, il fonctionne donc sur Node.js 20+, Bun, Deno, Cloudflare Workers et Vercel Edge Functions. Vous pouvez fournir une implémentation fetch personnalisée si votre runtime en a besoin.
- Comment gérer les erreurs dans le SDK Node.js PDFMonkey ?
- Les erreurs API lèvent des sous-classes typées d’APIError comme AuthenticationError (401), NotFoundError (404), UnprocessableEntityError (422) et RateLimitError (429, avec une propriété retryAfter). Les échecs réseau lèvent APIConnectionError. Toutes les erreurs héritent de PDFMonkeyError pour une interception globale.