Skip to content

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.

X-API-Key: pk-your-api-key

Get your key at /dashboard/keys

Endpoints

POST /render

Render a document from template + data to PDF.

{
  "template": "be.accounting.invoice",
  "data": { ... },
  "options": {
    "language": "fr",
    "strict": true
  }
}

Returns application/pdf on success.

POST /validate

Validate data against a template schema (dry run, no rendering).

{
  "template": "be.accounting.invoice",
  "data": { ... }
}
GET /packs

List all installed template packs and their templates.

GET /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

Python
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)
Node.js
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));