papii — reference
API Documentation
Generate professional PDFs from structured data.
Base URL
https://api.papii.eu Authentication
Pass your API key in the X-API-Key header.
Get your key at /dashboard/keys
Endpoints
/render Render a document from template + data to PDF.
{
"template": "be.accounting.invoice",
"data": { ... },
"options": {
"language": "fr",
"strict": true
}
}Returns application/pdf on success.
/validate Validate data against a template schema (dry run, no rendering).
{
"template": "be.accounting.invoice",
"data": { ... }
}/packs List all installed template packs and their templates.
/health Service health check.
Error Codes
| Code | Meaning |
|---|---|
| 400 | Schema validation failed |
| 401 | Missing or invalid API key |
| 402 | payment_required: no document is left on the account (see Limits) |
| 404 | Template not found |
| 422 | LaTeX render failed |
Limites et 402 payment_required
Une requête faite avec une clé d’API compte pour un document propre lorsqu’elle réussit. Les 5 premiers documents propres du mois sur les modèles de la liste gratuite sont gratuits ; viennent ensuite les documents de votre formule, puis vos crédits.
Quand il ne reste aucun document, l’API ne produit rien. Elle répond 402 avec ce corps, sans Retry-After, et sans rien de votre requête :
{
"detail": {
"error": "payment_required",
"message": "No document allowance is left on this account; choose a plan or buy credits to continue",
"buy_url": "https://papii.eu/pricing"
}
}buy_url est la page où vous pouvez choisir une formule ou acheter des documents. Les aperçus et les rendus échoués ne sont jamais comptés. Une requête répétée avec la même Idempotency-Key n’est pas comptée deux fois.
Examples
import httpx
res = httpx.post(
"https://api.papii.eu/render",
headers={"X-API-Key": "pk-your-key"},
json={
"template": "be.accounting.invoice",
"data": {
"company": {"name": "Chut SRL", "vat": "BE0795886652"},
"client": {"name": "ACME Corp"},
"invoice": {
"number": "2026-042",
"date": "2026-03-28",
"lines": [{"description": "Consulting", "quantity": "3", "unit_price": "120.00", "vat_rate": "21"}],
"total_excl_vat": "360.00",
"total_vat": "75.60",
"total_incl_vat": "435.60"
}
},
"options": {"language": "fr"}
}
)
with open("invoice.pdf", "wb") as f:
f.write(res.content) const res = await fetch("https://api.papii.eu/render", {
method: "POST",
headers: {
"X-API-Key": "pk-your-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
template: "be.accounting.invoice",
data: { /* ... */ },
options: { language: "fr" },
}),
});
const pdf = await res.arrayBuffer();
fs.writeFileSync("invoice.pdf", Buffer.from(pdf));