docs

Airpdf — API Reference

API pubblica per la generazione di PDF a partire da template.

Machine-readable spec: openapi.yaml (OpenAPI 3.1) · Postman: postman.json (one-click import)

  • Base URL: https://api.airpdf.io/api/v1
  • Auth: header Authorization: Bearer airpdf_live_xxxxxxxxxxxxx
  • Content-Type: application/json

Le API key sono emesse dal pannello tenant (sezione “API Keys”). Il prefisso airpdf_live_ indica chiavi produzione, airpdf_test_ chiavi sandbox (facoltativo).


POST /api/v1/render

Richiede la generazione di un PDF. Supporta due modalità:

  • sync: response body contiene direttamente il PDF (application/pdf). Consigliata per payload piccoli e tempi di rendering brevi.
  • async: restituisce un render_id; il PDF viene caricato su storage S3-compatibile e recuperato via GET /api/v1/render/:id.

Request body

{
  "template": "invoice-v2",
  "data": {
    "customer": { "name": "Acme Srl", "vat": "IT01234567890" },
    "items": [{ "sku": "SKU-1", "qty": 2, "price": 19.9 }]
  },
  "mode": "sync",
  "options": {
    "page_size": "A4",
    "orientation": "portrait"
  }
}
Campo Tipo Descrizione
template string Codice del template (snake/kebab). Richiesto.
data object Payload conforme al variables_schema del template. Richiesto.
engine string "react_pdf" (default) o "html". Override del template engine. HTML richiede plan.html_engine_enabled = true. Vedi sezione Render engines.
mode string "sync" (default) oppure "async".
options object Override runtime: page_size, orientation, margin, filename.

Render engines

Airpdf supporta due pipeline di rendering, selezionabili per template o overridable per request:

Engine Quando usarlo Latency tipica Quota cost (multiplier)
react_pdf (default) API ad alto volume, layout standard 100-500 ms 1×
html Brand-perfect HTML+CSS, web fonts, CSS Grid/Flex 1-3 s plan.html_engine_render_multiplier (typical 25×)

Il template carica il default engine via template.engine. Aggiungendo "engine": "html" nella request override quello del template (utile per A/B test o migrazione). L’engine HTML richiede:

  • plan.html_engine_enabled = true (altrimenti 402 payment_required)
  • template.html_template non vuoto

Quota: 1 render react_pdf = 1 unità contro render_limit_monthly. 1 render html = plan.html_engine_render_multiplier unità (default 1, tipicamente 25 per piani enterprise).

Rate limit HTML è un bucket separato da rate_limit_per_minute: plan.html_rate_limit_per_minute (default 10/min). Esaurito → 429 html_rate_limit_exceeded.

Per dettagli su template HTML, Mustache placeholders, opzioni PDF (headers/footers, margin, page size), e modello di sicurezza, vedi HTML render engine.

Response — mode: sync

200 OK con body binario application/pdf e header:

X-Airpdf-Render-Id: 01JHZ...
X-Airpdf-Render-Ms: 820

Response — mode: async

202 Accepted:

{
  "render_id": "01JHZ34567890ABCDEFG",
  "status": "queued",
  "poll_url": "/api/v1/render/01JHZ34567890ABCDEFG"
}

Esempio curl — sync

curl -sS -X POST "https://api.airpdf.io/api/v1/render" \
  -H "Authorization: Bearer airpdf_live_xxx" \
  -H "Content-Type: application/json" \
  -d @payload.json \
  -o invoice.pdf

Esempio curl — async + polling

render=$(curl -sS -X POST "https://api.airpdf.io/api/v1/render" \
  -H "Authorization: Bearer airpdf_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"template":"invoice-v2","data":{...},"mode":"async"}' | jq -r .render_id)

curl -sS "https://api.airpdf.io/api/v1/render/$render" \
  -H "Authorization: Bearer airpdf_live_xxx"

GET /api/v1/render/:id

Status di un render asincrono. Finché status != "succeeded" non c’è pdf_url.

{
  "render_id": "01JHZ34567890ABCDEFG",
  "template": "invoice-v2",
  "status": "succeeded",
  "pdf_url": "https://s3.wasabisys.com/airpdf-tenant-acme/renders/...",
  "pdf_size_bytes": 183042,
  "created_at": "2026-04-24T09:12:33Z",
  "finished_at": "2026-04-24T09:12:34Z"
}

Stati possibili: queued, running, succeeded, failed.


GET /api/v1/templates

Elenca i template pubblicati dell’account chiamante.

{
  "templates": [
    {
      "code": "invoice-v2",
      "name": "Fattura v2",
      "version": 7,
      "variables_schema": { "type": "object", "properties": {...} }
    }
  ]
}

Supporta paginazione: ?page=1&per_page=50.


Error codes

Tutte le risposte di errore hanno schema:

{ "error": { "code": "TEMPLATE_NOT_FOUND", "message": "..." } }
HTTP Code Descrizione
400 INVALID_PAYLOAD JSON mal formato o body mancante.
401 UNAUTHORIZED API key assente/invalida.
402 PAYMENT_REQUIRED Subscription non attiva o quota esaurita.
404 TEMPLATE_NOT_FOUND Template non esiste per il tenant.
422 VALIDATION_FAILED data non conforme a variables_schema.
429 RATE_LIMITED Rate limit superato (vedi header Retry-After).
500 INTERNAL_ERROR Errore rendering non recuperabile.
503 RENDER_UNAVAILABLE Nodi render temporaneamente irraggiungibili.

Rate limits

Default per API key:

  • 60 richieste / minuto sync
  • 600 richieste / minuto async
  • 10 MB per payload JSON

Header di risposta:

X-RateLimit-Limit: 60
X-RateLimit-Remaining: 58
X-RateLimit-Reset: 1714050000

Limiti custom sono configurabili per tenant dal pannello super-admin.

Spotted a typo or stale claim? Open an issue or ping us in the workspace — docs are versioned with the product.

Cookie settings

Choose what you consent to. Technical cookies are always on, because the site doesn't work without them. Details in the Cookie Policy.

TechnicalRemember your cookie choice and protect the site from abuse. Always on.Always on