Skip to content

Factum Parse API

Motore di parsing documentale ibrido. Risoluzione deterministica locale in RAM (41ms / $0.00 token) con routing asimmetrico e ZDR conforme GDPR/EU.

Invia un payload documentale (XML, UBL, FacturaPA, PDF, testo grezzo) e ottieni un DocumentEnvelope v2 strutturato e validato contro schema formale:

Terminal window
curl -X POST https://api.factum.pyragogy.org/v2/parse \
-H "Authorization: Bearer YOUR_ZYLA_API_KEY" \
-H "Accept: application/json" \
-F "file=@fattura_elettronica.xml" \
-F "deterministic_only=true"

Risultato — envelope strutturato validato da Pydantic v2:

{
"job_id": "a1b2c3d4e5",
"status": "completed",
"schema_version": "2.0",
"document_type": "invoice",
"meta": {
"cost_eur": 0.0,
"confidence": 0.99,
"provider": "fast-path",
"prompt_version": ""
},
"payload": {
"kind": "invoice",
"dati_trasmissione": { "IdTrasmittente": { "IdPaese": "IT", "IdCodice": "01234567890" } },
"cedente_prestatore": { "Denominazione": "Mario Rossi S.r.l." },
"corpi": [ { "DatiGenerali": {}, "DatiBeniServizi": {} } ]
}
}

XML deterministico Nessun token LLM consumato. 41ms roundtrip misurati.


Tempi di risposta misurati su produzione (Hetzner eu-central, Coolify). Test suite: 284 passati / 6 skipped, coverage 83.4%.

Scenario Endpoint Percorso Latency (p50) Costo Note
FatturaPA XML POST /v2/parse Deterministico (fast-path) 41 ms €0 Senza LLM. Zero emissioni.
PDF fattura POST /v2/parse Ibrido (Rizzo + LLM) ~520 ms €0.002 Pseudonimizzato in-RAM prima dell’LLM
Testo libero (F24) POST /v2/parse LLM + restore ~890 ms €0.005 Restore locale dopo risposta LLM
Upload XML + poll POST /v1/uploadsGET /v1/uploads/{id} Async (due chiamate) ~120 ms €0 Upload job, polling callback

Repository measurements, non SLA live. 41ms e 83.4% sono storici — esegui benchmark e build prima di fare affidamento sui valori correnti. Costi LLM basati su prezzi OpenRouter al modello standard.


┌──────────────────────────────┐
│ POST /v2/parse │
│ Auth: X-API-Key │
│ Fail-closed: 401 se assente │
└──────────────┬───────────────┘
┌───────────┴───────────┐
│ Content-Type / │
│ file extension │
└───────┬───────────────┘
┌─────────────────────┼─────────────────────┐
│ │ │
┌─────┴──────┐ ┌───────┴───────┐ ┌──────┴──────┐
│ │ │ │ │ │
│ XML │ │ PDF │ │ TEXT │
│ FacturaPA/ │ │ (application/ │ │ (plain/ │
│ UBL │ │ pdf) │ │ markdown) │
│ │ │ │ │ │
└──────┬─────┘ └───────┬───────┘ └──────┬──────┘
│ │ │
┌──────┴──────┐ ┌──────┴───────┐ ┌──────┴──────┐
│ │ │ │ │ │
│ Fast Parser │ │ Rizzo PII │ │ Rizzo PII │
│ (XSLT + │ │ /analyze │ │ /analyze │
│ validation)│ │ (22 categ.) │ │ (22 categ.) │
│ │ │ │ │ │
└──────┬──────┘ └──────┬───────┘ └──────┬──────┘
│ │ │
│ ┌────────┴────────┐ │
│ │ Pseudonymized │ │
│ │ text → LLM │ │
│ │ (OpenRouter) │ │
│ └────────┬────────┘ │
│ │ │
└──────────┬─────────┴──────────┬──────────┘
│ │
┌──────┴──────┐ ┌──────┴──────┐
│ restore() │ │ restore() │
│ mapping │ │ mapping │
│ in RAM │ │ in RAM │
└──────┬──────┘ └──────┬──────┘
│ │
└────────┬───────────┘
┌────────┴────────┐
│ DocumentEnvelope│
│ v2 │
│ Union discr. │
│ Pydantic valid. │
│ HTTP 200 │
└─────────────────┘

Fail-closed Se Rizzo sidecar non è raggiungibile → HTTP 503. Il sistema non degrada mai a testo scoperto.


┌──────────┐ ┌──────────┐ ┌──────────────────────────────────────────────┐
│ │ │ │ │ EU BOUNDARY │
│ Client │────►│ Auth │────►│ ┌────────┐ ┌──────────┐ ┌──────────────┐ │
│ │ │ Gateway │ │ │ Router │ │ Fast │ │ Document │ │
│ │ │ fail- │ │ │ (by │──►│ Parser │─►│ Envelope v2 │ │
│ │ │ closed │ │ │ type) │ │ (XSLT) │ │ (Pydantic) │ │
└──────────┘ └──────────┘ │ └────────┘ ├──────────┤ └──────────────┘ │
│ │ Rizzo │ │
│ │ /analyze │──► LLM (esterno) │
│ │ (22 cat) │ (solo testo │
│ │ restore()│ pseudonimizzato) │
│ └──────────┘ │
└──────────────────────────────────────────────┘
  • 41ms deterministici: FatturaPA XML, UBL — zero LLM, zero token, zero emissioni
  • Asimmetria di routing: Il router sceglie il percorso in base a content-type — non c’è un unico modello che fa tutto
  • ZDR strutturale: I file esistono solo in RAM volatile durante la transazione. DROP dopo la risposta HTTP
  • Confine EU: Il sidecar Rizzo (CPU, RAM, nessuna chiamata esterna) genera il mapping PII locale. L’LLM non vede mai plaintext

Metodo Route Auth Scopo
GET /health Liveness probe
GET /status Stato operativo pubblico
POST /v2/parse X-API-Key Parsing sincrono (XML/PDF/text)
POST /v1/uploads X-API-Key Ingest asincrono (file pesanti)
GET /v1/uploads/{job_id} X-API-Key Polling risultato

Tutti gli errori seguono RFC 7807 (application/problem+json). Rate limiting per tier: Free 60 req/min, Basic 100 req/min, Pro 1000 req/min.

Niente JSON piatto Ogni risposta è un DocumentEnvelope v2 validato da Pydantic con union discriminata sul campo kind.


  1. Ottieni una chiave su Zyla API Hub
  2. Copia il comando dalla scheda cURL qui sopra
  3. Invia il tuo primo documento — ricevi un envelope strutturato in < 1 secondo

Reality-first: 41ms e 83.4% coverage sono repository measurements, non un live SLA. €0 si applica solo al fast-path deterministico. “EU boundary” è la proprietà architetturale del sidecar Rizzo — l’infrastruttura di produzione è Hetzner eu-central (Nürnberg) gestita da Coolify. Verifica sempre in produzione prima di fare affidamento su qualsiasi claim.