Démarrer
Créez votre compte, puis une clé dans l'application (« Documents générés » → « Clés d'API »). Passez-la dans l'en-tête Authorization de chaque requête :
Authorization: Bearer pdfr_…
La clé n'est affichée qu'à sa création. Gardez-la côté serveur : elle donne accès à tous les documents de l'espace. Une clé compromise se révoque depuis l'application, sans toucher aux autres.
Modèles
Un modèle est un composant Vue : du HTML, du CSS, et les données de la requête reçues en props. On l'écrit dans l'éditeur de l'application, avec un aperçu en direct. Son identifiant est affiché sous « Informations API ».
<template>
<div class="page">
<h1>Facture n° {{ numero }}</h1>
<p>Client : {{ client }}</p>
<table>
<tr v-for="ligne in lignes" :key="ligne.libelle">
<td>{{ ligne.libelle }}</td>
<td class="montant">{{ ligne.montant }} €</td>
</tr>
</table>
</div>
</template>
<script>
export default {
props: ['numero', 'client', 'lignes']
}
</script>Générer un document
POST /documents/sync répond une fois le PDF prêt, avec un downloadUrl utilisable sans clé pendant une heure.
curl https://api.pdf-realm.io/documents/sync \
-H "Authorization: Bearer $PDF_REALM_KEY" \
-H "Content-Type: application/json" \
-d '{
"template": "facture",
"data": {
"numero": 42,
"client": "Dupont SARL",
"lignes": [{ "libelle": "Conseil", "montant": 1200 }]
},
"filename": "facture-42.pdf"
}'template | Identifiant du modèle (requis, sauf avec pageUrl). |
|---|---|
pageUrl | Ou bien : une page web publique à imprimer telle quelle. |
data | Objet JSON transmis au modèle. |
filename | Nom du fichier PDF ; par défaut document-<id>.pdf. |
meta | Objet JSON libre (4 Ko max), renvoyé tel quel avec le document. |
webhookUrl | Webhook propre à ce document ; sinon celui de l'espace. |
pdfOptions | format, landscape, margin, scale, printBackground, pageRanges, headerTemplate, footerTemplate… |
Mode asynchrone
Pour une application, préférez POST /documents : la réponse 202 arrive immédiatement et le PDF est généré dès que vient son tour. Récupérez-le par webhook, ou en interrogeant GET /documents/<id> jusqu'au statut success.
curl https://api.pdf-realm.io/documents \
-H "Authorization: Bearer $PDF_REALM_KEY" \
-H "Content-Type: application/json" \
-d '{
"template": "facture",
"data": { "numero": 42 },
"webhookUrl": "https://exemple.fr/webhooks/pdf-realm"
}'
# 202 Accepted
# { "id": "093e3ec6-…", "status": "pending", "downloadUrl": null, … }Imprimer une page web
Sans modèle, pageUrl imprime une page publique telle quelle. Les adresses privées (localhost, réseaux internes) sont refusées.
curl https://api.pdf-realm.io/documents/sync \
-H "Authorization: Bearer $PDF_REALM_KEY" \
-H "Content-Type: application/json" \
-d '{
"pageUrl": "https://exemple.fr/rapport/2026-10",
"pdfOptions": { "format": "A4", "landscape": true }
}'Webhooks
À la fin de chaque document, PDF Realm envoie un POST au webhook du document, ou à défaut à celui de l'espace. event vaut document.generated ou document.failed. Répondez par un code 2xx dans les 10 secondes ; sinon l'appel est réessayé après 1, 5 puis 30 minutes.
{
"event": "document.generated",
"document": {
"id": "093e3ec6-5e80-4865-bf20-54ab72e2b39d",
"status": "success",
"filename": "facture-42.pdf",
"meta": { "facture": 42 },
"downloadUrl": "https://api.pdf-realm.io/documents/093e…/pdf?…"
}
}Chaque appel est signé : vérifiez l'en-tête X-Pdf-Realm-Signature avec le secret de webhook de l'espace (whsec_…).
import crypto from 'node:crypto'
// En-tête X-Pdf-Realm-Signature: t=1793455563,v1=5f2b…
function signatureValide(entete, corpsBrut, secret) {
const { t, v1 } = Object.fromEntries(entete.split(',').map(p => p.split('=')))
if (Math.abs(Date.now() / 1000 - Number(t)) > 300) return false
const attendue = crypto.createHmac('sha256', secret).update(`${t}.${corpsBrut}`).digest('hex')
return attendue.length === v1.length && crypto.timingSafeEqual(Buffer.from(attendue), Buffer.from(v1))
}Quotas
Chaque offre inclut un nombre de documents par mois civil (UTC). Seuls les PDF réussis comptent. Quota atteint, la création est refusée en 402 jusqu'au 1er du mois suivant. La consommation en cours est donnée par GET /space/usage. Voir les offres.
Erreurs
Une requête refusée renvoie un code 4xx et un message en texte.
400 | Saisie invalide (le message indique quel champ). |
|---|---|
401 | Clé d'API absente, inconnue ou révoquée. |
402 | Quota mensuel atteint. |
404 | Modèle ou document introuvable dans votre espace. |
409 | Opération impossible dans l'état du document. |