Autenticazione
Tutte le richieste si autenticano con una API key Bearer. Le chiavi sono scoperate a una singola organizzazione, non mostrate in chiaro dopo la creazione, e possono essere ruotate o revocate senza toccare il codice — la prima richiesta con la chiave vecchia restituisce 401.
I token iniziano con `pdf_live_…` (produzione) o `pdf_test_…` (sandbox).
Authorization: Bearer pdf_live_X8s3...e2Qa
- ›Solo lato server — mai includere una API key in un bundle browser o in un binario mobile.
- ›Il timestamp `last_used` è aggiornato a ogni richiesta, visibile in dashboard.
- ›Revoca da `Settings → API keys`; effetto sulla richiesta successiva.
Templates
Templates — il PDF che il motore compila
Un template è il tuo PDF sorgente più le label (rettangoli nominati con coordinate) che indicano dove disegnare i valori. Le label vengono create manualmente via editor visuale o via endpoint bulk-upsert `/labels/` — non vengono auto-rilevate.
GET /templates/
Elenca tutti i template della tua organizzazione.
Paginati, ordinati per data. Supporta `?search=` per match fuzzy sul nome.
POST /templates/ multipart/form-data
Carica un nuovo PDF come template.
Fields
-
name string · obbligatorio Nome mostrato in dashboard. -
description string · opzionale Nota interna per il tuo team. -
file file · obbligatorio File PDF, fino a 25 MB.
Le anteprime per pagina girano in background. `previews_ready` passa a `true` quando è sicuro renderizzare.
GET /templates/{id}/
Recupera un template con le sue label e le anteprime per pagina.
DELETE /templates/{id}/
Elimina il template e gli artefatti S3.
Compilations
Compilations — un singolo PDF renderizzato
Invii una mappa di valori per un template, ottieni una risorsa `compilation`. Il rendering è asincrono: la risposta è immediata, il PDF arriva su S3 ed è esposto via `download_url` a breve scadenza quando lo status passa a `done`.
POST /compilations/ application/json
Crea una compilazione singola.
Fields
-
template uuid · obbligatorio Template da renderizzare. -
name string · opzionale Nome leggibile. -
values object · obbligatorio Mappa `label_name → valore`. Accetta stringhe, numeri, booleani e null — coercion server-side per tipo di campo.
Request body
{
"template": "3f0e4b2a-21c2-4d34-9c8d-9b0a5d6b3f11",
"values": {
"nome_completo": "Giulia Rossi",
"data_efficacia": "2026-06-01",
"accetta_condizioni": true
}
}
Response
HTTP/1.1 201 Created
{
"id": "c2a1...e9",
"status": "pending",
"download_url": null,
"created_at": "2026-05-27T10:13:51Z"
}
Ciclo di vita status: `pending → running → done | failed`. `download_url` è una URL S3 pre-firmata valida 5 minuti.
GET /compilations/{id}/
Polling su una compilazione, oppure recupero del `download_url` quando `status == done`.
PATCH /compilations/{id}/
Ri-renderizza con nuovi valori, o rinomina la compilazione.
Inviare `values` triggera un re-render e consuma una unità di quota. Inviare solo `name` è una modifica metadata gratuita.
DELETE /compilations/{id}/
Elimina la compilazione e il PDF renderizzato da S3.
Batches
Batches — migliaia di PDF in una sola chiamata
Due entry point: `/batches/json/` per uso programmatico, `/batches/upload/` per CSV/XLSX. Entrambi fanno streaming delle righe su un worker pool parallelo e producono un singolo `result.zip` al completamento.
POST /batches/json/ application/json
Invia fino a 5 000 righe di valori inline.
Fields
-
template uuid · obbligatorio Template di riferimento. -
rows array · obbligatorio 1–5000 oggetti riga. -
completion_webhook_endpoint uuid · opzionale Endpoint salvato da notificare al completamento. -
completion_webhook_url url · opzionale URL webhook inline one-shot.
Response
HTTP/1.1 202 Accepted
{
"id": "b1f2...77",
"source": "json",
"status": "pending",
"total": 0,
"expected_total": 2,
"succeeded": 0,
"failed": 0
}
Precedenza webhook: endpoint salvato → URL inline → endpoint di default dell'org. Senza configurazione, il batch parte comunque senza notifica.
POST /batches/upload/ multipart/form-data
Invia un file CSV o XLSX (fino a 20 MB).
Fields
-
template uuid · obbligatorio Template di riferimento. -
file file · obbligatorio .csv o .xlsx, ≤ 20 MB. -
column_mapping object · opzionale Mappa JSON colonna CSV → label name.
GET /batches/{id}/
Polling sull'avanzamento. `succeeded + failed` raggiungono `expected_total` a fine run; `download_url` diventa non-nullo in quel momento.
Share requests
Share requests — fai compilare al destinatario
Genera una URL protetta da token che punta a un form di compilazione hostato. Il destinatario apre il link da qualsiasi dispositivo, opzionalmente verifica l'email via OTP, compila e invia.
POST /share-requests/
Crea una share request singola.
Fields
-
template uuid · obbligatorio Template da esporre. -
recipient_email email · opzionale Se valorizzato, consegniamo il link via email. -
verify_email bool · default false Blocca il submit dietro a una challenge OTP via email. -
send_copy_to_recipient bool · default false Auto-CC del PDF finale al destinatario al submit. -
notify_sender_on_complete bool · default false Ti mandiamo una email quando il destinatario invia. -
prefill_values object · opzionale Valori che già conosci. -
expires_in_days int 1–90 · default 7 Durata del link.
POST /share-requests/batches/
Crea share request in bulk da una lista di destinatari.
Fields
-
template uuid · obbligatorio Template condiviso. -
expires_in_days int · default 7 Applicato a ogni link del batch. -
requests array · obbligatorio Lista di righe destinatario.
Webhooks
Webhooks — eventi consegnati al tuo endpoint
Configura un endpoint HTTPS che DataPDFEngine firma con HMAC-SHA256. Ogni payload include il nome dell'evento, l'ID risorsa e un timestamp stabile, così puoi costruire handler idempotenti.
Verifica firma (HMAC-SHA256)
Ogni richiesta in uscita porta tre header. Verifica la firma prima di fidarti del payload — e calcola sempre l'HMAC sul body grezzo della richiesta, prima di qualsiasi parsing JSON.
-
X-DataPdfEngine-Event Nome dell'evento, es. `batch.completed`. -
X-DataPdfEngine-Signature `sha256=<hex>` — HMAC del body grezzo con il secret del tuo endpoint. -
X-DataPdfEngine-Timestamp Tempo server ISO-8601; rifiuta richieste più vecchie di ~5 minuti per difendersi dal replay.
import crypto from "node:crypto";
export function verifyDataPdfEngineSignature(rawBody, headers, secret) {
const sig = headers["x-datapdfengine-signature"];
const ts = headers["x-datapdfengine-timestamp"];
if (!sig || !ts) return false;
if (Math.abs(Date.now() - Date.parse(ts)) > 5 * 60_000) return false;
const [scheme, hex] = sig.split("=");
if (scheme !== "sha256" || !hex) return false;
const expected = crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
const a = Buffer.from(hex, "hex");
const b = Buffer.from(expected, "hex");
return a.length === b.length && crypto.timingSafeEqual(a, b);
}
POST /webhooks/endpoints/
Registra un nuovo endpoint. La risposta include il `secret` una sola volta — conservalo.
POST /webhooks/endpoints/{id}/test/
Spara un `test.ping` in modo sincrono e cattura la risposta nel log delle delivery.
GET /webhooks/deliveries/
Ispeziona le delivery recenti: status code, numero tentativi, response body.
Events
-
batch.completed Batch arrivato a stato terminale. Payload: `{ event, batch_id, status, total, succeeded, failed, download_url? }`. -
test.ping Inviato in modo sincrono dalla dashboard quando clicchi 'Send test'. Usalo per validare la verifica della firma e la raggiungibilità TLS prima del go-live.
Modello di errore
Gli errori arrivano sempre come JSON con un `code` stabile e un `detail` leggibile. Lo status HTTP segue le convenzioni REST.
| HTTP | Code | Detail |
| 400 | invalid | Payload non valido. `detail` elenca i campi incriminati. |
| 401 | auth_failed | API key mancante, malformata o revocata. |
| 402 | quota_exceeded | Quota del piano esaurita per questa feature e overage disabilitato. |
| 403 | feature_locked | Il tuo piano non include questa feature. |
| 404 | not_found | Risorsa inesistente, o appartiene a un'altra organization. |
| 422 | render_failed | Il motore PDF non è riuscito a renderizzare i valori. |
| 429 | rate_limited | Hai colpito il rate cap per org. Suggerimento di backoff in `Retry-After`. |
| 502 | delivery_failed | Il target webhook ha risposto con uno status non-2xx. Controlla il delivery log. |