Webhook
La piattaforma invia notifiche HTTP POST al webhook_url configurato per il tenant a conclusione di ogni documento elaborato.
Configurare il webhook URL
L'amministratore host imposta il webhook_url nella pagina di dettaglio tenant. Se non configurato, gli eventi vengono silenziosamente ignorati — nessun errore, nessun retry.
Sicurezza
Nota MVP: i webhook non includono una firma HMAC. Non è possibile verificare criptograficamente l'autenticità della richiesta. Per sicurezza, usa un
webhook_urlnon indovinabile (con un token casuale nell'URL) e verifica il campotenant_id/tenant_slugnel payload.
Gli eventi
Nota sui nomi evento: i nomi
order.*riflettono il primo caso d'uso implementato, ma si applicano a qualsiasi tipo di documento elaborato da Parsly — fatture, bolle, contratti, ecc.
La piattaforma emette due tipi di evento:
order.processed— un documento (o tutte le parti di un multi-ordine) è stato completato ed è pronto per il sistema integrato.order.review_summary— almeno una parte richiede attenzione operatore (YELLOW o RED); riepilogo aggregato a livello di documento sorgente.
order.processed
Inviato quando un documento viene completato con successo. Il momento di invio dipende dal semaforo:
- GREEN — inviato immediatamente al termine dell'elaborazione AI
- YELLOW — inviato solo dopo che un operatore approva il documento dalla coda di revisione
Per documenti multi-ordine (PDF che contiene più ordini distinti e viene automaticamente diviso), un order.processed viene emesso per ciascuna parte, oppure un unico evento aggregato per il documento padre — dipende dal flusso interno di merge.
Campi del payload:
| Campo | Descrizione |
|---|---|
event |
"order.processed" |
timestamp |
ISO 8601 UTC del momento di invio |
tenant_id |
UUID del tenant |
tenant_slug |
Slug del tenant (es. legami) |
batch_id |
UUID del batch di ingest |
document_id |
UUID del documento elaborato |
pipeline_id |
UUID della pipeline di elaborazione |
semaphore |
green / yellow |
customer_name |
Valore del campo header customer_name estratto |
line_items_count |
Numero di righe estratte |
confidence_avg |
Media confidence (0.0–1.0) |
fields |
Oggetto con l'header canonico completo (tutti i campi non-line-items estratti) |
part_number |
Indice 1-based della parte (se PDF split). Altrimenti 1 |
total_parts |
Totale parti del PDF padre (se split). Altrimenti 1 |
parent_document_id |
UUID del documento originale se questo è una parte; altrimenti null |
{
"event": "order.processed",
"timestamp": "2026-04-10T10:00:00Z",
"tenant_id": "a1b2c3d4-...",
"tenant_slug": "legami",
"batch_id": "b-uuid-...",
"pipeline_id": "p-uuid-...",
"document_id": "d-uuid-...",
"semaphore": "green",
"customer_name": "GOTTARDO SPA",
"line_items_count": 37,
"confidence_avg": 0.912,
"fields": {
"customer_name": "GOTTARDO SPA",
"order_number_original": "OC-2026-0421",
"order_date": "2026-04-08",
"delivery_date": "2026-04-22"
},
"part_number": 1,
"total_parts": 1,
"parent_document_id": null
}
Nota: I documenti YELLOW rigettati dall'operatore non generano alcun
order.processed.
order.review_summary
Inviato una sola volta per documento sorgente quando almeno una parte richiede attenzione operatore (semaforo YELLOW o RED), dopo che tutte le parti del documento (single o multi-ordine) hanno completato il primo passaggio del cruncher. Sostituisce i precedenti eventi order.review_pending e order.quarantined.
L'invio è idempotente: il flag interno review_summary_sent_at garantisce esattamente un invio per documento padre. Non viene emesso se: il documento è stato caricato manualmente via UI (source=upload), il tenant non ha webhook_url, oppure tutte le parti sono GREEN.
Campi del payload:
| Campo | Descrizione |
|---|---|
event |
"order.review_summary" |
tenant_id |
UUID del tenant |
tenant_slug |
Slug del tenant |
parent_document_id |
UUID del documento sorgente (padre per multi-ordine, lo stesso doc per single) |
pdf_filename |
Nome del PDF originale |
total_orders |
Numero totale di ordini estratti dal PDF (1 per single, N per multi) |
green_count |
Numero di ordini con semaforo verde |
yellow_count |
Numero di ordini con semaforo giallo (richiedono review) |
red_count |
Numero di ordini con semaforo rosso (non elaborabili) |
review_url |
URL relativo della coda di review nel workspace tenant |
{
"event": "order.review_summary",
"tenant_id": "a1b2c3d4-...",
"tenant_slug": "legami",
"parent_document_id": "d-uuid-...",
"pdf_filename": "ordini_misti.pdf",
"total_orders": 5,
"green_count": 2,
"yellow_count": 2,
"red_count": 1,
"review_url": "/t/legami/review"
}
Flusso tipico per un documento con almeno una parte non-green:
- Tutte le parti completano il primo passaggio del cruncher
order.review_summaryinviato una volta sola- L'operatore apre
review_urle processa le parti YELLOW/RED dalla UI Parsly - Quando una parte viene approvata o auto-completata, il suo
order.processedviene emesso
Documenti multi-parte (split)
Quando un PDF contiene più ordini distinti e viene automaticamente diviso, ciascun ordine è una "parte" con parent_document_id valorizzato. Gli eventi sono emessi in questo modo:
order.review_summaryviene inviato una sola volta per il documento padre (aggregato su tutte le parti).order.processedviene inviato per ogni parte completata con successo (GREEN automatico o YELLOW approvato dall'operatore).- Il documento padre stesso non genera
order.processed.
Retry policy
Se il tuo endpoint risponde con un codice HTTP diverso da 2xx, la piattaforma riprova fino a 3 volte con backoff esponenziale.
Dopo 3 tentativi falliti l'evento viene scartato. Il documento è comunque persistito su Postgres — nessun dato va perso, solo la notifica.
Requisiti del tuo endpoint:
- Risponde entro 10 secondi
- Restituisce HTTP
200(o qualsiasi2xx) - È idempotente — potresti ricevere lo stesso evento più di una volta in caso di retry