API
L'API è FastAPI, tutta sotto /api/v1. La chat è streaming SSE; il resto è JSON. Lo schema OpenAPI generato è disponibile su /docs dell'API stessa (Swagger UI, in locale http://localhost:8000/docs); questa pagina descrive il contratto e le scelte non ovvie.
Autenticazione
- Self-hosting single-user (default,
APP_ENV=local): nessuna autenticazione richiesta. - Token statico: fuori da
APP_ENV=localil server esigeAPI_AUTH_TOKEN(fail-closed: senza token configurato non parte). Le richieste lo passano comeAuthorization: Bearer <token>. - Account (
ACCOUNTS_ENABLED=true): sessioni utente via/auth/*; il token di sessione è restituito al login e va passato come bearer. Lato server è conservato solo il suo hash SHA-256.
Rate limiting per IP configurabile via RATE_LIMIT_PER_MINUTE (0 = disattivato).
Endpoint
| Endpoint | Descrizione |
|---|---|
POST /chat | Risposta in streaming SSE con retrieval e trust layer |
POST /search | Solo retrieval: hit rankati senza generazione |
GET /norma/{source}/art/{num} | Testo consolidato di un articolo (es. /norma/cc/art/2043) |
POST /documents · DELETE /documents/{id} | Upload (multipart, .docx/.pdf) e rimozione documenti per l'analisi |
POST /export/docx | Esporta una risposta in .docx; ri-verifica le citazioni server-side |
POST /citations/validate | Trust layer standalone: verifica le citazioni di un testo qualsiasi |
POST /auth/register|login|logout · GET /auth/me|config | Gestione account (attivi solo con ACCOUNTS_ENABLED) |
GET /health/live · GET /health/ready | Liveness / readiness (DB e vector store raggiungibili) |
POST /chat: lo stream
Richiesta:
{
"question": "Recesso dal contratto per vizio della cosa venduta",
"history": [{"role": "user", "content": "..."},
{"role": "assistant", "content": "..."}], // opzionale
"mode": "ricerca", // ricerca | analisi | redazione | giurisprudenza
"document_ids": ["..."], // opzionale, documenti caricati
"corpora": ["codici"], // opzionale; il primo è il corpus primario
"effective_at": "2026-08-01" // opzionale, data di vigenza (default oggi)
}La risposta è text/event-stream. Eventi, nell'ordine tipico:
| Evento | Payload |
|---|---|
status | {stage, detail}: le fasi reali della pipeline (instradamento, espansione, retrieval, reranking, generazione, verifica, riparazione), emesse quando accadono |
retrieval | {hits: [{chunk_id, citation_display, citation_anchor, score, excerpt}], latency_ms} |
token | {text}: frammento incrementale della risposta |
citation_warnings | {valid: [...], invalid: [{source, num, reason}], total}: esito del trust layer; le citazioni valide includono grounding: strong|weak |
done | {finish_reason, final_text, citations_total, citations_valid}:final_text è il testo con le citazioni in prosa promosse a tag <cite/> ed eventualmente riparate; è la forma da usare per l'export |
error | {message}: errore applicativo; chiude lo stream |
Esempio con curl:
curl -N -X POST http://localhost:8000/api/v1/chat \
-H "Content-Type: application/json" \
-d '{"question": "Qual è il termine di prescrizione del danno da fatto illecito?"}'Note per l'integrazione: EventSource nativo è GET-only, serve un client SSE che supporti POST (il frontend usa @microsoft/fetch-event-source). Se metti un reverse proxy davanti all'API, escludi /api/v1/chat da compressione e buffering, o lo stream arriverà in un blocco unico a fine generazione.
POST /citations/validate
Il trust layer come servizio: passi un testo (per esempio un atto già scritto), ricevi l'elenco delle citazioni riconosciute con l'esito della verifica di ciascuna. È l'endpoint usato dall'add-in Word.
curl -X POST http://localhost:8000/api/v1/citations/validate \
-H "Content-Type: application/json" \
-d '{"text": "Ai sensi dell'"'"'art. 2043 c.c. e dell'"'"'art. 18 St. lav. ..."}'Vigenza temporale
effective_at filtra il retrieval per data di vigenza: con "2020-01-01" il sistema risponde sulla base dei testi vigenti a quella data, e le versioni successive degli articoli non entrano nel contesto. Default: oggi. Il dettaglio della multivigenza storica completa è in roadmap; oggi il corpus porta il consolidato corrente con le finestre di vigenza note.